卷积神经网络的整体结构、卷积层、池化、python实现
卷積神經(jīng)網(wǎng)絡(luò)的整體結(jié)構(gòu)、卷積層、池化、python實現(xiàn)
- 一、整體結(jié)構(gòu)
- 二、卷積層
- 三、池化層
- 四、python實現(xiàn)卷積層、池化層
一、整體結(jié)構(gòu)
神經(jīng)網(wǎng)絡(luò)相鄰層所有神經(jīng)元之間都有連接,稱為全連接。前面用Affine層實現(xiàn)了全連接。
舉個例子
全連接神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu):
卷積神經(jīng)網(wǎng)絡(luò)CNN的結(jié)構(gòu):
新增了Conv卷積層和Pooling池化層,之前的Affine-ReLU連接替換成了Conv-ReLU-Pooling連接。
CNN中,靠近輸出的層中使用之前Affine-ReLU組合,最后輸出層使用之前Affine-softmax組合,這是一種常見的CNN結(jié)構(gòu)。
二、卷積層
全連接神經(jīng)網(wǎng)絡(luò)存在的問題就是數(shù)據(jù)的形狀被忽視了,輸入三維圖像,但是向全連接層輸入時,需將三維拉成一維,這導(dǎo)致忽視了形狀中含有的空間信息,也就是說全連接,無法利用與形狀相關(guān)的信息。
卷積神經(jīng)網(wǎng)絡(luò)為了解決這一問題,向各層中傳遞的數(shù)據(jù)是有形狀的數(shù)據(jù),比如三維數(shù)據(jù)。
卷積層進(jìn)行卷積運算,就像是圖像處理的濾波。
對于輸入數(shù)據(jù),卷積運算以一定間隔滑動濾波器的窗口并將各個位置上濾波器的元素和輸入的對應(yīng)元素相乘再求和,進(jìn)行所謂乘積累加運算。
全連接神經(jīng)網(wǎng)絡(luò)中,參數(shù)有權(quán)重和偏置等。
CNN中濾波器里面的數(shù)就是參數(shù),濾波器里面數(shù)據(jù)的偏置也是參數(shù)。要通過cnn網(wǎng)絡(luò)對數(shù)據(jù)的學(xué)習(xí),把這些參數(shù)給找到,從而達(dá)到優(yōu)異的學(xué)習(xí)效果。
有時候進(jìn)行卷積處理前要進(jìn)行填充,也就是向輸入數(shù)據(jù)周圍填入固定的數(shù)據(jù),填充主要是為了調(diào)整輸出的大小。(4,4)的輸入數(shù)據(jù)應(yīng)用(3,3)濾波器時,輸出為(2,2),輸出比輸入縮小兩個元素就導(dǎo)致一個問題,如果每次進(jìn)行卷積運算都縮小輸出,那么某時刻就無法再對輸出進(jìn)行卷積運算,網(wǎng)絡(luò)就傳不下去了。如果說這個例子填充幅度是1,那么卷積運算輸出也是(4,4),卷積運算就可以在保持空間大小不變的情況下傳遞數(shù)據(jù)給下一層。
增大步幅,輸出大小會變小,增大填充輸出大小會變大。
假設(shè)輸入大小為(H,W),濾波器大小為(FH,FW),輸出大小為(OH,OW),填充為P,步幅為S。
有下面這個公式。
多維數(shù)據(jù)的卷積運算:
通道數(shù)為C、高度為H、長度為W的數(shù)據(jù)形狀,(C,H,W)
濾波器通道數(shù)為C、高度為FH、長度為FW,(C,FH,FW)
卷積后輸出的是一張?zhí)卣鲌D。可以這樣理解,一個小方塊在大方塊里面移動,由于大方塊的C和小方塊一樣,所以卷積后是二維的。
如果想在通道上也有多個卷積運算,就需要用到多個濾波器如下圖。輸出將以方塊的形式傳給下一層。
如果增加偏置,如下圖:小長方體,也就是FN個偏置值。
如果增加批處理,也就是一次性處理N個數(shù)據(jù),那么各層傳遞數(shù)據(jù)保存維度將增加一維,如下圖。
三、池化層
池化是縮小高、長方向上的空間運算。Max池化層是獲取目標(biāo)區(qū)域最大值,然后把最大值放到輸出數(shù)據(jù)的其中一個元素里。池化層沒有要學(xué)習(xí)的參數(shù),通道數(shù)不發(fā)生變化。池化對輸入數(shù)據(jù)微小偏差具有魯棒性,也就是說,輸入數(shù)據(jù)發(fā)生微小偏差時,池化層返回(與輸入數(shù)據(jù)沒發(fā)生微小偏差時)相同的輸出結(jié)果。
四、python實現(xiàn)卷積層、池化層
對于卷積來說,im2col這個函數(shù)能夠把大方塊的小方塊展開一行,這樣的話能和濾波器的小方塊 進(jìn)行矩陣乘積運算,如下圖所示。
對于池化來說,im2col依然可以這么展開,就是把大正方形里面的小正方形展成一行,這里就不放圖了。
im2col實現(xiàn)代碼:
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):"""Parameters----------input_data : 由(數(shù)據(jù)量, 通道, 高, 長)的4維數(shù)組構(gòu)成的輸入數(shù)據(jù)filter_h : 濾波器的高filter_w : 濾波器的長stride : 步幅pad : 填充Returns-------col : 2維數(shù)組"""N, C, H, W = input_data.shapeout_h = (H + 2*pad - filter_h)//stride + 1out_w = (W + 2*pad - filter_w)//stride + 1img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))for y in range(filter_h):y_max = y + stride*out_hfor x in range(filter_w):x_max = x + stride*out_wcol[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)return col反向傳播時候,要進(jìn)行im2col逆處理,用的是col2im函數(shù)。
def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):"""Parameters----------col :input_shape : 輸入數(shù)據(jù)的形狀(例:(10, 1, 28, 28))filter_h :filter_wstridepadReturns-------"""N, C, H, W = input_shapeout_h = (H + 2*pad - filter_h)//stride + 1out_w = (W + 2*pad - filter_w)//stride + 1col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))for y in range(filter_h):y_max = y + stride*out_hfor x in range(filter_w):x_max = x + stride*out_wimg[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]return img[:, :, pad:H + pad, pad:W + pad]卷積層、池化層實現(xiàn)代碼:
class Convolution:def __init__(self, W, b, stride=1, pad=0):self.W = Wself.b = bself.stride = strideself.pad = pad# 中間數(shù)據(jù)(backward時使用)self.x = None self.col = Noneself.col_W = None# 權(quán)重和偏置參數(shù)的梯度self.dW = Noneself.db = Nonedef forward(self, x):FN, C, FH, FW = self.W.shapeN, C, H, W = x.shapeout_h = 1 + int((H + 2*self.pad - FH) / self.stride)out_w = 1 + int((W + 2*self.pad - FW) / self.stride)col = im2col(x, FH, FW, self.stride, self.pad)col_W = self.W.reshape(FN, -1).Tout = np.dot(col, col_W) + self.bout = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)self.x = xself.col = colself.col_W = col_Wreturn outdef backward(self, dout):FN, C, FH, FW = self.W.shapedout = dout.transpose(0,2,3,1).reshape(-1, FN)self.db = np.sum(dout, axis=0)self.dW = np.dot(self.col.T, dout)self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)dcol = np.dot(dout, self.col_W.T)dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)return dxclass Pooling:def __init__(self, pool_h, pool_w, stride=1, pad=0):self.pool_h = pool_hself.pool_w = pool_wself.stride = strideself.pad = padself.x = Noneself.arg_max = Nonedef forward(self, x):N, C, H, W = x.shapeout_h = int(1 + (H - self.pool_h) / self.stride)out_w = int(1 + (W - self.pool_w) / self.stride)col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)col = col.reshape(-1, self.pool_h*self.pool_w)arg_max = np.argmax(col, axis=1)out = np.max(col, axis=1)out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)self.x = xself.arg_max = arg_maxreturn outdef backward(self, dout):dout = dout.transpose(0, 2, 3, 1)pool_size = self.pool_h * self.pool_wdmax = np.zeros((dout.size, pool_size))dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten()dmax = dmax.reshape(dout.shape + (pool_size,)) dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad)return dx總結(jié)
以上是生活随笔為你收集整理的卷积神经网络的整体结构、卷积层、池化、python实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: delphi 执行长时间存储过程 显示进
- 下一篇: 基于卷积神经网络的手写数字识别、pyth