簡 介
一茧彤、relu層
1、前向傳播
2疆栏、反向傳播
二曾掂、dropout層
1、dropout工作原理
2壁顶、在哪里使用dropout
3珠洗、dropout的實現(xiàn)
4、dropout的功效
5若专、python實現(xiàn)dropout的前向傳播
6许蓖、python實現(xiàn)dropout的反向傳播
三、卷積層
1 Im2col
2前向傳播
3反向
4小案例
四调衰、池化層
1膊爪、python實現(xiàn)池化層的前向傳播
2、python實現(xiàn)池化層的反向傳播
relu層
如何在Python中實現(xiàn)ReLU層嚎莉?
簡而言之米酬,relu層就是輸入張量通過一個非線性的relu函數(shù),得到輸出趋箩,而不改變其空間或者深度信息
image
從上圖可以看出赃额,所有大于0的保持不變,而小于零的變?yōu)榱憬腥贰4送馓迹臻g信息和深度也是相同的
relu函數(shù)作為激活函數(shù),具有以下功能:
易于計算(前向/反向傳播)竹勉,采用sigmoid函數(shù)作為激活函數(shù)時候(指數(shù)運算)飞盆,計算量大,反向傳播求誤差梯度時,求導(dǎo)涉及除法桨啃,計算量相當(dāng)大车胡,而采用Relu激活函數(shù)檬输,整個過程的計算量節(jié)省很多照瘾。
深度模型中受消失梯度的影響要小得多,對于深層網(wǎng)絡(luò)丧慈,sigmoid函數(shù)反向傳播時析命,很容易就出現(xiàn)梯度消失的情況(在sigmoid函數(shù)接近飽和區(qū)時,變換太緩慢逃默,導(dǎo)數(shù)趨于0鹃愤,這種情況會造成信息丟失),從而無法完成深層網(wǎng)絡(luò)的訓(xùn)練完域。
如果你使用大的學(xué)習(xí)率软吐,他們可能會不可逆轉(zhuǎn)地死去,因為當(dāng)一個非常大的梯度流過一個 ReLU 神經(jīng)元吟税,更新過參數(shù)之后凹耙,這個神經(jīng)元再也不會對任何數(shù)據(jù)有激活現(xiàn)象了。這個神經(jīng)元的梯度將一直都是0了肠仪。
1肖抱、前向傳播
將所有小于0的數(shù)變成0,大于0的數(shù)保持不變异旧,空間和深度信息保持不變意述。
python實現(xiàn)relu的前向傳播:
2、反向傳播
在前向傳播的時候吮蛹,我們對每個輸入X=[x1,x2,x3]應(yīng)用了max(0,x)函數(shù)荤崇,所以在反向傳播的時候,小于0的元素,梯度dx等于0:
python實現(xiàn)relu 反向傳播:
02
Dropout層
Dropout是一種用于防止神經(jīng)網(wǎng)絡(luò)過度擬合的技術(shù)潮针,你還可以使用L2正則化防止過擬合术荤。
image
下面是分類的錯誤率,可以發(fā)現(xiàn)使用了dropout之后錯誤率更低:
image
和其他正則化技術(shù)一樣然低,使用dropout會使得訓(xùn)練損失稍稍惡化喜每,但是模型的泛化能力卻更好,因為如果我們的模型過于復(fù)雜(更多層或者更多神經(jīng)元)雳攘,模型就很可能過擬合带兜,下面是訓(xùn)練和驗證集上的損失情況,以及他們中有無dropout情況吨灭。
image
1刚照、dropout工作原理
在訓(xùn)練期間,隨機的選擇一定比例的神經(jīng)元喧兄,讓它停止工作无畔,如下圖所示啊楚,這樣泛化能力更好,因為你的網(wǎng)絡(luò)層的不同的神經(jīng)元會學(xué)習(xí)相同的“概念”浑彰。在測試階段恭理,不需要使用dropout.
2、在哪里使用dropout
通常會在全連接層使用dropout郭变,但也可以在最大池化后使用dropout,從而產(chǎn)生某種圖像噪聲增強颜价。
3、dropout的實現(xiàn)
為了實現(xiàn)某個神經(jīng)元的失活诉濒,我們在前向傳播過程中創(chuàng)建一個掩碼(0和1)周伦,此掩碼應(yīng)用于訓(xùn)練期間的層的輸出,并緩存以供以后在反向傳播中使用未荒。如前所述专挪,這個dropout掩碼只在訓(xùn)練中使用。
在反向傳播中片排,我們對被激活的神經(jīng)元感興趣(我們需要將掩碼保存為前向傳播)寨腔,這些被選中的神經(jīng)元中,使用反向傳播划纽,失活的神經(jīng)元沒有可學(xué)習(xí)的參數(shù)脆侮,僅僅是輸入x,反向傳播返回dx勇劣。
4靖避、dropout的功效
Dropout背后理念和集成模型很相似。在Drpout層比默,不同的神經(jīng)元組合被關(guān)閉幻捏,這代表了一種不同的結(jié)構(gòu),所有這些不同的結(jié)構(gòu)使用一個的子數(shù)據(jù)集并行地帶權(quán)重訓(xùn)練命咐,而權(quán)重總和為1篡九。
如果Dropout層有 n 個神經(jīng)元,那么會形成2^n個不同的子結(jié)構(gòu)醋奠。在預(yù)測時榛臼,相當(dāng)于集成這些模型并取均值。這種結(jié)構(gòu)化的模型正則化技術(shù)有利于避免過擬合窜司。
Dropout有效的另外一個視點是:由于神經(jīng)元是隨機選擇的沛善,所以可以減少神經(jīng)元之間的相互依賴,從而確保提取出相互獨立的重要特征塞祈。
5金刁、python實現(xiàn)dropout的前向傳播
6、python實現(xiàn)dropout的反向傳播
image
03
卷積層
簡單的說,卷積層所做的工作就是對輸入的特征圖應(yīng)用卷積算子尤蛮,卷積核的個數(shù)是輸出特征圖的深度媳友。下面我們介紹一下相關(guān)的參數(shù):
N:批處理大小(4d張量上的圖像數(shù))
F:卷積層上的濾波器個數(shù)
kW/kH:內(nèi)核寬度/高度(通常我們使用方形卷積核,kW=kH)
H/W:圖像高度/寬度(通常H=W)
H'/W':卷積圖像高度/寬度(如果使用適當(dāng)?shù)奶畛洳蹋瑒t與輸入相同)
Stride:卷積滑動窗口將要移動的像素數(shù)醇锚。
Padding:將0添加到圖像的邊框,以保持輸入和輸出大小相同轧葛。
Depth:輸入特征圖的深度(如輸入為RGB圖像則深度為3)
Output depth:輸出的特征圖的深度(與F相同)
1搂抒、前向傳播
在前向傳播過程中,我們用不同的過濾器“卷積”輸入尿扯,每個過濾器將在圖像上尋找不同的特征。
在這里觀察到所有來自第一層的神經(jīng)元共享相同的權(quán)重集焰雕,不同的過濾器得到不同的特征衷笋。
2、python實現(xiàn)卷積層的前向傳播
3矩屁、反向傳播
為了更好的理解辟宗,這里使用1維卷積來理解卷積層的反向傳播,2維的也類似吝秕。
輸入信號為X=[x0,x1,x2,x3,x4],參數(shù)為W=[w0,w1,w2]泊脐,不使用padding,卷積之后的結(jié)果是:Y=[y0,y1,y2]烁峭,這里Y = X * flip(W)容客,flip可以看作是180度的旋轉(zhuǎn)。
現(xiàn)在我們使用計算圖來表示约郁,并且加上一個偏差缩挑,通過觀察可以發(fā)現(xiàn)這個過程跟全連接層類似,不同之處在于卷積核可以使得權(quán)重共享鬓梅。
現(xiàn)在來看反向傳播
向后追蹤計算圖供置,反向傳播可以表示為以下的公式
意味著損失值隨著輸入進行變化,由上圖可以看出绽快。
image
注意:
dX跟X大小相同芥丧,所以我們需要進行填充
dout跟Y大小相同,在本例中為3(漸變輸入)
為了節(jié)省編程工作量坊罢,我們將梯度的計算采用卷積的形式
在dX梯度上续担,所有元素都乘以W,所以我們可能會對W和dout進行卷積操作
1d卷積的輸出尺寸計算公式:outputSize=(InputSize-KernelSize+2P)+1艘绍,
我們期望的尺寸是3赤拒,由于原始輸入尺寸是3,并且我們將與也有3個元素的W矩陣進行卷積。所以我們需要用2個零填充輸入挎挖,之后再進行卷積这敬,就可以得到尺寸為3的輸出。
就卷積而言:
根據(jù)鏈?zhǔn)椒▌t蕉朵,求損失函數(shù)對各個參數(shù)的偏導(dǎo):
再次查看從圖表中得到的表達式崔涂,可以將它們表示為dout和X之間的卷積。同樣始衅,由于輸出將是3個元素冷蚂,因此不需要進行填充。
就卷積的計算而言汛闸,
如果將X看成是卷積核蝙茶,而dout看做輸入信號,則:
對于偏差诸老,計算將類似于全連接層隆夯。 基本上我們每個過濾器有一個偏差,計算如下:
4、python實現(xiàn)卷積的反向傳播
5别伏、卷積運算轉(zhuǎn)換為矩陣運算
使用矩陣運算蹄衷,能夠使得運算速度更快,但也會消耗更多的內(nèi)存厘肮。
5.1 Im2col
前面的代碼愧口,使用的是for循環(huán)來實現(xiàn)卷積,運算速度不夠快类茂,在本節(jié)中耍属,我們將學(xué)習(xí)如何使用矩陣運算來實現(xiàn)卷積,首先大咱,卷積是內(nèi)核過濾器和它移動之后在圖像上選擇的區(qū)域之間的點積恬涧,如果我們在內(nèi)存上擴展所有可能的窗口并將點積作為矩陣運算,運算速度將更快碴巾,但內(nèi)存的消耗也會更大溯捆。
例如,輸入圖片為2272273厦瓢,卷積核為11113提揍,步長為4,padding為0煮仇,進行卷積運算的時候劳跃,我們可以將卷積核在輸入圖片上采樣的11113大小的像素塊(感受野)拉伸為大小為11113=363的列向量,2272273大小的圖片浙垫,又有步長為4刨仑,padding為0郑诺,卷積之后的寬高計算方式為(227-11)/4)+1=55,所以采樣之后得到5555個11113大小的像素塊(感受野)杉武,最終可以得到尺寸為3633025的輸出矩陣X_col辙诞,(3025由55*55得到,表示有3025個感受野)
總結(jié)一下轻抱,如何計算im2col輸出的大蟹赏俊:
[img_height, img_width, img_channels] = size(img);
newImgHeight = floor(((img_height + 2P - ksize) / S)+1);
newImgWidth = floor(((img_width + 2
P - ksize) / S)+1);
cols = single(zeros((img_channelsksizeksize),(newImgHeight * newImgWidth)));
卷積核也進行類似的伸展,假設(shè)有96個大小為11113的卷積核祈搜,通過im2col函數(shù)之后较店,得到96*363的矩陣W_col.
將圖像和卷積核轉(zhuǎn)換之后,卷積操作就變成了簡單的矩陣乘法運算容燕,這個例子中梁呈,W_col(96363)c乘以X_col(3633025)得到的矩陣是963025,最后可以重塑為5555*96缰趋,重塑可以定義一個col2im的函數(shù)來實現(xiàn)捧杉。
5.2前向傳播計算圖
下圖是前向傳播中使用im2col之后的計算圖,輸入為443秘血,步長為1,padding為0评甜,卷積核大小為2*2灰粮,卷積核個數(shù)為1:
前向傳播代碼如下:
defconv_forward_naive(x, w, b, conv_param):"""
? A naive implementation of the forward pass for a convolutional layer.
? The input consists of N data points, each with C channels, height H and width
? W. We convolve each input with F different filters, where each filter spans
? all C channels and has height HH and width HH.
? Input:
? - x: Input data of shape (N, C, H, W)
? - w: Filter weights of shape (F, C, HH, WW)
? - b: Biases, of shape (F,)
? - conv_param: A dictionary with the following keys:
? ? - 'stride': The number of pixels between adjacent receptive fields in the
? ? ? horizontal and vertical directions.
? ? - 'pad': The number of pixels that will be used to zero-pad the input.
? Returns a tuple of:
? - out: Output data, of shape (N, F, H', W') where H' and W' are given by
? ? H' = 1 + (H + 2 * pad - HH) / stride
? ? W' = 1 + (W + 2 * pad - WW) / stride
? - cache: (x, w, b, conv_param)
? """out =Nonepad_num = conv_param['pad']? stride = conv_param['stride']? N,C,H,W = x.shape? F,C,HH,WW = w.shape? H_prime = (H+2*pad_num-HH) // stride +1W_prime = (W+2*pad_num-WW) // stride +1out = np.zeros([N,F,H_prime,W_prime])#im2colforim_numinrange(N):? ? ? im = x[im_num,:,:,:]? ? ? im_pad = np.pad(im,((0,0),(pad_num,pad_num),(pad_num,pad_num)),'constant')? ? ? im_col = im2col(im_pad,HH,WW,stride)? ? ? filter_col = np.reshape(w,(F,-1))? ? ? mul = im_col.dot(filter_col.T) + b? ? ? out[im_num,:,:,:] = col2im(mul,H_prime,W_prime,1)? cache = (x, w, b, conv_param)returnout, cache
im2col函數(shù):
defim2col(x,hh,ww,stride):"""
? ? Args:
? ? ? x: image matrix to be translated into columns, (C,H,W)
? ? ? hh: filter height
? ? ? ww: filter width
? ? ? stride: stride
? ? Returns:
? ? ? col: (new_h*new_w,hh*ww*C) matrix, each column is a cube that will convolve with a filter
? ? ? ? ? ? new_h = (H-hh) // stride + 1, new_w = (W-ww) // stride + 1
? ? """c,h,w = x.shape? ? new_h = (h-hh) // stride +1new_w = (w-ww) // stride +1col = np.zeros([new_h*new_w,c*hh*ww])foriinrange(new_h):forjinrange(new_w):? ? ? ? ? patch = x[...,i*stride:i*stride+hh,j*stride:j*stride+ww]? ? ? ? ? col[i*new_w+j,:] = np.reshape(patch,-1)returncol
5.3反向傳播圖
使用im2col,計算圖類似于具有相同格式的FC層
忍坷,不同之處在于有一堆重塑粘舟,轉(zhuǎn)置和im2col塊。
關(guān)于在反向傳播期間的重塑和轉(zhuǎn)置佩研,只需要再次使用另一個重塑或轉(zhuǎn)置來反轉(zhuǎn)它們的操作柑肴,需要注意的是,如果在向前傳播期間使用行優(yōu)先進行重塑旬薯,反向傳播中也要使用行優(yōu)先晰骑。
im2col反向傳播操作時。無法實現(xiàn)簡單的重塑绊序。這是因為感受野實際上是重合的(取決于步長)硕舆,所以需要將感受野相交的地方的梯度相加。
反向傳播代碼:
defconv_backward_naive(dout, cache):"""
? A naive implementation of the backward pass for a convolutional layer.
? Inputs:
? - dout: Upstream derivatives.
? - cache: A tuple of (x, w, b, conv_param) as in conv_forward_naive
? Returns a tuple of:
? - dx: Gradient with respect to x
? - dw: Gradient with respect to w
? - db: Gradient with respect to b
? """dx, dw, db =None,None,Nonex, w, b, conv_param = cache? pad_num = conv_param['pad']? stride = conv_param['stride']? N,C,H,W = x.shape? F,C,HH,WW = w.shape? H_prime = (H+2*pad_num-HH) // stride +1W_prime = (W+2*pad_num-WW) // stride +1dw = np.zeros(w.shape)? dx = np.zeros(x.shape)? db = np.zeros(b.shape)# We could calculate the bias by just summing over the right dimensions# Bias gradient (Sum on dout dimensions (batch, rows, cols)#db = np.sum(dout, axis=(0, 2, 3))foriinrange(N):? ? ? im = x[i,:,:,:]? ? ? im_pad = np.pad(im,((0,0),(pad_num,pad_num),(pad_num,pad_num)),'constant')? ? ? im_col = im2col(im_pad,HH,WW,stride)? ? ? filter_col = np.reshape(w,(F,-1)).T? ? ? dout_i = dout[i,:,:,:]? ? ? dbias_sum = np.reshape(dout_i,(F,-1))? ? ? dbias_sum = dbias_sum.T#bias_sum = mul + bdb += np.sum(dbias_sum,axis=0)? ? ? dmul = dbias_sum#mul = im_col * filter_coldfilter_col = (im_col.T).dot(dmul)? ? ? dim_col = dmul.dot(filter_col.T)? ? ? dx_padded = col2im_back(dim_col,H_prime,W_prime,stride,HH,WW,C)? ? ? dx[i,:,:,:] = dx_padded[:,pad_num:H+pad_num,pad_num:W+pad_num]? ? ? dw += np.reshape(dfilter_col.T,(F,C,HH,WW))returndx, dw, db
col2im函數(shù):
defcol2im(mul,h_prime,w_prime,C):"""
? ? ? Args:
? ? ? mul: (h_prime*w_prime*w,F) matrix, each col should be reshaped to C*h_prime*w_prime when C>0, or h_prime*w_prime when C = 0
? ? ? h_prime: reshaped filter height
? ? ? w_prime: reshaped filter width
? ? ? C: reshaped filter channel, if 0, reshape the filter to 2D, Otherwise reshape it to 3D
? ? Returns:
? ? ? if C == 0: (F,h_prime,w_prime) matrix
? ? ? Otherwise: (F,C,h_prime,w_prime) matrix
? ? """F = mul.shape[1]if(C ==1):? ? ? ? out = np.zeros([F,h_prime,w_prime])foriinrange(F):? ? ? ? ? ? col = mul[:,i]? ? ? ? ? ? out[i,:,:] = np.reshape(col,(h_prime,w_prime))else:? ? ? ? out = np.zeros([F,C,h_prime,w_prime])foriinrange(F):? ? ? ? ? ? col = mul[:,i]? ? ? ? ? ? out[i,:,:] = np.reshape(col,(C,h_prime,w_prime))returnout
col2im_back函數(shù):
defcol2im_back(dim_col,h_prime,w_prime,stride,hh,ww,c):"""
? ? Args:
? ? ? dim_col: gradients for im_col,(h_prime*w_prime,hh*ww*c)
? ? ? h_prime,w_prime: height and width for the feature map
? ? ? strid: stride
? ? ? hh,ww,c: size of the filters
? ? Returns:
? ? ? dx: Gradients for x, (C,H,W)
? ? """H = (h_prime -1) * stride + hh? ? W = (w_prime -1) * stride + ww? ? dx = np.zeros([c,H,W])foriinrange(h_prime*w_prime):? ? ? ? row = dim_col[i,:]? ? ? ? h_start = (i / w_prime) * stride? ? ? ? w_start = (i % w_prime) * stride? ? ? ? dx[:,h_start:h_start+hh,w_start:w_start+ww] += np.reshape(row,(c,hh,ww))returndx
5.4小案例
這里使用X[3x3]與W [2x2]進行卷積的簡單示例骤公,來幫助大家的理解抚官。
04
池化層
池化層用于減少特征空間的維度,但是不會改變特征圖的深度阶捆,它的左右有如下的幾點:
減少了特征空間信息凌节,內(nèi)存的使用更少钦听,計算速度也將更
防止過擬合
引入了位移不變性,更關(guān)注是否存在某些特征而不是特征具體的位置倍奢。比如最常見的max pooling朴上,因為取一片區(qū)域的最大值,所以這個最大值在該區(qū)域內(nèi)無論在哪娱挨,max-pooling之后都是它余指,相當(dāng)于對微小位移的不變性。
使用的最多的是最大池化跷坝,如下圖所示酵镜,最大池化像卷積核一樣滑動窗,并在窗口上獲得最大值作為輸出柴钻。
參數(shù)有:
輸入:H1 x W1 x Depth_In x N.
步長:控制窗口滑動的像素數(shù)量的標(biāo)量淮韭。
K:內(nèi)核大小
輸出:H2 x W2 x Depth_Out x N:
由于池化層上沒有可學(xué)習(xí)的參數(shù),所以它的反向傳播更簡單贴届。
最大池在其計算圖上使用一系列最大節(jié)點靠粪。因此,最大池化層的反向傳播包含在前向傳播期間選擇的所有元素和dout的掩碼之間的乘積毫蚓。
換句話說占键,最大池層的輸入的梯度是由前向傳播選擇的元素的梯度和0組成的張量。
1元潘、python實現(xiàn)池化層的前向傳播
池化層上的窗口移動機制與卷積核相同畔乙,不同之處在于池化層的窗口是選擇最大值。
2翩概、python實現(xiàn)池化層的反向傳播
參考文獻:
https://blog.csdn.net/byplane/article/details/52422997
https://mp.weixin.qq.com/s/oFWqM9HPhstk7H-GQY0O3g
作者:機器學(xué)習(xí)算法工程師
鏈接:http://www.reibang.com/p/efa807c256ae
來源:簡書
簡書著作權(quán)歸作者所有牲距,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。