神經網絡及其實現
神經網絡及其實現
神經網絡的表示
最小的神經網絡
兩層神經網絡
在下圖的表示中將參數b放到了中,每一層增加了一個值為1的隱藏單元
X為輸入變量
為權重矩陣(所要計算的參數)
為隱藏層變量
g為激活函數
反向傳播算法
下面我們從一個簡單的例子入手考慮如何從數學上計算代價函數的梯度,考慮如下簡單的神經網絡,該神經網絡有三層神經元,對應的兩個權重矩陣,為了計算梯度我們只需要計算兩個偏導數即可:
首先計算第二個權重矩陣的偏導數,即
首先需要在之間建立聯系,很容易可以看到的值取決於,而,而又是由取sigmoid得到,最後,所以他們之間的聯系可以如下表示:
按照求導的鏈式法則,我們可以先求對的導數,然後乘以對的導數,即
由於
不難計算
令
上式可以重寫為
接下來僅需要計算即可,由於
忽略前面的
設k=1得到
這裏只對一個example推導,最後累加即可
因此
得到下面的求導過程
由於
,計算如下,得
至此我們得到了
接下去我們需要求的偏導數,的依賴關系如下:
根據鏈式求導法則有
分別計算等式右邊的三項可得
帶入後得
令
上式可以重寫為
將上面的結果放在一起,我們得到對兩個權重矩陣的偏導數為:
觀察上面的四個等式,我們發現
- 偏導數可以由當層神經元向量與下一層的誤差向量相乘得到
- 當前層的誤差向量可以由下一層的誤差向量與權重矩陣的乘積得到
所以可以從後往前逐層計算誤差向量,然後通過簡單的乘法運算得到代價函數對每一層權重矩陣的偏導數。
假設我們有m個訓練example,L層神經網絡即
初始化:設置(理解為對第l層的權重矩陣的偏導累加值,每一個訓練的偏導數累加值,最後再除以樣本數得到均值)
參數w和b的初始化
For k=1:m
設置 =
通過前向傳播算法(FP)計算對各層的預測值,其中l=1,2,3,4…,L
計算最後一層的誤差向量,利用後向傳播算法(BP)從後至前逐層計算誤差向量,計算公式為
更新
End//
計算梯度:
通過梯度下降的方法來更新梯度,從而使代價函數達到最小的目的。
激活函數
上式例子中的激活函數g為SIGMOID
常見的激活函數還有TANH,RELU,LEAKY RELU
sigmoid激活函數的數學表達式如下
tanh激活函數的數學表達式如下
RELU激活函數
Leak RELU激活函數
註意:神經網絡中的激活函數不能為非線性
如果激活函數為線性函數的話,不管你加多少隱藏層,都會和logistic回歸一樣
正則化
正則化可以用來幫助神經網絡減少方差防止過擬合
常見的正則化有L1,L2
神經網絡的matlab實現
sigmoid函數
function g = sigmoid(z)
g = 1.0 ./ (1.0 + exp(-z));
end
sigmoid函數求導
function g = sigmoidGradient(z)
g = zeros(size(z));
g = sigmoid(z) .* (1 - sigmoid(z));
end
初始化權重參數
function W = randInitializeWeights(L_in, L_out)
W = zeros(L_out, 1 + L_in);
epsilon_init = 0.12;
W = rand(L_out, 1 + L_in) * 2 * epsilon_init - epsilon_init;
end
計算代價函數(包含實現了前向傳播和反向傳播)
function [J grad] = nnCostFunction(nn_params, ...
input_layer_size, ...
hidden_layer_size, ...
num_labels, ...
X, y, lambda)
Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)),hidden_layer_size, (input_layer_size + 1));
Theta2 = reshape(nn_params((1 + (hidden_layer_size *(input_layer_size + 1))):end),num_labels, (hidden_layer_size + 1));
% Setup some useful variables
m = size(X, 1);
J = 0;
Theta1_grad = zeros(size(Theta1));
Theta2_grad = zeros(size(Theta2));
%% Part 1 前向傳播的實現
a1 = [ones(m, 1) X];
z2 = a1 * Theta1‘;
a2 = sigmoid(z2);
a2 = [ones(size(a2,1), 1) a2];
z3 = a2 * Theta2‘;
a3 = sigmoid(z3);
hThetaX = a3;
yVec = zeros(m,num_labels);
for i = 1:m
yVec(i,y(i)) = 1;
end
%% 計算代價函數
J = 1/m * sum(sum(-1 * yVec .* log(hThetaX)-(1-yVec) .* log(1-hThetaX)));
%% 正則化項
regularator = (sum(sum(Theta1(:,2:end).^2)) + sum(sum(Theta2(:,2:end).^2))) * (lambda/(2*m));
J = J + regularator;
%% Part 2 反向傳播的實現
for t = 1:m
% For the input layer, where l=1:
a1 = [1; X(t,:)‘];
% For the hidden layers, where l=2:
z2 = Theta1 * a1;
a2 = [1; sigmoid(z2)];
z3 = Theta2 * a2;
a3 = sigmoid(z3);
yy = ([1:num_labels]==y(t))‘;
% For the delta values:
delta_3 = a3 - yy;
delta_2 = (Theta2‘ * delta_3) .* [1; sigmoidGradient(z2)];
delta_2 = delta_2(2:end); % Taking of the bias row
% delta_1 is not calculated because we do not associate error with the input
% Big delta update
Theta1_grad = Theta1_grad + delta_2 * a1‘;
Theta2_grad = Theta2_grad + delta_3 * a2‘;
end
Theta1_grad = (1/m) * Theta1_grad + (lambda/m) * [zeros(size(Theta1, 1), 1) Theta1(:,2:end)];
Theta2_grad = (1/m) * Theta2_grad + (lambda/m) * [zeros(size(Theta2, 1), 1) Theta2(:,2:end)];
% Unroll gradients
grad = [Theta1_grad(:) ; Theta2_grad(:)];
end
訓練神經網絡及預測
%% Initialization
clear ; close all; clc
%% Setup the parameters you will use for this exercise
input_layer_size = 400; % 20x20 Input Images of Digits
hidden_layer_size = 25; % 25 hidden units
num_labels = 10; % 10 labels, from 1 to 10
% (note that we have mapped "0" to label 10)
% 加載訓練數據
load(‘data.mat‘);
% 初始化權重參數
initial_Theta1 = randInitializeWeights(input_layer_size, hidden_layer_size);
initial_Theta2 = randInitializeWeights(hidden_layer_size, num_labels);
% Unroll parameters
initial_nn_params = [initial_Theta1(:) ; initial_Theta2(:)];
options = optimset(‘MaxIter‘, 50);
lambda = 1;
costFunction = @(p) nnCostFunction(p, ...
input_layer_size, ...
hidden_layer_size, ...
num_labels, X, y, lambda);
% 實現叠代計算梯度
[nn_params, cost] = fmincg(costFunction, initial_nn_params, options);
% 獲得訓練好的權重參數
Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)),hidden_layer_size, (input_layer_size + 1));
Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), num_labels, (hidden_layer_size + 1));
% 實現預測
pred = predict(Theta1, Theta2, X);
fprintf(‘\nTraining Set Accuracy: %f\n‘, mean(double(pred == y)) * 100);
神經網絡及其實現