1.4 卷積神經網路初探

註:題圖繪製MathematicaGraphPlot[Table[1, {20}, {20}], Method -> "CircularEmbedding"]n

其實也不算初探了,有幾張圖已經看吐血了,我們來看看百度上的那張抄來抄去的圖:

有沒有感覺很熟悉?是的,第一張圖是Lecun Y大作《Gradient-based learning applied to document recognition》里的配圖。第二張我也不知道是誰為了抄的不明顯換了個比較丑的圖形。

當然知道卷積神經網路的庫如何用是足夠的,畢竟28天學會xxx,但是科學上的東西怎麼也得想想人家是如何想到這些的。

在全鏈接網路中,數據的處理順序如下公式:

Y_m=A_{mn}cdot B_{np}cdot C_{pq}cdot X_q

Y_m=f(A_{mn}cdot f(B_{np}cdot f(C_{pq}cdot X_q)) )

其中X是數據,ABC是矩陣,矩陣中所有元素都是需要求解的,這樣自由參數的個數達到了N=mcdot ncdot ncdot p cdot p cdot q個,用個常用的詞就隨著層數的增,多參數呈指數級的增長。

參數增多是一個非常可怕的事情。這種時候一個最簡單的解題思路就出現了,因為最近的一個數據點只與其臨近的點有關,所以連接數可以進行降低,每一層神經元只與其附近的神經元相連。矩陣來說怎麼表示呢?

bold{M}={left(nbegin{array}{ccccccc}n 1 & 1 & 1 & 1 & 1 & 1 & 1 n 1 & 1 & 1 & 1 & 1 & 1 & 1 n 1 & 1 & 1 & 1 & 1 & 1 & 1 n 1 & 1 & 1 & 1 & 1 & 1 & 1 n 1 & 1 & 1 & 1 & 1 & 1 & 1 n 1 & 1 & 1 & 1 & 1 & 1 & 1 n 1 & 1 & 1 & 1 & 1 & 1 & 1 n 1 & 1 & 1 & 1 & 1 & 1 & 1 nend{array}nright)}

上述矩陣中,每一個1對應於需要確定的參數,對於全鏈接形式的神經元,可見其需要確定的參數是非常之多的。然而如果僅將神經元和與之附近的神經元相連。矩陣形式則變換為:

bold{M}={left(nbegin{array}{ccccccc}n 1 & 0 & 0 & 0 & 0 & 0 & 0 n 1 & 1 & 0 & 0 & 0 & 0 & 0 n 1 & 1 & 1 & 0 & 0 & 0 & 0 n 0 & 1 & 1 & 1 & 0 & 0 & 0 n 0 & 0 & 1 & 1 & 1 & 0 & 0 n 0 & 0 & 0 & 1 & 1 & 1 & 0 n 0 & 0 & 0 & 0 & 1 & 1 & 1 n 0 & 0 & 0 & 0 & 0 & 1 & 1 nend{array}nright)}

0的部分是不需要求解的,也就是說不需要存儲的,知道稀疏矩陣的人應該知道這種存儲方式節省了多少空間,同時也就理解了節省了多少的神經元參數。

更進一步的,對於波形或者其他形式的數據而言在過去我們有一個常用的概念就是波形的變換,比如說常用的傅里葉變換,小波變換,圖像有二維小波,二維傅里葉等變換。這些變換的形式雖有不同,但是其核心思想是一致的,就是利用基函數對於波形進行展開。對於傅里葉變換是基函數是sin、cos;對於小波是小波基函數。這些展開代表了我們看待問題的一種方式,不是基於單個數據點的,而是整體數據提取一些特徵(基函數組合方式),可以說是一個整體的思考方式。類比於人的思考方式來說,我們看到一個事物,並不是逐個像素點的去分析提取特徵,而是從事物的大致輪廓和形狀去提取特徵。總的來說,波形的變換大致如此。同時可以看到,傅里葉變換中sin、cos 是不變的,也就是用於提取特徵的感受器是不變的。

類比於上面的思維過程,繼續去思考上面簡化過程的神經網路,如上所言特徵提取的感受器是不變的,那麼就可以假設一層神經元中每個權值都是相同的,也就是矩陣行向量中每一層都是一樣的。理解起來可能還是有些乾澀,參考1.3中的用卷積神經網路做數值模擬的例子。我們只用到了一個3*3的矩陣,就代表了整個迭代過程的卷積核心也就是權值,這時參數數目不可謂多。同時如前文所說,基函數可能不止一套,所以這裡可以用幾種基函數去適配,到卷積神經網路中將其稱為通道(大致可以這麼理解)。

