【TensorFlow学习小组】Week 3动手任务list

实践作业

#1

2017.11.22

动手任务:

1、在MNIST手写数字数据集上,使用LeNet5模型进行训练和测试,评估准确率。截止日期:12.4 2、使用AlexNet模型,训练图片分类器,并评估准确率。(图片分类数据集:CIFAR-10 dataset 链接:http://www.cs.toronto.edu/~kriz/cifar.html)(选做)截止日期:12.15

备注:

代码结果在后面帖子回复


#2

#3

###Week3 MNIST LeNet5 参考了Tensorflow的mnist例子,使用了两个卷积层两个池化层两个全连接层 参数:第一个卷积池化层感受野55,特征维数32 第二个卷积池化层感受野55,特征维数64, 此时图片大小为的参数为7764,第一个全连接层的 特征向量为120,第二个全连接层的特征向量为 84,输出层为10。

import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('../MNIST_data', one_hot=True)
#输入占位符
x = tf.placeholder(tf.float32, [None, 784])                        #输入的数据占位符
y = tf.placeholder(tf.float32, shape=[None, 10])            #输入的标签占位符


#定义一个函数,用于初始化所有的权值 W
def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

#定义一个函数,用于初始化所有的偏置项 b
def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)
  
#定义一个函数,用于构建卷积层
def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
 
#定义一个函数,用于构建池化层
def max_pool(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')

#构建网络
x_image = tf.reshape(x, [-1,28,28,1])         #转换输入数据shape,以便于用于网络中
W_conv1 = weight_variable([5, 5, 1, 32])      
b_conv1 = bias_variable([32])       
h_conv1 = tf.nn.relu(conv2d( x_image, W_conv1) + b_conv1)     #第一个卷积层
h_pool1 = max_pool(h_conv1)                                  #第一个池化层

W_conv2 = weight_variable([5, 5, 32, 64])

b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)      #第二个卷积层
h_pool2 = max_pool(h_conv2)                                   #第二个池化层

W_fc1 = weight_variable([7 * 7 * 64, 120])
b_fc1 = bias_variable([120])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])              #reshape成向量
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)    #第一个全连接层

W_fc2 = weight_variable([120,84])
b_fc2 = bias_variable([84])
h_fc2 = tf.nn.relu(tf.matmul(h_fc1, W_fc2) + b_fc2)    #第二个全连接层


keep_prob = tf.placeholder("float") 
h_fc1_drop = tf.nn.dropout(h_fc2, keep_prob)                  #dropout层

W_fc3 = weight_variable([84, 10])
b_fc3 = bias_variable([10])
y_predict=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc3) + b_fc3)   #softmax层

cross_entropy = -tf.reduce_sum(y*tf.log(y_predict))     #交叉熵
train_step = tf.train.GradientDescentOptimizer(1e-3).minimize(cross_entropy)    #梯度下降法
correct_prediction = tf.equal(tf.argmax(y_predict,1), tf.argmax(y,1))    
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))                 #精确度计算
sess=tf.InteractiveSession()                          
sess.run(tf.initialize_all_variables())
for i in range(20000):
  batch = mnist.train.next_batch(50)
  if i%100 == 0:                  #训练100次,验证一次
    train_acc = accuracy.eval(feed_dict={x:batch[0], y: batch[1], keep_prob: 1.0})
    print('step',i,'training accuracy',train_acc)
  train_step.run(feed_dict={x: batch[0], y: batch[1], keep_prob: 0.5})

test_acc=accuracy.eval(feed_dict={x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0})
print("test accuracy",test_acc)


#4

week3 在MNIST手写数字数据集上,使用LeNet5模型进行训练和测试,评估准确率。

# -*- coding: utf-8 -*-
import tensorflow as tf
# 配置神经网络的参数
INPUT_NODE = 784
OUTPUT_NODE = 10

IMAGE_SIZE = 28
NUM_CHANNELS = 1
NUM_LABELS = 10
# 第一层卷积的深度和尺寸
CONV1_DEEP = 32
CONV1_SIZE = 5
# 第二层卷积的深度和尺寸
CONV2_DEEP = 64
CONV2_SIZE = 5
# 全连接的层的节点个数
FC_SIZE = 512

