一、前述
Convolutional neural networks
視覺皮層、感受野,一些神經元看線,一些神經元看線的方向,一些神經元有更大的感受野,組合
底層的圖案
1998年Yann LeCun等人推出了LeNet-5架構,廣泛用於手寫體數字識別,包含全連線層和sigmoid
啟用函式,還有卷積層和池化層
二、具體原理
1、直觀感受:(每一個神經元只看到一部分,並且先看到基本的形狀,然後再把相關特徵進行組合,只需要區域性連線即可)
2、卷積層理解
CNN裡面最重要的構建單元就是卷積層
神經元在第一個卷積層不是連線輸入圖片的每一個畫素,只是連線它們感受野的畫素,以此類推,
第二個卷積層的每一個神經元僅連線位於第一個卷積層的一個小方塊的神經元
以前我們做MNIST的時候,把影象變成1D的,現在直接用2D
3、Zero Padding
Zero Padding是一個可選項,加上說明更注重於邊緣的畫素點
VALID
不適用zero padding,有可能會忽略圖片右側或底下,這個得看stride的設定
SAME
必要會加zero padding,這種情況下,輸出神經元個數等於輸入神經元個數除以步長 ceil(13/5)=3,當步長為1時卷積完後的長寬一樣,畫素點一樣,維度一樣(輸入神經元的個數和輸出神經元的個數一樣)
4、卷積的計算
假設有一個5*5的影象,使用一個3*3的filter(卷積核)進行卷積,想得到一個3*3(沒有使用Zero_padding,因為下一層和上一層長寬不一樣)的Feature Map。
演示如圖:
結論:
通過3*3的維度可以看到對角線上的大概分佈,因為卷積核想保留對角線上的值
5、當步長為2時(生成的Feacture_map更小了)
舉例如下:
6.當多個卷積核時(3D圖片使用,3個通道累加,再加上bias偏置項)圖示如下:
D是深度;F是filter的大小(寬度或高度,兩者相同);
Wd,m,n表示filter的第m行第n列權重;
ad,I,j表示影象的第d層第i行第j列畫素;
結論:
在一個卷積層裡面可以有多個卷積核,每一個卷積核可以有多個維度
每一個卷積核生成一個Feature_map,因為有兩個卷積核,所以生成兩個Feacture_Map
7、卷積核的設定
Vertical line filter 中間列為1,周圍列為0
Horizontal line filter 中間行為1,周圍行為0
8、程式碼演示
import numpy as np from sklearn.datasets import load_sample_images import tensorflow as tf import matplotlib.pyplot as plt # 載入資料集 # 輸入圖片通常是3D,[height, width, channels] # mini-batch通常是4D,[mini-batch size, height, width, channels] dataset = np.array(load_sample_images().images, dtype=np.float32) # 資料集裡面兩張圖片,一箇中國廟宇,一個花 batch_size, height, width, channels = dataset.shape print(batch_size, height, width, channels) # 建立兩個filter # 高,寬,通道,卷積核 # 7, 7, channels, 2 filters_test = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32) filters_test[:, 3, :, 0] = 1 # 垂直 filters_test[3, :, :, 1] = 1 # 水平 # filter引數是一個filters的集合 X = tf.placeholder(tf.float32, shape=(None, height, width, channels)) # strides=[1, 2, 2, 1] 中第一最後一個為1,中間對應sh和sw convolution = tf.nn.conv2d(X, filter=filters_test, strides=[1, 2, 2, 1], padding='SAME') with tf.Session() as sess: output = sess.run(convolution, feed_dict={X: dataset}) plt.imshow(output[1, :, :, 1]) # 繪製第一個圖的第二個特徵圖 plt.show()
在一個特徵圖裡面,所有的神經元共享一樣的引數(weights bias),權值共享