一、CNN簡介
卷積神經網絡(Convolutional Neural Network,簡稱CNN)已經成為計算機視覺領域內的一種重要的深度學習網絡結構,主要用於圖像識別、目標檢測、圖像分割等任務。與傳統的神經網絡相比,CNN利用局部感受野、參數共享、下採樣等操作可以大大減少網絡參數數量,並且可以有效提取圖像特徵。
二、CNN反向傳播介紹
CNN反向傳播是CNN的訓練算法,是一種基於梯度下降的方法,用於權值(weight)的優化,從而讓網絡能夠更好地擬合數據。它的基本思想是通過計算預測值與真實值之間的誤差,通過鏈式法則將誤差從輸出層一直向前傳遞,最終得到每一層的梯度,以此來更新每一層的權值和偏差(bias)。它的前提條件是我們已經有一批已經標註的數據,通過CNN反向傳播算法來調整權重和偏差,使得損失函數最小。
三、CNN反向傳播原理
3.1 前向傳播
在訓練CNN之前,需要我們先對一張圖像進行前向傳播,計算出卷積層、池化層、全連接層的輸出層數據(預測值)。具體步驟如下:
for each conv layer do: conv_output = convolve(filter, input) pooled_output = max_pool(conv_output) input = pooled_output flatten_input = flatten(pooled_output) for each fc layer do: fc_output = active_function(W * flatten_input + b) flatten_input = fc_output
3.2 反向傳播
在計算出預測值之後,我們需要計算誤差以及梯度,為接下來的優化提供基礎。CNN反向傳播的流程可以分為以下幾個步驟:
3.2.1 計算第n層的誤差$\delta_n$
在反向傳播的過程中,我們需要從輸出層開始計算誤差,從而逐層往回傳遞,計算出每一層的誤差。具體計算公式如下:
$$\delta_n = \frac{\partial L}{\partial z_n}$$
其中,$z_n$表示第n層的加權輸入,$L$表示最終的損失函數,對於分類問題,通常採用交叉熵(Cross-Entropy)作為損失函數。
3.2.2 計算第n層的權重梯度$\frac{\partial L}{\partial W_n}$和偏差梯度$\frac{\partial L}{\partial b_n}$
根據鏈式法則,我們可以根據上層的誤差$\delta_{n+1}$和當前層的加權輸入$z_n$,計算出當前層的誤差$\delta_n$。然後,利用誤差和上一層輸出(或者輸入)的值,計算出該層的權重和偏差的梯度。
$$\frac{\partial L}{\partial W_n} = a_{n-1} \delta_n$$
$$\frac{\partial L}{\partial b_n} = \delta_n$$
3.2.3 計算第n-1層的誤差$\delta_{n-1}$
通過誤差反向傳播的過程,我們可以計算出每一層的誤差$\delta_n$,然後通過$\delta_{n-1} = f'(\phi_{n-1})W_n^T\delta_n $(其中$f'(\phi_{n-1})$表示激活函數的導數,$\phi_{n-1}$表示第n-1層的加權輸入)來計算前一層的誤差。
3.2.4 更新權重和偏差
我們可以根據之前計算出的權重和偏差梯度,利用梯度下降的算法,更新權重和偏差,來不斷縮小損失函數。具體算法如下:
$$W_n = W_n – \alpha\frac{\partial L}{\partial W_n}$$
$$b_n = b_n – \alpha\frac{\partial L}{\partial b_n}$$
其中,$\alpha$是學習率,表示每次更新的步長。
四、CNN反向傳播代碼實現
4.1 前向傳播
def forward_propagation(X, parameters): """ Implement the forward propagation of the CNN Arguments: X -- input data of shape (input_shape, number of examples) parameters -- python dictionary with parameters "W1", "b1", ..., "WL", "bL" W1 -- filter matrix of shape (f1, f1, depth_prev, channels) b1 -- bias vector of shape (1, 1, 1, channels) ... WL -- filter matrix of shape (fL, fL, depth_L-1, channels_L) bL -- bias vector of shape (1, 1, 1, channels_L) Returns: output_layer -- output of the last fully connected layer caches -- list of caches for each layer """ caches = [] A = X L = len(parameters) // 2 # conv and pooling layers for l in range(1, L+1): W = parameters['W' + str(l)] b = parameters['b' + str(l)] conv_output, conv_cache = conv_forward(A, W, b, stride=1, padding='valid') # convolutional layer pooled_output, pool_cache = pool_forward(conv_output, mode='max', pool_size=2, stride=2) # pooling layer cache = (conv_cache, pool_cache) caches.append(cache) A = pooled_output # flatten layer flatten_input, shape_input = flatten(A) # fully connected layers for l in range(L+1, 2*L): W = parameters['W' + str(l)] b = parameters['b' + str(l)] fc_output, fc_cache = fc_forward(flatten_input, W, b, activation='relu') cache = (fc_cache, shape_input) caches.append(cache) flatten_input = fc_output # output layer W = parameters['W' + str(2*L)] b = parameters['b' + str(2*L)] output_layer, output_cache = fc_forward(flatten_input, W, b, activation='softmax') caches.append(output_cache) return output_layer, caches
4.2 反向傳播
def backward_propagation(Y, output_layer, caches): """ Implement the backward propagation of the CNN Arguments: Y -- true "label" vector (containing 0 and 1) of shape (output_shape, number of examples) output_layer -- output of the last fully connected layer caches -- list of caches for each layer Returns: gradients -- python dictionary with gradients for each parameter """ gradients = {} L = len(caches) m = Y.shape[1] # output layer delta = softmax_backward(output_layer, Y) cache = caches[L-1] fc_cache, _ = cache dflatten_input, dW, db = fc_backward(delta, fc_cache, activation='softmax') gradients['dW' + str(L)] = dW gradients['db' + str(L)] = db # fully connected layers for l in reversed(range(L-1, L//2, -1)): cache = caches[l] fc_cache, shape_input = cache dflatten_input, dW, db = fc_backward(dflatten_input, fc_cache, activation='relu') gradients['dW' + str(l+1)] = dW gradients['db' + str(l+1)] = db # flatten layer dA = flatten_backward(dflatten_input, shape_input) # conv and pooling layers for l in reversed(range(L//2)): cache = caches[l] conv_cache, pool_cache = cache dpooled_output = pool_backward(dA, pool_cache, mode='max', pool_size=2, stride=2) dA, dW, db = conv_backward(dpooled_output, conv_cache) gradients['dW' + str(l+1)] = dW gradients['db' + str(l+1)] = db return gradients
五、總結
通過對CNN反向傳播原理和代碼實現的講解,我們對CNN的訓練過程有了更深入的認識。在CNN的訓練過程中,反向傳播算法是非常重要的一環,通過鏈式法則計算出誤差和梯度,再利用梯度下降的方法更新權重和偏差,從而達到訓練的目的。我們可以看到,雖然CNN的網絡結構很複雜,但藉助於反向傳播算法,我們可以非常簡單地實現CNN的訓練過程。相信通過深入地學習和練習,我們一定可以創建出更加優秀的CNN模型。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/246187.html