卷積神經網絡的概念理解和簡單實現

  卷積神經網絡的(convolutional neural network,CNN)是一種專門用來處理具有類似網絡結構的數據的神經網絡。卷積是一種特殊的線性運算。本文總結了卷積和池化的深入理解,以及一個簡單的卷積神經網絡的實現。

1.卷積

  通常形式中,卷積是對兩個實變函數的一種數學運算。表示爲:
                    s(t)=(xw)(t)s(t)=(x*w)(t)
  函數x爲輸入(input),w爲核函數(kernel function),輸出有時被稱爲特徵映射(feature map)。
  如圖所示,輸入爲一個3x4的矩陣A,卷積核爲一個2x2的矩陣,進行卷積操作後輸出一個2x3的矩陣。可參考該鏈接的動態圖更有利於理解。
在這裏插入圖片描述
  通常情況下,輸入時多維數組的數據,而核通常是由學習算法優化得到的多維數組的參數。

2.池化

  池化函數使用某一位置的相鄰輸出的總體統計特徵來代替網絡在該位置的輸出。例如,最大池化(max pool)函數給出相鄰矩形區域內的最大值,其他常用的池化函數包括相鄰矩形區域內的平均值,L2L^2範數以及基於距中心像素距離的加權平均函數。而其中“最大池化(Max pooling)”是最爲常見的。它是將輸入的圖像劃分爲若干個矩形區域,對每個子區域輸出最大值。直覺上,這種機制能夠有效地原因在於,在發現一個特徵之後,它的精確位置遠不及它和其他特徵的相對位置的關係重要。池化層會不斷地減小數據的空間大小,因此參數的數量和計算量也會下降,這在一定程度上也控制了過擬合。通常來說,CNN的卷積層之間都會週期性地插入池化層。
  池化層通常會分別作用於每個輸入的特徵並減小其大小。當前最常用形式的池化層是每隔2個元素從圖像劃分出2*2的區塊,然後對每個區塊中的4個數取最大值。這將會減少75%的數據量。
在這裏插入圖片描述
  池化函數的作用主要由以下幾個方面:
1.特徵不變形:池化操作是模型更加關注是否存在某些特徵而不是特徵具體的位置。
2.特徵降維:池化相當於在空間範圍內做了維度約減,從而使模型可以抽取更加廣範圍的特徵。同時減小了下一層的輸入大小,進而減少計算量和參數個數。
3.在一定程度上防止過擬合,更方便優化。

3.CNN的簡單實現

實驗環境:python 3.6 ,tensorflow 1.2

# 導入數據集並創建默認的Interactive Session
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
sess = tf.InteractiveSession()

# 創建權重和偏置
def weight_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)

# tf.nn.conv2d是tensorflow中的二維卷積函數,參數x是輸入,W是卷積的參數
# [5,5,1,32];前兩個是卷積核的尺寸;第三個數字代表有多少個channel(灰度是1,彩色RGB是3),最後一個數字代表卷積核的數量(也就是這個卷積層會提取多少類特徵)
# strides代表卷積模板移動的步長,都是1代表會不遺漏地劃過圖片的每一個點。
# padding代表邊界的處理方式,SAME代表給邊界加上Padding讓卷積的輸出和輸入保持同樣的尺寸。
# tf.nn.max_pool是tensorflow中的最大池化函數,這裏使用2*2的最大池化,即將一個2*2的像素塊降爲一個1*1的像素
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=(1,2,2,1),strides=[1,2,2,1],padding='SAME')

# x是特徵,y_是真實的label
# 因爲卷積神經網絡會利用空間結構信息,需要將1D的輸入向量轉爲2D的圖片結構,即從1*784的形式轉爲原始的28*28的結構
x = tf.placeholder(tf.float32, [None, 784])
y_ = tf.placeholder(tf.float32, [None, 10])
x_image = tf.reshape(x, [-1,28,28,1])  # -1代表樣本數量不固定,1代表顏色通道數量

# 定義第一個卷積層
W_conv1 = weight_variable([5,5,1,32])  # 卷積核尺寸是5*5,1個顏色通道,32個不同的卷積核。
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)  # conv2d卷積操作並加上偏置,再使用ReLu激活函數進行非線性處理
h_pool1 = max_pool_2x2(h_conv1)  # 對輸出結果進行池化操作

# 定義第二個卷積層
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)
h_pool2 = max_pool_2x2(h_conv2)

# 經歷了兩次步長爲2*2的最大池化,邊長已經只有1/4了,圖片尺寸由28*28變成了7*7
# 而第二個卷積層的卷積核數量爲64,其輸出tensor尺寸爲7*7*64
# 使用tf.reshape函數對第二個卷積層的輸出tensor進行變形,將其轉成1D的向量,然後連接一個全連接層。
# 隱含節點爲1024,並使用ReLu激活函數
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([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)

# dropout通過一個keep_prob比率來控制
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# 將Dropout層的輸出連接一個Softmax層,得到最後的概率輸出
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2)+b_fc2)

# 損失函數爲cross_entropy,和之前一樣,但是優化器使用Adam,並給與一個比較小的學習速率1e-4
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y_conv), reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

# 再繼續定義評測準確率的操作
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# 開始訓練過程
tf.global_variables_initializer().run()
for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i%100 == 0:
        train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_:batch[1], keep_prob:1.0})
        print("step %d,training accuracy %g"%(i, train_accuracy))

    train_step.run(feed_dict={x:batch[0], y_:batch[1],keep_prob:0.5})
print("test accuracy %g"%accuracy.eval(feed_dict={x:mnist.test.images, y_:mnist.test.labels, keep_prob:1.0}))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章