slim模块精简代码

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import os
import tensorflow.contrib.slim as slim

def weight_variable(shape):
    return tf.Variable(tf.truncated_normal(shape,stddev=0.1))

def bias_variable(shape):
    return tf.Variable(tf.constant(0.0,shape=shape))

def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides = [1, 1, 1, 1], padding = 'SAME')

def max_pool_2_2(x):
    return tf.nn.max_pool(x, ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')

mnist = input_data.read_data_sets('/newSoftware/Sublime Text 3/Data/myCode/MNIST-data/',one_hot=True)
#这个函数用于设置默认参数值,对指定列表设置stride和padding的默认值
#这个模块可以精简代码
with slim.arg_scope([slim.conv2d,slim.max_pool2d,slim.avg_pool2d],stride=1,padding='SAME'):
    x = tf.placeholder(tf.float32, [None, 784])
    y_ = tf.placeholder(tf.float32, [None, 10])
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    #以下注释是原来做法,现在改为使用slim模块实现,池化层步长为2不是默认值,另外设置一下就好
    #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)#28*28*32卷积层不改变图片像素大小,只是用一个窗口去做内积
    #h_pool1=max_pool_2_2(h_conv1)#池化层根据窗口和步长改变图片大小,但不改变特征维度32.窗口2*2,步长2,即输出14*14*32
    h_conv1 = slim.conv2d(x_image,32,[5,5])
    h_pool1 = slim.max_pool2d(h_conv1,[2,2],stride=2)

#下面就不一一使用了

W_conv2 = weight_variable([5, 5, 32, 64])#每个卷积核的通道深度32跟输入深度一致
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)#14*14*64同理,卷积层不改变大小,只是调节特征维度
h_pool2 = max_pool_2_2(h_conv2)#进一步缩小尺寸为7*7*64

W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])#压缩成二维
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

#dropout选在第一个全连接后,为何?
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)#随机去掉百分比的训练数据,防止过拟合

W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
#此时不用激活函数,softmax转为概率分布
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)#(batch_size-dropout)*10
#reduction_indices=1表示在行上取最大值,得到batch_size*1,再去这batch_size个交叉熵的平均作为这一batch_size的交叉熵
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices = [1]))
global_step=tf.Variable(0,trainable=False)
#滑动平均,维护影子变量,利于测试验证
variable_averages=tf.train.ExponentialMovingAverage(0.99,global_step)
variable_averages_op=variable_averages.apply(tf.trainable_variables())
#这个优化器一般更好
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy,global_step=global_step)
#控制顺序
with tf.control_dependencies([train_step,variable_averages_op]):
    train_op=tf.no_op(name='train')#什么也不做,就一个控制效果
#布尔值再转为浮点值,得到精度
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
#用于保存模型,下次可以直接调出测试或接着训练,这个东西有时候放的位置不对会报错,好像最好放在变量之后
saver=tf.train.Saver()
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(3000):
        batch=mnist.train.next_batch(100)
        _,entropy_value,train_accuracy,step=sess.run([train_op,cross_entropy,accuracy,global_step],feed_dict={x: batch[0], y_: batch[1],keep_prob:0.5})
        if i%1000==0:
            print("step %d, cross_entropy %g, training accuracy %g"%(step,entropy_value, train_accuracy))
            saver.save(sess,os.path.join('/tmp/','model2.ckpt'),global_step=global_step,write_meta_graph=True)
    print("test accuracy %g"%accuracy.eval(feed_dict = {x: mnist.test.images, y_: mnist.test.labels,keep_prob:1.0}))

--------------------------------------------------------------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/qq_26567507/article/details/79681350