def inference(input_tensor, train, regularizer):
	# 第一层 卷积层
	# 定义输入的28x28x1的矩阵的原始MNIST的原始数据,输出28x28x32的举证
    with tf.variable_scope('layer1-conv1'):
        conv1_weights = tf.get_variable(
            "weight", [CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_DEEP],
            initializer=tf.truncated_normal_initializer(stddev=0.1))
        conv1_biases = tf.get_variable("bias", [CONV1_DEEP], initializer=tf.constant_initializer(0.0))
        # 使用CONV1 边长为5 深度为32的过滤器 过滤器的移动步长为1 且使用的全0填充
        conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))
	# 第二层 池化层
	# 使用全0填充并且移动的步数为2.输入28x28x32 ,输出14x14x32
    with tf.name_scope("layer2-pool1"):
        pool1 = tf.nn.max_pool(relu1, ksize = [1,2,2,1],strides=[1,2,2,1],padding="SAME")
	# 第三层 卷积层
	# 输入14x14x32的矩阵,输出14x14x64
    with tf.variable_scope("layer3-conv2"):
        conv2_weights = tf.get_variable(
            "weight", [CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP],
            initializer=tf.truncated_normal_initializer(stddev=0.1))
        conv2_biases = tf.get_variable("bias", [CONV2_DEEP], initializer=tf.constant_initializer(0.0))
         # 使用CONV2 边长为5 深度为64的过滤器 过滤器的移动步长为1 且使用的全0填充
        conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))
	# 第四层 池化层
	# 输入14x14x64 输出为7x7x64  
	# 用pool2.get_shape函数,可以得到第四层的输出维度.
    with tf.name_scope("layer4-pool2"):
        pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        pool_shape = pool2.get_shape().as_list()
		# 维度中包括一个batch的数据的个数,pool_shape[0]为一个batch中的数据
        nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
		# 通过tf.reshape,函数将第四层输出一个batch的变量
        reshaped = tf.reshape(pool2, [pool_shape[0], nodes])
	# 第五层 全连接层
	# 输入一个拉直后一组向量
	# 向量长度为7x7x64=3136 ,输出FC_SIZE=512的向量
    with tf.variable_scope('layer5-fc1'):
        fc1_weights = tf.get_variable("weight", [nodes, FC_SIZE],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc1_weights))
        fc1_biases = tf.get_variable("bias", [FC_SIZE], initializer=tf.constant_initializer(0.1))

        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
        if train: fc1 = tf.nn.dropout(fc1, 0.5)
	# 第六层 全连接层
    with tf.variable_scope('layer6-fc2'):
		# 声明第六层的变量继续传播,输入一组长度为 FC_SIZE = 512的向量
        fc2_weights = tf.get_variable("weight", [FC_SIZE, NUM_LABELS],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        # 输出一组长度为10的向量
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc2_weights))
        fc2_biases = tf.get_variable("bias", [NUM_LABELS], initializer=tf.constant_initializer(0.1))
        logit = tf.matmul(fc1, fc2_weights) + fc2_biases
	# 返回第六层的输出
    return logit
# -*- coding: utf-8 -*-
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_inference
import numpy as np
import os
# 配置神经网络的参数
# 一个训练batch中的训练数据个数,数字越小 训练过程月接接近
BATCH_SIZE = 100
# 基础的训练率
LEARNING_RATE_BASE = 0.8
# 训练的衰减率
LEARNING_RATE_DECAY = 0.99
# 描述模型复杂的正则化在损失函数的系数
REGULARIZATION_RATE = 0.0001
# 训练的轮数
TRAINING_STEPS = 30000
# 滑动的平均衰减率
MOVING_AVERAGE_DECAY = 0.99
# 模型保存的路径和文件名
MODEL_SAVE_PATH="MNIST_model/"
MODEL_NAME="mnist_model"


