Tensorflow
基于Tensorflow 1.14
此次笔记记录的是搭建卷积神经网络来识别手写数字。
废话不多说,开始吧,笔记的细节都在注释里。
抄完改变了我的一个错误观念,CNN的学习过程:更新卷积核的值(更新提取的图像特征)。之前我以为卷积核都是固定的。
因为卷积核实际上就是如33,55这样子的权值矩阵。我们的网络要学习的,或者说要确定下来的,就是这些权值(Weights)的数值。
网络不断前后向的计算学习,一致在更新出合适的weights。也就是一直在更新卷积核。卷积核在更新了,学习到的特征也就被更新了。
对分类问题而言,目的就是:对图像提取特征,再以合适的特征来判断他所属的类别。
类似这种概念:你有那些个子的特征,我就根据这些特征,把你划分到某个类别去。
这样就说得通了,卷积神经网络的一整套流程就是:更新卷积核参数Weights,就相当于是一致在更新所提取到的图像特征,以得到可以把图像正确分类的最合适的特征。
参考:https://blog.csdn.net/qq_38262266/article/details/100096292 把它看完,答应我
参考:https://www.cnblogs.com/wj-1314/p/9754072.html
参考:https://www.bilibili.com/video/BV1Lx411j7ws?p=28
抄袭:https://github.com/MorvanZhou/tutorials/blob/master/tensorflowTUT/tf18_CNN3/full_code.py
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
# 最后计算精度的函数,y是个1*10的向量
def compute_accuracy(v_xs, v_ys):
global prediction
y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
return result
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
# 定义卷积核,也就是权重矩阵,参悟吧
def weights_variable(shape):
initial = tf.truncated_normal(shape,stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1,shape=shape)
return tf.Variable(initial)
# 定义卷积过程
# 具体的参数含义,参考https://blog.csdn.net/qq_38262266/article/details/100096292
# 为什么叫con2d,之前都是把二维图像展平来计算,现在是直接计算,直接卷积2维图像
def conv2d(x,W):
# stride [1, x_movement, y_movement, 1]
# Must have strides[0] = strides[3] = 1
return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
# 定义池化过程
def max_pool_2X2(x):
# stride [1, x_movement, y_movement, 1]
return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
# define placeholder for inputs to network
xs = tf.placeholder(tf.float32,[None,784])/255
ys = tf.placeholder(tf.float32,[None,10])
keep_prob = tf.placeholder(tf.float32) # drop_out 比例
x_image = tf.reshape(xs,[-1,28,28,1])
网络设计
卷积池化1层 + relu maxpool
卷积池化2层 + relu maxpool
全连接1层 1024个神经元 + 将卷积层的特征作为输入 drop_out
全连接2层(输出层) + softmax
## conv1 layer ##
W_conv1 = weights_variable([5,5,1,32]) # kernel大小5X5,in size1 灰度图像单通道,out size 32 ,32个卷积核
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1) # output size 28X28X32 ,padding = same
h_pool1 = max_pool_2X2(h_conv1) # 池化的strides 是 2,所以现在是 14*14*32
## conv2 layer ##
W_conv2 = weights_variable([5,5, 32, 64]) # patch 5x5, in size 32, out size 64
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # output size 14x14x64
h_pool2 = max_pool_2X2(h_conv2) # output size 7x7x64
## full contection layer1 ##
W_fc1 = weights_variable([7*7*64,1024]) # 全连接第一个隐层,先展平
b_fc1 = bias_variable([1024]) # 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) # relu 激活
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
## full contection layer2 ##
W_fc2 = weights_variable([1024,10]) # 10个输出
b_fc2 = bias_variable([10])
prediction = tf.nn.softmax(tf.matmul(h_fc1,W_fc2)+ b_fc2)# softmax
# 损失函数
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))
train = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
for i in range(1000):
batch_xs,batch_ys = mnist.train.next_batch(100)
sess.run(train,feed_dict={xs:batch_xs,ys:batch_ys,keep_prob:0.5})
if i %100==0:
print(compute_accuracy(mnist.test.images[:1000],mnist.test.labels[:1000]))
0.068
0.841
0.902
0.911
0.941
0.949
0.964
0.962
0.961
0.96
网友评论