Tensorflow实现CNN网络

时间:2023-02-03 21:16:42
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

#1 到 10 的数
mnist = input_data.read_data_sets('MNIST_data',one_hot= True)

#定义一个计算精确度的函数
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
#权值建立函数
def weight_variable(shape):
#给一个参数返回一个权值
#stddev代表标准差
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)

#定义一个卷积层
#strides代表步长,其中第一个和第四个一定要为1,中间两个代表x方向和y方向
def conv2d(x,W):
return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding = 'SAME')

#定义一个池化层 pooling 可以将参数进一步减小,同时也可以防止过拟合
def max_pool_2x2(x):
#这里的ksize提供了一个过滤器尺寸,这里相当于是一个2x2尺寸
return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding ='SAME')

#传入图片信息
xs = tf.placeholder(tf.float32,[None,784]) #这里的手写数据是28x28
ys = tf.placeholder(tf.float32,[None,10]) #这里是一个10分类问题
#这里的keep_prob是保留概率,即我们要保留的RELU的结果所占比例
keep_prob = tf.placeholder(tf.float32)

#将图片形状变为-1,28,28,1 因为xs的data包含了所有图片的例子
#-1代表不用理会输入了多少图片,28x28代表图片的维度,1代表是channel即黑白图片
x_image = tf.reshape(xs,[-1,28,28,1])

#定义权值 5x5x1x32
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) #输出 28x28x32
#第一次池化
h_pool1 = max_pool_2x2(h_conv1)#输出14x14x32

#第二次卷积 相当于将图片变得越来越深····

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) #变为了 14x14x64
h_pool2 = max_pool_2x2(h_conv2) #变为了 7x7x64


#定义全连接层
W_fc1 = weight_variable([7*7*64,1024]) #相当于定义了1024个隐藏结点
b_fc1 = bias_variable([1024])

#将输出的数据转化为一维数据
h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])
#relu激活函数
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)

#加入drop_out
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)



#定义第二层全连接层,作为输出层
W_fc2 = weight_variable([1024,10]) #相当于定义了1024个隐藏结点
b_fc2 = bias_variable([10])

#softmax激活函数
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)

#计算误差

cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1])) #这是计算loss

train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) #训练减少误差


sess = tf.Session()
sess.run(tf.global_variables_initializer())

for i in range(10000):
batch_xs,batch_ys = mnist.train.next_batch(100)
sess.run(train_step,feed_dict={xs:batch_xs,ys:batch_ys,keep_prob:0.5})
if i%50 == 0:
print(compute_accuracy(mnist.test.images,mnist.test.labels))

提几个重要点
卷积层中的过滤器可以将当前神经网络上的一个子节点矩阵转化为下一层神经网络上的一个单位节点矩阵。
常用的过滤器尺寸有3x3和5x5。且过滤器处理的矩阵深度和当前层神经网络节点矩阵的深度是一致的。

卷积和池化层的主要作用就是降维·······,另外随着卷积层数的增加,数据的深度也随之增加,CNN或许也是因此能够提取数据更深层次的特征

另外每一个卷积层中使用的过滤器的参数都是一样的。因为这样可以减少输入参数。

使用池化层既可以加快计算速度也可以防止过拟合问题的作用。

关于dropout····具体·······好像有点说不清楚···