def train(mnist):
	# 定义输出为4维矩阵的placeholder
    x = tf.placeholder(tf.float32, [
        BATCH_SIZE,# 第一维表示一个batch中样例的个数
        mnist_inference.IMAGE_SIZE,# 第二维度表示的图书的尺寸
        mnist_inference.IMAGE_SIZE,# 第三维度表示的图书的尺寸
        mnist_inference.NUM_CHANNELS],# 第四维度表示图片的深度 RBG格式的深度为5
                       name='x-input')
    y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')

    regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
	# 直接使用mnist_inference中定义的前向传播
    y = mnist_inference.inference(x,True, regularizer)
	# 初始化迭代轮数
    global_step = tf.Variable(0, trainable=False)

	# 定义损失函数,学习率,滑动平均操作和过程
    variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
    variables_averages_op = variable_averages.apply(tf.trainable_variables())
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
    cross_entropy_mean = tf.reduce_mean(cross_entropy)
    loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
    learning_rate = tf.train.exponential_decay(
        LEARNING_RATE_BASE,# 基础的学习率 在这个基础上递减
        global_step,# 当前的迭代轮数
        mnist.train.num_examples / BATCH_SIZE,# 过完所有的训练数据的需要的迭代次数
		LEARNING_RATE_DECAY,# 训练的衰减率
        staircase=True)
    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
    with tf.control_dependencies([train_step, variables_averages_op]):
        train_op = tf.no_op(name='train')

	# 初始化Tensorflow的持久化类 开始训练
    saver = tf.train.Saver()
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
		# 在训练过程中
        for i in range(TRAINING_STEPS):
            xs, ys = mnist.train.next_batch(BATCH_SIZE)
			# 输入的训练集格式调整一个四维的矩阵,并将这个调整数据传入下面的sess.run
            reshaped_xs = np.reshape(xs, (
                BATCH_SIZE,
                mnist_inference.IMAGE_SIZE,
                mnist_inference.IMAGE_SIZE,
                mnist_inference.NUM_CHANNELS))
            _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: reshaped_xs, y_: ys})
            if i % 1000 == 0:
                print("After %d training step(s), loss on training batch is %g." % (step, loss_value))
                saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step)


def main(argv=None):
	#载入MNIST的数据集
    mnist = input_data.read_data_sets("./MNIST_data/", one_hot=True)
    train(mnist)

if __name__ == '__main__':
    tf.app.run()



# -*- coding: utf-8 -*-
import time
import math
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import mnist_inference
import mnist_train

def evaluate(mnist):
    with tf.Graph().as_default() as g:
        # 定义输出为4维矩阵的placeholder
        x = tf.placeholder(tf.float32, [
            mnist_train.BATCH_SIZE,
            mnist_inference.IMAGE_SIZE,
            mnist_inference.IMAGE_SIZE,
            mnist_inference.NUM_CHANNELS],
                           name='x-input')
        y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')
        validate_feed = {x: mnist.test.images, y_: mnist.test.labels}
        global_step = tf.Variable(0, trainable=False)

        regularizer = tf.contrib.layers.l2_regularizer(mnist_train.REGULARIZATION_RATE)
		# 直接使用mnist_inference中定义的前向传播
		y = mnist_inference.inference(x, False, regularizer)
        correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
		# 定义损失函数,学习率,滑动平均操作和过程
        variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)
        variables_to_restore = variable_averages.variables_to_restore()
        saver = tf.train.Saver(variables_to_restore)

        n = math.ceil(mnist.test.num_examples / mnist_train.BATCH_SIZE)
        for i in range(int(n)):
            with tf.Session() as sess:
                ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SAVE_PATH)
                if ckpt and ckpt.model_checkpoint_path:
                    saver.restore(sess, ckpt.model_checkpoint_path)
                    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
                    xs, ys = mnist.test.next_batch(mnist_train.BATCH_SIZE)
                    reshaped_xs = np.reshape(xs, (
                        mnist_train.BATCH_SIZE,
                        mnist_inference.IMAGE_SIZE,
                        mnist_inference.IMAGE_SIZE,
                        mnist_inference.NUM_CHANNELS))
                    accuracy_score = sess.run(accuracy, feed_dict={x:reshaped_xs, y_:ys})
                    print("After %s training step(s), test accuracy = %g" % (global_step, accuracy_score))
                else:
                    print('No checkpoint file found')
                    return


def main(argv=None):
	#载入训练的MNIST的数据集
    mnist = input_data.read_data_sets("./MNIST_data/", one_hot=True)
    evaluate(mnist)

if __name__ == '__main__':
    main()

训练

测试

很明显这样的实验结果和预期不太一样 可能是基础的训练率 LEARNING_RATE_BASE = 0.8 过大 所以我尝试可以试着减小100倍后 LEARNING_RATE_BASE = 0.008 就可以得到下面的 数据结果

训练

测试


#5

调节batch_size会影响计算速度,在GPU上尤其明显。适当调高训练轮数,会提高精度。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("../MNIST_data", one_hot=True)

sess = tf.InteractiveSession()

# some parameters
batch_size = 500
epoch=1000

# define net
x = tf.placeholder(tf.float32, [None, 784], name="image")
y = tf.placeholder(tf.float32, [None, 10], name="label") # the real label
x_image = tf.reshape(x, [-1, 28, 28, 1])


# define the weight variable
def weight_para(shape):
    initial = tf.constant(0.0, shape=shape)
    return tf.Variable(initial)


# define the bias
def bias_para(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)


# define the convolution network
def con_net(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding="SAME")


# define activation
def activate(con, bias):
    return tf.nn.relu(con + bias)


# define the max pooling
def max_pool(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


# START TO TRAIN
# the first layer
W_1 = weight_para([5, 5, 1, 32])
b_1 = bias_para([32])
a_1 = activate(con_net(x_image, W_1), b_1)
h_1 = max_pool(a_1)

# the second layer
W_2 = weight_para([5, 5, 32, 64])
b_2 = bias_para([64])
a_2 = activate(con_net(h_1,W_2),b_2)
h_2 = max_pool(a_2)

# the full connect
W_f1 = weight_para([7 * 7 * 64, 1024])
b_f1 = bias_para([1024])
h_2_plat = tf.reshape(h_2, [-1, 7 * 7 * 64])
h_f1 = activate(tf.matmul(h_2_plat, W_f1), b_f1)
# the dropout layer
keep_prob = tf.placeholder(tf.float32)
h_f1_drop = tf.nn.dropout(h_f1, keep_prob)

# follow by the softmax
W_f2 = weight_para([1024, 10])
b_f2 = bias_para([10])
y_con = tf.nn.softmax(tf.matmul(h_f1_drop, W_f2) + b_f2)  # the predict label

# loss function
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y * tf.log(y_con), reduction_indices=[1]))
# train algorithm
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_pre = tf.equal(tf.argmax(y_con, 1), tf.argmax(y, 1))
acc = tf.reduce_mean(tf.cast(correct_pre, tf.float32))

tf.global_variables_initializer().run()

for i in range(epoch):
    batch = mnist.train.next_batch(batch_size)
    if i % 100 == 0:
        train_acc = acc.eval(feed_dict={x: batch[0], y: batch[1], keep_prob: 1.0})
        print("step %d, train_acc %g" % (i, train_acc))
    train_step.run(feed_dict={x: batch[0], y: batch[1], keep_prob: 0.5})

# test acc
test_acc=acc.eval(feed_dict={x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0})
print("test acc %g" % test_acc)


#6

在MNIST 写数字数据集上,使 LeNet5模型进 训练和测试,评估准确率。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
%matplotlib inline
#Mnist数据集
# one_hot=True会使得 label由1维变位10维
mnist = input_data.read_data_sets("MNIST_Data/data/", one_hot=True)
Extracting MNIST_Data/data/train-images-idx3-ubyte.gz
Extracting MNIST_Data/data/train-labels-idx1-ubyte.gz
Extracting MNIST_Data/data/t10k-images-idx3-ubyte.gz
Extracting MNIST_Data/data/t10k-labels-idx1-ubyte.gz
img = mnist.train.images[66].reshape(28,28);
plt.imshow(img)
<matplotlib.image.AxesImage at 0x7fbcf7c4b6a0>

sess = tf.InteractiveSession()
#构造权重函数,标准差0.1, 给权重制造一些随机的噪声
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1);
    return tf.Variable(initial)

#给偏置bias增加0.1, 防止死亡节点
def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)
# 构造二维卷积函数
# tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

# input 参数
# an input tensor of shape [batch, in_height, in_width, in_channels]
# [一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],这是一个4维的Tensor,要求类型为float32和float64其中之一

# filter 参数
# 相当于CNN中的卷积核, [filter_height, filter_width, in_channels, out_channels],
# [卷积核的高度,卷积核的宽度,图像通道数,卷积核个数]
# 要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维

# strides 参数
# 卷积时在图像每一维的步长,这是一个一维的向量,长度4

# padding 参数
# 边界的处理方式,SAME代表边界加上padding让卷积的输入和输出保持同样的尺寸。
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')

# ksize 使用 2*2 最大化池, 保留像素值最大的点
# ksize 池化窗口的大小,取一个四维向量,一般是[1, height, width, 1],
# 因为我们不想在batch和channels上做池化,所以这两个维度设为了1,即横纵两个方向上步长为2进行遍历
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

