1. 程式人生 > >神經網絡及其實現

神經網絡及其實現

技術 正則化 gree psi radi variables 幫助 span 神經網絡

神經網絡及其實現

神經網絡的表示

最小的神經網絡

技術分享圖片

兩層神經網絡

技術分享圖片

在下圖的表示中將參數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);

神經網絡及其實現