CNN
一璃诀、卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
1.全連接神經(jīng)網(wǎng)絡(luò)
2.卷積神經(jīng)網(wǎng)絡(luò)
全連接層存在的問題:數(shù)據(jù)的形狀被“忽視”了
例如弧可,輸入數(shù)據(jù)是圖像時,圖像通常是高劣欢、長棕诵、通道方向上的 3 維形狀。但是凿将,向全連接層輸入時校套,需要將 3 維數(shù)據(jù)拉平為 1 維數(shù)據(jù)。實(shí)際上牧抵,前面提到的使用了 MNIST 數(shù)據(jù)集的例子中笛匙,輸入圖像就是 1 通道、高 28 像素犀变、長 28 像素的(1, 28, 28)形狀妹孙,但卻被排成 1 列,以 784 個數(shù)據(jù)的形式輸入到最開始的 Affine 層获枝。
圖像是 3 維形狀蠢正,這個形狀中應(yīng)該含有重要的空間信息。例如省店,空間上鄰近的像素為相似的值嚣崭、RBG 的各個通道之間分別有密切的關(guān)聯(lián)性、相距較遠(yuǎn)的像素之間沒有什么關(guān)聯(lián)等懦傍,3 維形狀中可能隱藏有值得提取的本質(zhì)模式有鹿。但是,因?yàn)槿B接層會忽視形狀谎脯,將全部的輸入數(shù)據(jù)作為相同的神經(jīng)元(同一維度的神經(jīng)元)處理,所以無法利用與形狀相關(guān)的信息持寄。
而卷積層可以保持形狀不變源梭。當(dāng)輸入數(shù)據(jù)是圖像時,卷積層會以 3 維數(shù)據(jù)的形式接收輸入數(shù)據(jù)稍味,并同樣以 3 維數(shù)據(jù)的形式輸出至下一層废麻。因此,在 CNN 中模庐,可以(有可能)正確理解圖像等具有形狀的數(shù)據(jù)烛愧。
CNN 中,有時將卷積層的輸入輸出數(shù)據(jù)稱為特征圖(feature map)。其中怜姿,卷積層的輸入數(shù)據(jù)稱為輸入特征圖(input feature map)慎冤,輸出數(shù)據(jù)稱為輸出特征圖(output feature map)。
二沧卢、卷積層
1.卷積運(yùn)算(Convolution)
2.填充(Padding)
在進(jìn)行卷積層的處理之前蚁堤,有時要向輸入數(shù)據(jù)的周圍填入固定的數(shù)據(jù)(比如0等)。
3.卷積步長(Stride)
應(yīng)用濾波器的位置間隔稱為步長(stride)但狭。
假設(shè)輸入大小為 (H, W)披诗,濾波器大小為 (FH, FW),輸出大小為 (OH, OW)立磁,填充為 P呈队,步幅為 S。此時唱歧,輸出大小為
4.多通道卷積
通道方向上有多個特征圖時宪摧,會按通道進(jìn)行輸入數(shù)據(jù)和濾波器的卷積運(yùn)算,并將結(jié)果相加迈喉,從而得到輸出绍刮。
5.卷積層完整處理流
三、池化層
除了 Max 池化之外挨摸,還有 Average 池化等孩革。相對于 Max 池化是從目標(biāo)區(qū)域中取出最大值,Average 池化則是計(jì)算目標(biāo)區(qū)域的平均值得运。在圖像識別領(lǐng)域膝蜈,主要使用 Max 池化。
池化層的特征
- 1.沒有要學(xué)習(xí)的參數(shù)
池化層和卷積層不同熔掺,沒有要學(xué)習(xí)的參數(shù)饱搏。池化只是從目標(biāo)區(qū)域中取最大值(或者平均值),所以不存在要學(xué)習(xí)的參數(shù)置逻。
- 2.通道數(shù)不發(fā)生變化
經(jīng)過池化運(yùn)算推沸,輸入數(shù)據(jù)和輸出數(shù)據(jù)的通道數(shù)不會發(fā)生變化。
- 3.對微小的位置變化具有魯棒性
輸入數(shù)據(jù)發(fā)生微小偏差時券坞,池化仍會返回相同的結(jié)果鬓催。因此,池化對輸入數(shù)據(jù)的微小偏差具有魯棒性恨锚。
四宇驾、卷積層實(shí)現(xiàn)
1.基于 im2col 的展開
如果老老實(shí)實(shí)地實(shí)現(xiàn)卷積運(yùn)算,估計(jì)要重復(fù)好幾層的 for 語句猴伶。這樣的實(shí)現(xiàn)有點(diǎn)麻煩课舍,而且塌西,NumPy 中存在使用 for 語句后處理變慢的缺點(diǎn)(NumPy 中,訪問元素時最好不要用 for 語句)筝尾。這里捡需,我們不使用 for 語句,而是使用 im2col 這個便利的函數(shù)進(jìn)行簡單的實(shí)現(xiàn)忿等。
im2col 是一個函數(shù)栖忠,將輸入數(shù)據(jù)展開以適合濾波器(權(quán)重)。如圖 7-17 所示贸街,對 3 維的輸入數(shù)據(jù)應(yīng)用 im2col 后庵寞,數(shù)據(jù)轉(zhuǎn)換為 2 維矩陣(正確地講,是把包含批數(shù)量的 4 維數(shù)據(jù)轉(zhuǎn)換成了 2 維數(shù)據(jù))薛匪。
卷積運(yùn)算的濾波器處理的細(xì)節(jié):將濾波器縱向展開為 1 列捐川,并計(jì)算和 im2col 展開的數(shù)據(jù)的矩陣乘積,最后轉(zhuǎn)換(reshape)為輸出數(shù)據(jù)的大小逸尖。
class Convolution:
def __init__(self, W, b, stride=1, pad=0):
self.W = W
self.b = b
self.stride = stride
self.pad = pad
def forward(self, x):
FN, C, FH, FW = self.W.shape
N, C, H, W = x.shape
out_h = int(1 + (H + 2*self.pad - FH) / self.stride)
out_w = int(1 + (W + 2*self.pad - FW) / self.stride)
col = im2col(x, FH, FW, self.stride, self.pad)
col_W = self.W.reshape(FN, -1).T # 濾波器的展開
out = np.dot(col, col_W) + self.b
out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)
return out
五古沥、池化層實(shí)現(xiàn)
class Pooling:
def __init__(self, pool_h, pool_w, stride=1, pad=0):
self.pool_h = pool_h
self.pool_w = pool_w
self.stride = stride
self.pad = pad
def forward(self, x):
N, C, H, W = x.shape
out_h = int(1 + (H - self.pool_h) / self.stride)
out_w = int(1 + (W - self.pool_w) / self.stride)
# 展開(1)
col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
col = col.reshape(-1, self.pool_h*self.pool_w)
# 最大值(2)
out = np.max(col, axis=1)
# 轉(zhuǎn)換(3)
out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)
return out