CNN卷积神经网络的构建
1.卷积神经网络由输入层,卷积层,激活函数,池化层,全连接层组成.
input(输入层)–conv(卷积层)–relu(激活函数)–pool(池化层)–fc(全连接层)
2.卷积层:
主要用来进行特征的提取
卷积操作是使用一个二维的卷积核在一个批处理的图片上进行不断扫描。具体操作是将一个卷积核在每张图片上按照一个合适的尺寸在每个通道上面进行扫描。
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
这个函数的作用是对一个四维的输入数据 input 和四维的卷积核 filter 进行操作,然后对输入数据进行一个二维的卷积操作,最后得到卷积之后的结果。
tf.nn.bias_add(value, bias, name = None):这个函数的作用是将偏差项 bias 加到 value 上面。
3.激活函数
在神经网络中,激活函数的作用是能够给神经网络加入一些非线性因素,使得神经网络可以更好地解决较为复杂的问题。
在神经网络中,我们有很多的非线性函数来作为激活函数,比如连续的平滑非线性函数(sigmoid,tanh和softplus),连续但不平滑的非线性函数(relu,relu6和relu_x)和随机正则化函数(dropout)。
所有的激活函数都是单独应用在每个元素上面的,并且输出张量的维度和输入张量的维度一样。
常用的激活函数:
(1)tf.nn.relu(features, name = None):这个函数的作用是计算激活函数relu,即max(features, 0)
(2)tf.nn.relu6(features, name = None):这个函数的作用是计算激活函数relu6,即min(max(features, 0), 6)
(3)tf.nn.softplus(features, name = None):这个函数的作用是计算激活函数softplus,即log( exp( features ) + 1)。
(4)tf.sigmoid(x, name = None):这个函数的作用是计算 x 的 sigmoid 函数。具体计算公式为 y = 1 / (1 + exp(-x))。
(5)tf.tanh(x, name = None):这个函数的作用是计算 x 的 tanh 函数。具体计算公式为 ( exp(x) – exp(-x) ) / ( exp(x) + exp(-x) )。
激活函数应该具有的特征:
(1)非线性。线性激活层对于深层神经网络没有作用,因为其作用以后仍然是输入的各种线性变换。。
(2)连续可微。梯度下降法的要求。
(3)范围最好不饱和,当有饱和的区间段时,若系统优化进入到该段,梯度近似为0,网络的学习就会停止。
(4)单调性,当激活函数是单调时,单层神经网络的误差函数是凸的,好优化。
(5)在原点处近似线性,这样当权值初始化为接近0的随机值时,网络可以学习的较快,不用可以调节网络的初始值。
4.池化层
主要是对输入的特征图进行压缩,一方面使特征图变小,简化网络计算负责度,另一方面进行特征压缩,提取主要特征。
迟化操作一般有两种:Avy Pooling和max Pooling
max Pooling:计算迟化区域中元素的最大值
5.Dropout 防止过拟合
当训练数据量比较小时,可能会出现因为追求最小差值导致训练出来的模型极度符合训练集,但是缺乏普适性,不能表达训练数据之外的数据
解决方案:
tf.nn.dropout(x, keep_prob, noise_shape = None, seed = None, name = None)
Dropout就是在不同的训练过程中随机扔掉一部分神经元也就是让某个神经元的激活值以一定的概率p,让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了。如下图:
6.全连接层
连接所有的特征,将输出值送给分类器
7.总体的结构
8.CNN代码实现预测手写数字
1 import warnings 2 warnings.filterwarnings('ignore') 3 import numpy as np 4 import tensorflow as tf 5 from tensorflow.examples.tutorials.mnist import input_data 6 7 # 加载数据,one-hot形式 8 mnist = input_data.read_data_sets('./',one_hot=True) 9 10 # 卷积方法 11 def conv(input_data,filter_,b): 12 return tf.nn.conv2d(input_data,filter_,[1,1,1,1],'SAME') + b 13 # 池化:降维 14 def pool(input_data): 15 return tf.nn.max_pool(input_data,[1,2,2,1],[1,2,2,1],'SAME') 16 # 变量 17 def gen_v(shape): 18 return tf.Variable(initial_value=tf.random_normal(shape = shape,dtype = tf.float64)) 19 20 # 第一层卷积 21 X = tf.placeholder(shape = [None,784],dtype=tf.float64) 22 y = tf.placeholder(shape = [None,10],dtype=tf.float64) 23 input_data = tf.reshape(X,shape = [-1,28,28,1]) 24 filter1 = gen_v([3,3,1,32]) 25 b1 = gen_v([32]) 26 conv1 = tf.nn.relu(conv(input_data,filter1,b1)) 27 pool1 = pool(conv1) 28 # pool1 shape=(?, 14, 14, 32) 29 30 # 第二层卷积 31 filter2 = gen_v([3,3,32,64]) 32 b2 = gen_v([64]) 33 conv2 = tf.nn.relu(conv(pool1,filter2,b2)) 34 pool2 = pool(conv2) 35 # pool2 shape=(?, 7, 7, 64) 36 37 # 第三层卷积 38 filter3 = gen_v([3,3,64,64]) 39 b3 = gen_v([64]) 40 conv3 = tf.nn.relu(conv(pool2,filter3,b3)) 41 pool3 = pool(conv3) 42 # pool3 shape=(?, 4, 4, 64) 43 44 # 全连接层1024个神经元,输出1024个神经元 45 fc = tf.reshape(pool3,shape = [-1,4*4*64]) 46 fc_w = gen_v([4*4*64,1024]) 47 fc_b = gen_v([1024]) 48 conn = tf.nn.relu(tf.matmul(fc,fc_w) + fc_b) 49 # conn shape=(?, 1024) 50 51 # 防止过拟合dropout 52 rate = tf.placeholder(dtype=tf.float64) 53 dp = tf.nn.dropout(conn,rate =rate) 54 55 # 输出层,其实就是全连接层 56 out_w = gen_v([1024,10]) 57 out_b = gen_v([10]) 58 out = tf.matmul(dp,out_w) + out_b 59 # out shape=(?,10) 60 y_ = tf.nn.softmax(out) 61 62 # 构建损失函数 63 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y,logits = out)) 64 65 # 优化梯度下降 66 opt = tf.train.AdamOptimizer(0.001).minimize(loss) 67 68 # 训练 69 saver = tf.train.Saver() 70 with tf.Session() as sess: 71 sess.run(tf.global_variables_initializer()) 72 73 for i in range(10): 74 for j in range(100): 75 X_train,y_train = mnist.train.next_batch(550) 76 opt_,loss_ = sess.run([opt,loss],feed_dict = {X:X_train,y:y_train,rate:0.5}) 77 print('里层循环执行次数:%d。损失是:%0.4f'%(j+1,loss_)) 78 # 计算准确率 79 X_validation ,y_validation = mnist.validation.next_batch(2000) 80 y_pred = sess.run(y_,feed_dict = {X:X_validation,rate:0}) 81 accuracy = (np.argmax(y_pred,axis = -1) == np.argmax(y_validation,axis = -1)).mean() 82 print('--------------------循环执行%d。准确率是%0.4f-------------------'%(i+1,accuracy)) 83 saver.save(sess,'./model/three_cnn')
CNN预测手写数字