1. Input层

#定义 Input 向量格式
#变形函数tf.reshape将数据转换为 28*28 ,单通道颜色
# -1 代表样本数量未知 , 1 代表单通道颜色
_X = tf.placeholder(tf.float32, [None, 784])
_y = tf.placeholder(tf.float32, [None, 10])
X_image = tf.reshape(_X, [-1,28,28,1]); # 将 1*784 转换为 28*28 结构

2. 第一次卷积、池化、非线性

W_conv1 = weight_variable([5,5,1,32]) # 卷积核的尺寸;1代表单通道颜色;6代表卷积核数量,就是最后提取特征的类别6特种
b_conv1 = bias_variable([32]) # 偏置
h_conv1 = tf.nn.relu(conv2d(X_image, W_conv1) + b_conv1)# 卷积 + 非线性
print(h_conv1.get_shape()) #第一次卷积之后输出数据格式
h_pool1 = max_pool_2x2(h_conv1)#第一次最大池化
(?, 28, 28, 32)

查看第一最大池化之后, 可以看到图像大小由 $282832$ 边为 $141432$

print(h_pool1.get_shape())
(?, 14, 14, 32)

3. 第二次卷积、池化、非线性

W_conv2 = weight_variable([5, 5, 32,64]) # 使用64个卷积核
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)# 第二次卷积 + 非线性
print(h_conv2.get_shape()) # 第二次卷积之后输出数据格式
h_pool2 = max_pool_2x2(h_conv2)
print(h_pool2.get_shape()) # 第二次最大池化
(?, 14, 14, 64)
(?, 7, 7, 64)

4. 全连接层、非线性

隐含节点1024个

W_fc1 = weight_variable([7*7*64, 1024])
print(W_fc1.get_shape())
b_fc1 = bias_variable([1024])
h_pool2_flatten = tf.reshape(h_pool2, [-1, 7*7*64]) # 将第二次最大池化后的结果重构为 一维向量
print(h_pool2_flatten.get_shape())
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flatten, W_fc1) + b_fc1) # 全连接层  非线性
(3136, 1024)
(?, 3136)
print(h_fc1.get_shape())
(?, 1024)

6. Dropout层

训练时随机丢弃一部分节点的数据, 减轻过拟合

keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

7. Softmax层

W_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

8. Loss函数 & 优化器

cross_entropy = tf.reduce_mean(-tf.reduce_sum(_y * tf.log(y_conv), reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# accuracy函数
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(_y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.global_variables_initializer().run()
# 训练20000次 每次大小为50的mini-batch 每100次训练查看训练结果 用以实时监测模型性能
for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i % 100 == 0:
        train_accuracy = accuracy.eval(feed_dict={_X: batch[0], _y: batch[1], keep_prob: 1.0})
        print("step %d, train_accuracy %g" % (i, train_accuracy))
    train_step.run(feed_dict={_X: batch[0], _y: batch[1], keep_prob: 0.5})

print("test accuracy %g" % accuracy.eval(feed_dict={
    _X: mnist.test.images, _y: mnist.test.labels, keep_prob: 1.0
}))
step 0, train_accuracy 0.08
step 100, train_accuracy 0.8
step 200, train_accuracy 0.88
step 300, train_accuracy 0.86
step 400, train_accuracy 0.94

省略很多很多行

step 19500, train_accuracy 1
step 19600, train_accuracy 1
step 19700, train_accuracy 1
step 19800, train_accuracy 1
step 19900, train_accuracy 1
test accuracy 0.9924


#7

-- coding: utf-8 --

“”" Created on Wed Mar 28 22:04:54 2018

@author: HP-JiaoLiu """

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

import LeNet5_infernece

import os

import numpy as np

batch_size = 100

learning_rate_base = 0.01

learning_rate_decay = 0.99

regularization_rate = 0.0001

training_steps = 4000

moving_average_decay = 0.99

def train(mnist):

x = tf.placeholder(tf.float32, [
        batch_size,
        LeNet5_infernece.IMAGE_SIZE,
        LeNet5_infernece.IMAGE_SIZE,
        LeNet5_infernece.NUM_CHANNELS],
        name='x-input')
y_ = tf.placeholder(tf.float32, [None, LeNet5_infernece.OUTPUT_NODE], 
                    name='y-input')
regularizer = tf.contrib.layers.l2_regularizer(regularization_rate)
y = LeNet5_infernece.inference(x, False, regularizer)
global_step = tf.Variable(0, trainable=False)

variable_averages = tf.train.ExponentialMovingAverage(moving_average_decay,
                                                      global_step)
variables_averages_op = variable_averages.apply(tf.trainable_variables())
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,
                    labels=tf.arg_max(y_, 1))
cross_entropy_mean = tf.reduce_mean(cross_entropy)
loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
learning_rate = tf.train.exponential_decay(
        learning_rate_base,
        global_step,
        mnist.train.num_examples / batch_size, learning_rate_decay,
        staircase=True)

train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
with tf.control_dependencies([train_step, variables_averages_op]):
    train_op = tf.no_op(name='train')
    
saver = tf.train.Saver()
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(training_steps):
        xs, ys = mnist.train.next_batch(batch_size)
        
        reshaped_xs = np.reshape(xs, (
                batch_size,
                LeNet5_infernece.IMAGE_SIZE,
                LeNet5_infernece.IMAGE_SIZE,
                LeNet5_infernece.NUM_CHANNELS))
        _, loss_value, step = sess.run([train_op, loss, global_step],
                                       feed_dict={x:reshaped_xs, y_:ys})
        if i % 100 == 0:
            print("After %d training step(s), loss on training batch is %g." % 
                  (i, loss_value))

def main(argv=None):

mnist = input_data.read_data_sets("../../datasets/MNIST_data", one_hot=True)
train(mnist)

if name == ‘main’:

main()

LeNet5_infernece.py

import tensorflow as tf

INPUT_NODE = 784

OUTPUT_NODE = 10

IMAGE_SIZE = 28

NUM_CHANNELS = 1

NUM_LABELS = 10

CONV1_DEEP = 32

CONV1_SIZE = 5

CONV2_DEEP = 64

CONV2_SIZE = 5

FC_SIZE = 512

def inference(input_tensor, train, regularizer):

with tf.variable_scope('layer1-conv1', reuse=tf.AUTO_REUSE):
    conv1_weights = tf.get_variable(
        "weight", [CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_DEEP],
        initializer=tf.truncated_normal_initializer(stddev=0.1))
    conv1_biases = tf.get_variable("bias", [CONV1_DEEP], initializer=tf.constant_initializer(0.0))
    conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
    relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))

with tf.name_scope("layer2-pool1"):
    pool1 = tf.nn.max_pool(relu1, ksize = [1,2,2,1],strides=[1,2,2,1],padding="SAME")

with tf.variable_scope("layer3-conv2", reuse=tf.AUTO_REUSE):
    conv2_weights = tf.get_variable(
        "weight", [CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP],
        initializer=tf.truncated_normal_initializer(stddev=0.1))
    conv2_biases = tf.get_variable("bias", [CONV2_DEEP], initializer=tf.constant_initializer(0.0))
    conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
    relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))

with tf.name_scope("layer4-pool2"):
    pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    pool_shape = pool2.get_shape().as_list()
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
    reshaped = tf.reshape(pool2, [pool_shape[0], nodes])

with tf.variable_scope('layer5-fc1', reuse=tf.AUTO_REUSE):
    fc1_weights = tf.get_variable("weight", [nodes, FC_SIZE],
                                  initializer=tf.truncated_normal_initializer(stddev=0.1))
    if regularizer != None: tf.add_to_collection('losses', regularizer(fc1_weights))
    fc1_biases = tf.get_variable("bias", [FC_SIZE], initializer=tf.constant_initializer(0.1))

    fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
    if train: fc1 = tf.nn.dropout(fc1, 0.5)

with tf.variable_scope('layer6-fc2', reuse=tf.AUTO_REUSE):
    fc2_weights = tf.get_variable("weight", [FC_SIZE, NUM_LABELS],
                                  initializer=tf.truncated_normal_initializer(stddev=0.1))
    if regularizer != None: tf.add_to_collection('losses', regularizer(fc2_weights))
    fc2_biases = tf.get_variable("bias", [NUM_LABELS], initializer=tf.constant_initializer(0.1))
    logit = tf.matmul(fc1, fc2_weights) + fc2_biases

return logit

#8

补上LeNet5实现手写数字识别,用的是Kaggle的数据集,训练模型并测试,得分0.98642

import tensorflow as tf
import tools
import numpy as np
from sklearn import model_selection
tf.logging.set_verbosity(tf.logging.INFO)

# 模型定义
def cnn_model_fn(features, labels, mode):
    # 输入层 28x28
    input_layer = tf.reshape(features['x'], [-1, 28, 28, 1])
    # 第一个卷积层 卷积核5x5,激活函数ReLU
    conv1 = tf.layers.conv2d(
        inputs=input_layer,
        filters=32,
        kernel_size=[5, 5],
        padding='same',
        activation=tf.nn.relu
    )
    # 第一个汇合层 大小2x2
    pool1 = tf.layers.max_pooling2d(
        inputs=conv1,
        pool_size=[2, 2],
        strides=2
    )
    # 第二个卷积层 卷积核5x5,激活函数ReLU
    conv2 = tf.layers.conv2d(
        inputs=pool1,
        filters=64,
        kernel_size=[5, 5],
        padding='same',
        activation=tf.nn.relu
    )
    # 第二个汇合层 大小2x2
    pool2 = tf.layers.max_pooling2d(
        inputs=conv2,
        pool_size=[2, 2],
        strides=2
    )
    # 全连接层
    pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
    dense = tf.layers.dense(pool2_flat, units=1024, activation=tf.nn.relu)
    # dropout
    dropout = tf.layers.dropout(
        inputs=dense, rate=0.5, training=mode == tf.estimator.ModeKeys.TRAIN)
    # 输出层
    logits = tf.layers.dense(inputs=dropout, units=10)

    predictions = {
        'classes': tf.argmax(input=logits, axis=1),
        'probabilities': tf.nn.softmax(logits, name='softmax_tensor')
    }

    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions['classes'])

    loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

    if mode == tf.estimator.ModeKeys.TRAIN:
        optimizer = tf.train.AdamOptimizer(learning_rate=0.0001)
        train_op = optimizer.minimize(
            loss=loss, global_step=tf.train.get_global_step())
        return tf.estimator.EstimatorSpec(
            mode=mode, loss=loss, train_op=train_op)

    eval_metrics_ops = {
        'accuracy': tf.metrics.accuracy(
            labels=labels, predictions=predictions['classes'])}

    return tf.estimator.EstimatorSpec(
        mode=mode, loss=loss, eval_metric_ops=eval_metrics_ops)

# 模型训练
def train():
    images, labels = tools.readtrainset('G:/Kaggle/DigitRecognizer/train.csv')
    X, X1, y, y1 = model_selection.train_test_split(images, labels, test_size=0.2)
    train_data = np.array(X, dtype=np.float32)
    train_labels = np.array(y, dtype=np.int32)
    eval_data = np.array(X1, dtype=np.float32)
    eval_labels = np.array(y1, dtype=np.int32)

    mnist_classifier = tf.estimator.Estimator(
        model_fn=cnn_model_fn, model_dir='/tmp/mnist_convnet_model')

    tensors_to_log = {'probabilities': 'softmax_tensor'}
    logging_hook = tf.train.LoggingTensorHook(
        tensors=tensors_to_log, every_n_iter=50)

    train_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={'x': train_data},
        y=train_labels,
        batch_size=100,
        num_epochs=None,
        shuffle=True)
    mnist_classifier.train(
        input_fn=train_input_fn,
        steps=2000,
        hooks=[logging_hook]
    )

    eval_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={'x': eval_data},
        y=eval_labels,
        num_epochs=1,
        shuffle=False)
    eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
    print(eval_results)

# 做预测
def predict():
    mnist_classifier = tf.estimator.Estimator(
        model_fn=cnn_model_fn, model_dir='/tmp/mnist_convnet_model')

    tensors_to_log = {'probabilities': 'softmax_tensor'}
    logging_hook = tf.train.LoggingTensorHook(
        tensors=tensors_to_log, every_n_iter=50)

    test_images = tools.readtestset('G:/Kaggle/DigitRecognizer/test.csv')
    test_data = np.array(test_images, dtype=np.float32)

    test_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={'x': test_data},
        num_epochs=1,
        shuffle=False)
    predictions = mnist_classifier.predict(input_fn=test_input_fn)
    print(predictions)
    tools.write_csv('G:/Kaggle/DigitRecognizer/cnn_submission.csv', predictions)


def main(argv):
    predict()


if __name__ == '__main__':
    tf.app.run()

#9

得分好高,厉害 :face_with_raised_eyebrow:


#10

还有提升空间,嘿嘿