語言永遠是乾癟的,上代碼,這次這次真的真的得用TensorFlow里本來的例子了,手寫識別的例子:

#example1.4.1.pyn#預讀取MNIST手寫字型檔nfrom tensorflow.examples.tutorials.mnist import input_datanmnist=input_data.read_data_sets(MNIST_data,one_hot=True)nnimport tensorflow as tfn#用正態分布隨機數初始化變數,本例中作為權值ndef weight_variable(shape):n initial=tf.truncated_normal(shape,stddev=0.1)n #正態分布n return tf.Variable(initial)n#用常量方式初始化偏置ndef bias_variable(shape):n initial=tf.constant(0.1,shape=shape)n #常數分布n return tf.Variable(initial)n#定義二維卷積過程 ndef conv2d(x,W):n return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding=SAME)n#定義池化層,簡單來說就是選個最大的數,進一步降低自由參數個數。ndef max_pool_2x2(x):n return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding=SAME)nnx=tf.placeholder(tf.float32,shape=[100,784])ny=tf.placeholder(tf.float32,shape=[100,10])nW_conv1=weight_variable([5,5,1,32])nb_conv1=bias_variable([32])nx_image=tf.reshape(x,[-1,28,28,1])ny_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)ny_pool1=max_pool_2x2(y_conv1)nW_conv2 = weight_variable([5, 5, 32, 64])nb_conv2 = bias_variable([64])ny_conv2 = tf.nn.relu(conv2d(y_pool1, W_conv2) + b_conv2)ny_pool2 = max_pool_2x2(y_conv2)ny_fc_flat= tf.reshape(y_pool2,[-1,7*7*64])nW_fc1 = weight_variable([7*7*64,10])nb_fc1 = bias_variable([10])ny_fc1=tf.nn.relu(tf.matmul(y_fc_flat,W_fc1)+b_fc1)nncross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=y_fc1))ntrain_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)nnsess=tf.Session()ninit = tf.global_variables_initializer()nsess.run(init)nfor i in range(1000):n bx,by=mnist.train.next_batch(100)n sess.run(train_step,feed_dict={x:bx,y:by})nnimport numpy as npnimport matplotlib.pyplot as pltn#為了畫圖更好看,其實並沒有nimport matplotlib as mplnmpl.style.use(seaborn-darkgrid)nnval=W_conv1.value()nconvVal=np.array(sess.run(val))nconvVal=np.reshape(convVal,[5,5,32])nnplt.imshow(convVal[:,:,6])nplt.show()n

手寫識別的過程中,四維變數的參數是:

conv1_shape=[5,5,1,32]n

任意選取一個特徵的,權參數繪製成圖:

val=W_conv1.value()nconvVal=np.array(sess.run(val))nconvVal=np.reshape(convVal,[5,5,32])n

最終得到的圖形如下:

可以說,手寫字體中所有圖形都可以由類似的上述32個圖形組成(有可能有錯誤)。

具體意思1.3章節中已經提到,因為傳入只有一個通道就是黑白顏色通道,所以中間為1,前面兩個5代表了卷積核心的大小是5*5個像素。32代表基函數有32個,卷積神經網路里叫通道有32個。

在舉一個簡單的例子,利用卷積神經網路進行曲線擬合的例子:

這個程序太長,我直接放到github/cangyeone裡面了

擬合結果暫且不論,我們先看一下權函數繪製成圖是何種形狀:

這是通道數選取了8,每個神經元連接數為16,所得到的圖形。可以看到權值曲線有明顯的波形特徵。

一般情況下這些結果為了使得收斂速度的問題都是通過無監督的學習得到的。再結合其他方式進行迭代。

至此,感性上理解卷積神經網路就先寫到這。

參考文獻:

Lecun Y, Bottou L, Bengio Y, et al. Gradient-based learning applied to document recognition[J]. Proceedings of the IEEE, 1998, 86(11):2278-2324.


推薦閱讀:

譯文 | 與TensorFlow的第一次接觸 第六章:並發
NLP(2) Tensorflow 文本- 價格建模 Part2
【博客存檔】風格畫之最後一彈MRF-CNN
深度學習對話系統實戰篇--老版本tf.contrib.legacy_seq2seq API介紹和源碼解析
拔了智齒,疼滴想屎。

TAG:卷积神经网络CNN | 神经网络 | TensorFlow |