一、实现简单的cnn卷积神经网络
实现简单的cnn卷积神经网络(用到的是MNIST手写数字的数据库yann.lecun.com/exdb/mnist)
用到激活函数:
二、步骤
输入端是28
28
1这样的一张图片,就是一张黑白的图片(假如他是一张彩色图片,它的高度是28
28
3,RGB3通道红绿蓝三原色图像的高度);
经过第一层卷积,有32个过滤器,就会变成28
28
32,之后经过一个石化层pool,变成14
14
32这样一个网络结构,然后在经过第二层的卷积网络就会变成14
14
64这样的网络结构,再经过一个pool亚采样层就会变成7
7
64之后再对他进行一个扁平的序列化,它就变成1
1
1024最后经过一个全连接网络进行一个输出就会变成一个1
1
10这样的一个结果;
大致就是这样。
conv2:inputs(需要的输入);
filters(表示过滤器的数目,也就是输出的深度如图为32个过滤器);
kernel_size(就是卷积核横向的大小,5
5);
strides步长,每隔多少步取样一次,此处设置为1,保证28个采样);
padding(卷积神经网络里面的补零,补零方案有两种,一种是valid表示采样的时候不超过28
28边界此时不需要补零,另一种same表示采样之后得到采样之后大小与之前一致,)
三、pool方案
有max、avarage两种;
max_pooling2d
四、代码即注释详解
import numpy as np
import input_data #下载并手动导入MNIST手写数字库(55000*28*28其中一部分不然太多)
import tensorflow as tf
import os #解除警报必须写
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'#解除警报必须写
tf.compat.v1.disable_eager_execution()#新版tensorflow需要
#from tensorflow.examples.tutorials.mnist import input_data###太远了import不进来
#from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets#没卵用了老代码
#把下载下的mnist数据集使用读取数据集函数保存在py同文件夹下起名为mnist_data
#one_hot是一种编码(encoding)形式,叫做读热码,0,1,2,3,4,5,6,7,8,9
#这样的十位数字以一种独特的形式进行表示,比如0:1000000000;1:0100000000
#None表示tensor张量的一个维度,第一个维度可以是任何长度
mnist=input_data.read_data_sets('mnist_data',one_hot=True)
#输入(除以255是因为是0-255灰度值的范围)
input_x=tf.compat.v1.placeholder(tf.float32,[None,28*28])/255.
#输出10个数字的标签
output_y=tf.compat.v1.placeholder(tf.int32,[None,10])
#把输入图片变成28*28*1的矩阵样式
input_x_images=tf.reshape(input_x,[-1,28,28,1])
#从Test测试数据集选取3000个手写数字的图片和对应的标签
test_x=mnist.test.images[:3000]#0-2999一共三千张图片
test_y=mnist.test.labels[:3000]#标签
#构建卷积神经网络
#构建第一层卷积
conv1=tf.compat.v1.layers.conv2d(
inputs=input_x_images,#形状【28,28,1】
filters=32,#过滤器的数目也就是输出的深度
kernel_size=[5,5],#过滤器在二维的大小
strides=1,#步长是1
padding='same',#采用same在外围补零方案
activation=tf.nn.relu
)#经过这层神经网络图片会变成28*28*32的采样结果
#第一层池化(亚采样)
pool1=tf.compat.v1.layers.max_pooling2d(
inputs=conv1,
pool_size=[2,2],
strides=2#步长是2
)#经过亚采样形状是14*14*32
#构建第二层卷积
conv2=tf.compat.v1.layers.conv2d(
inputs=pool1,#形状【14,14,32】
filters=64,#过滤器的数目也就是输出的深度
kernel_size=[5,5],#过滤器在二维的大小
strides=1,#步长是1
padding='same',#采用same在外围补零的方案
activation=tf.nn.relu
)#经过这层神经网络图片会变成14*14*64的采样结果
#第二层池化(亚采样)
pool2=tf.compat.v1.layers.max_pooling2d(
inputs=conv2,#形状14*14*64
pool_size=[2,2],#过滤器在二维的大小是2*2
strides=2#步长是2
)#经过亚采样形状是7*7*64
#平坦化(flat)
flat=tf.compat.v1.reshape(pool2,[-1,7*7*64])
#用1024个神经元组成全连接层
dense=tf.compat.v1.layers.dense(inputs=flat,units=1024,activation=tf.nn.relu)
#Droput:丢失50%,rete=0.5
dropout=tf.compat.v1.layers.dropout(inputs=dense,rate=0.5,training=True)
#10个神经元的全链接层的构建,这里不用激活函数来做非线性化了
logits=tf.compat.v1.layers.dense(inputs=dropout,units=10)#输出形状表征【1*1*10】
#计算误差,用误差反向传递,优化神经网络参数让模型精度不断提高
#Cross entropy(交叉熵),再用Softmax计算百分比概率
loss=tf.compat.v1.losses.softmax_cross_entropy(onehot_labels=output_y,logits=logits)
#用Adam优化器最小化误差,学习率也就是步长为0.001
train_op=tf.compat.v1.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
#计算神经网络精度即预测值和实际标签匹配程度
#返回(accuracy,update_op),会创建两个局部变量
accuracy=tf.compat.v1.metrics.accuracy(
labels=tf.argmax(output_y,axis=1),
predictions=tf.compat.v1.argmax(logits,axis=1)
)[1]
#创建一个会话
sess=tf.compat.v1.Session()
#初始化变量:全局和局部
init=tf.group(tf.compat.v1.global_variables_initializer(),tf.compat.v1.local_variables_initializer())
sess.run(init)
for i in range(20000):
batch=mnist.train.next_batch(50)#从Train数据集里面取到下一组50个样本
train_loss,train_op_=sess.run([loss,train_op],{input_x:batch[0],output_y:batch[1]})
if i%100==0:
test_accuracy=sess.run(accuracy,{input_x:test_x,output_y:test_y})
print(("Step=%d,Train loss=%.4f,[Test accurancy=%.2f]")%(i,train_loss,test_accuracy))
#测试:打印20个预测值和真实值的对
test_output=sess.run(logits,{input_x:test_x[:20]})
inferenced_y=np.argmax(test_output,1)
print(inferenced_y,'Inferenced numbers')#推测的数字
print(np.argmax(test_y[:20],1),'Real numbers')#真实的数字
参数的设置至关重要,我这里简单的设置以下并没有寻求最优,下面是我简单改变其中一些参数之后运行出来的精确度等结果: