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')