tensorflow:3)实现简单的卷积网络

来源:互联网 发布:mac主页被篡改 编辑:程序博客网 时间:2024/06/05 17:40

这次依然使用MNIST数据集进行手写数组识别,但是为了进一步提高模型的准确度,这次我们使用卷积网络来训练模型

1.加载数据

# 加载mnist数据from tensorflow.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets("MNIST_data/", one_hot=True)# 初始化sessionsess = tf.InteractiveSession()

2.把常用的权重和偏置封装成函数

def weight_variable(shape):    #权重为标准差为0.1的正态分布随机样本    initial = tf.truncated_normal(shape, stddev=0.1)    return tf.Variable(initial)def bias_variable(shape):    # 偏置设置0.1为了防止ReLU的死亡节点    initial = tf.constant(0.1, shape=shape)    return tf.Variable(initial)

3.把卷积层和池化层封装成函数

def conv2d(x, W):    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding="SAME")def max_pool_2x2(x):    return  tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")

参数strides=[1,1,1,1]为滑动窗口移动的步长,第1维和第4维为输入的batch(批次)和channel(通道数),通常使用默认值1。中间的第2维和第3维为在witdh和height上滑动的步长,通常设置为一样的。参数ksize=[1,2,2,1]表示滑动窗口的大小,和strides类似,第1维和第4维通常为1,第2维和第3位才是真正的窗体大小。

4.数据预处理

#输入的训练集x=tf.placeholder(tf.float32,[None,784])#训练集标签y_=tf.placeholder(tf.float32,[None,10])#mnist的数据集是1维的,因此要把其转换成4维 1x784->28x28x_image=tf.reshape(x,[-1,28,28,1])

[-1,28,28,1]:-1表示样本数不固定,最后的1表示通道数

5.定义第一个卷积层

#[5,5,1,32]表示使用卷积核尺寸为5x5,1个颜色通道,32个不同的卷积核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_2x2(h_conv1)

首先对该层的权重和偏置进行初始化,然后使用conv2d函数进行卷积操作并加上权重,接着使用ReLU激活函数进行非线性处理。最后,使用池化函数对卷积的输出进行池化操作

6.定义第二个卷积层

#较第一层,唯一不同的就是卷积核的数目变成了64W_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_2x2(h_conv2)

7.定义全连接层
因为前面经历了2次2x2的池化操作,卷积操作因为使用了padding0技术,width和height都没有改变,所以边长剩下1/4,图像尺寸从28X28变成了7X7,而第二个卷积层的卷积核数为64,其输出的tensor尺寸即为7x7x64。我们使用rf.reshape对输出的tensor变形,将其转换为1维的向量,然后连接一个全连接层,隐藏节点为1024,并使用ReLU激活函数

W_fc1 = weight_variable([7 * 7 * 64, 1024])b_fc1 = bias_variable([1024])# (n, 7, 7, 64) ->(n,7*7*64) n为样本数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)

8.定义DropOut层

#为了减轻过过拟合,在训练时,根据输入的比率随机丢弃一部分节点kepp_prob=tf.placeholder(tf.float32)h_hf1_drop=tf.nn.dropout(h_fc1,keep_prob=kepp_prob)

9.定义Softmax层
我们将dropout的输出连接到一个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)cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1]))train_step=tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

10.模型训练

# 初始化所有参数tf.global_variables_initializer().run()correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))# 进行20000次迭代训练for i in range(20000):    # 随机从训练集中抽取50个样本作为一个批次进行训练    batch_xs, batch_ys = mnist.train.next_batch(50)    if i%1000==0:        train_accuracy=accuracy.eval(feed_dict={x: batch_xs, y_: batch_ys, kepp_prob: 1.0})        print("step %d,training accurary %g"%(i,train_accuracy))    # 为占位变量赋值    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys, kepp_prob: 0.5})

这里我们总共进行2w次迭代,每次迭代样本大小为50,每1000次对准确度进行一次评测,这里需要注意下,测试的时候kepp_prob的值为1.0表示使用全部神经元。训练输出的部分结果如下:

step 0,training accurary 0.06step 1000,training accurary 0.94step 2000,training accurary 0.98step 3000,training accurary 0.96step 4000,training accurary 1step 5000,training accurary 1step 6000,training accurary 1step 7000,training accurary 1

11.模型测试

# 计算模型的准确度print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels, kepp_prob: 1.0}))

最终测试集跑出来的准确度为:99.19%
果然是神器,不过最后吐槽下:没有GPU的孩子真的伤不起啊,模型’猪猪’训练了20分钟

原创粉丝点击