神经网络笔记(Neural Network)
来源:互联网 发布:武汉淘宝摄影师招聘 编辑:程序博客网 时间:2024/05/17 04:01
- Neural Network model
- Forward Propagation
- Backpropagation Alrithm
- Vectorization
- Logistic Regression
- Neural Network
- Forward Propagation
- Back Propagation
- summary
给定训练样本集
最简单的神经网络是神经元,如下图:
这个神经元输入
其他常用的激活函数还有tanh函数:
以下是三个函数的图像:
Neural Network model
将多个神经元连接起来便成了神经网络,如下图的例子:
用
以上例子中,神经网络的参数为
用
Forward Propagation
以上神经网络计算步骤如下:
在上面等式中,通常用
如果将函数
这个步骤叫做前向传播(Forward propagation)。
更一般地,定义
Backpropagation Alrithm
假设我们有训练集
具体来说,对于单个训练样例
对于m个样例的数据集,cost function定义为:
第一项为均方差项,第二项为规则化项,减小权重幅度,防止过拟合。
对于参数
因为
最后,需要再次强调的是,要将参数进行随机初始化,而不是全部置为0。如果所有参数都用相同的值作为初始值,那么所有隐藏层单元最终会得到与输入值有关的、相同的函数(也就是说,对于所有
梯度下降法中每一次迭代都按照如下公式对参数 \textstyle W 和\textstyle b 进行更新:
其中
接着介绍反向传播算法,它是一种计算偏导的有效方法。
用反向传播算法来计算
以上两行公式稍有不同,第一行比第二行多出一项,是因为权重衰减是作用于
反向传播算法主要思想是先进行向前传播,计算网络中所有的值。然后针对第
具体实现:
- 进行前馈传导计算,利用前向传导公式,得到
L2,L3,… 直到输出层Lnl 的激活值。 - 对于第
nl 层(输出层)的每个输出单元i ,我们根据以下公式计算残差:δ(nl)i=∂∂znliJ(W,b;x,y)=∂∂znli12||y−hW,b(x)||2=∂∂znli12∑Snlj=1(yj−a(nl)j)2=∂∂znli12∑Snlj=1(yj−f(z(nl)j))2=−(yi−f(z(nl)i))⋅f′(z(nl)i)=−(yi−a(nl)i)⋅f′(z(nl)i) - 对
l=nl−1,nl−2,nl−3,…,2 的各个层,第l 层的第i 个节点的残差计算方法如下:δ(nl−1)i=∂∂znl−1iJ(W,b;x,y)=∂∂znl−1i12∥∥y−hW,b(x)∥∥2=∂∂znl−1i12∑Snlj=1(yj−a(nl)j)2=12∑Snlj=1∂∂znl−1i(yj−a(nl)j)2=12∑Snlj=1∂∂znl−1i(yj−f(z(nl)j))2=∑Snlj=1−(yj−f(z(nl)j))⋅∂∂z(nl−1)if(z(nl)j)=∑Snlj=1−(yj−f(z(nl)j))⋅f′(z(nl)j)⋅∂z(nl)j∂z(nl−1)i=∑Snlj=1δ(nl)j⋅∂z(nl)j∂znl−1i=∑Snlj=1(δ(nl)j⋅∂∂znl−1i∑Snl−1k=1f(znl−1k)⋅Wnl−1jk)=∑Snlj=1δ(nl)j⋅Wnl−1ji⋅f′(znl−1i)=(∑Snlj=1Wnl−1jiδ(nl)j)f′(znl−1i)
将上式中的nl−1 与nl 的关系替换为l 与l+1 的关系,就可以得到:δ(l)i=(∑sl+1j=1W(l)jiδ(l+1)j)f′(z(l)i)
4.计算偏导数:∂∂W(l)ijJ(W,b;x,y)=a(l)jδ(l+1)i∂∂b(l)iJ(W,b;x,y)=δ(l+1)i
扩展函数
- 进行前馈传导计算,利用前向传导公式,得到
L2,L3,… 直到输出层Lnl 的激活值。 - 对输出层(第
nl 层),计算:δ(nl)=−(y−a(nl)).∗f′(z(nl)) 。 - 对于
l=nl−1,nl−2,nl−3,…,2 的各层,计算:δ(l)=((W(l))Tδ(l+1)).∗f′(z(l)) 。 - 计算最终需要的偏导数值:
∇W(l)J(W,b;x,y)=δ(l+1)(a(l))T ∇b(l)J(W,b;x,y)=δ(l+1) 。
Vectorization
使用学习算法时,一段更快的代码通常意味着项目进展更快。
总而言之,矢量化编程是提高算法速度的一种有效方法。思想是尽量使用被高度优化的数值运算操作来实现学习算法。
在matlab中,矢量化的诀窍在于:代码中尽量避免显式的for循环。
调试方法:刚开始编写程序的时候,你可能会选择不使用太多矢量化技巧来实现你的算法,并验证它是否正确(可能只在一个小问题上验证)。在确定它正确后,你可以每次只矢量化一小段代码,并在这段代码之后暂停,以验证矢量化后的代码计算结果和之前是否相同。
Logistic Regression
用批量梯度上升法对logistic回归分析模型进行训练,其模型如下:
符号定义:设
初实现,循环嵌套,速度非常慢:
grad = zeros(n+1,1);for i = 1 : m, h = sigmoid(theta'*x(:,i)); temp = y(i) - h; for j = 1 : n+1, grad(j) = grad(j) + temp * x(j,i); end;end;
优化内层循环:
grad = zeros(n+1,1);for i=1:m, grad = grad + (y(i) - sigmoid(theta'*x(:,i)))* x(:,i);end;
彻底优化:
特别的,假定b是一个列向量,A是一个矩阵,我们用以下两种方式来计算A*b:
% 矩阵-向量乘法运算的低效代码grad = zeros(n+1,1);for i=1:m, grad = grad + b(i) * A(:,i); % 通常写法为A(:,i)*b(i)end;% 矩阵-向量乘法运算的高效代码grad = A*b;
将b(i)看成(y(i) - sigmoid(theta’*x(:,i))),A看成x,我们就可以使用以下高效率的代码:
grad = x * (y- sigmoid(theta'*x));
这里假定sigmoid(z)函数接受一个向量形式的输入z,依次对输入向量的每个元素施行sigmoid函数,最后返回运算结果,因此sigmoid(z)的输出结果是一个与z有相同维度的向量。
Neural Network
Forward Propagation
考虑一个三层网络(一个输入层、一个隐含层、以及一个输出层),并且假定x是包含一个单一训练样本x^{(i)} \in \Re^{n} 的列向量。则向量化的正向传播步骤如下:
这对于单一训练样本而言是非常有效的一种实现,但是当我们需要处理m个训练样本时,则需要把如上步骤放入一个for循环中。
% 非向量化实现for i=1:m, z2 = W1 * x(:,i) + b1; a2 = f(z2); z3 = W2 * a2 + b2; h(:,i) = f(z3);end;
向量化:
% 正向传播的向量化实现z2 = W1 * x + repmat(b1,1,m);a2 = f(z2);z3 = W2 * a2 + repmat(b2,1,m);h = f(z3)
其中repmat(A,m,n)函数能够把矩阵A,扩展成m行n列个A。比如:
B=repmat( [1 2;3 4],2,3)得到:
激活函数实现:
% 低效的、非向量化的激活函数实现function output = unvectorized_f(z)output = zeros(size(z))for i=1:size(z,1), for j=1:size(z,2), output(i,j) = 1/(1+exp(-z(i,j))); end; end;end% 高效的、向量化激活函数实现function output = vectorized_f(z)output = 1./(1+exp(-z)); % "./" 在Matlab或Octave中表示对矩阵的每个元素分别进行除法操作end
Back Propagation
假定网络的输出有
还是以三层为例子,优化前:
% 'for' version for i = 1 : m y_vec = zeros(1, num_labels); y_vec(y(i)) = 1; delta3 = a3(i, :) - y_vec; %1 10 delta2 = delta3 * Theta2 .* [0 sigmoidGradient(z2(i, :))]; %1 26 delta2 = delta2(2 : end); %1 25 Theta2_grad = Theta2_grad + delta3' * a2(i, :); Theta1_grad = Theta1_grad + delta2' * a1(i, :); end
向量化:
% vectorize y_vec = zeros(m, num_labels); for i = 1 : m y_vec(i, y(i)) = 1; end delta3 = a3 - y_vec; delta2 = delta3 * Theta2 .* [zeros(m, 1), sigmoidGradient(z2)]; delta2 = delta2(:, 2:end); Theta2_grad = delta3' * a2; Theta1_grad = delta2' * a1;
summary
拿之前那个手写识别来试了下,这个优化是相当可观的。
向量化之前:
向量化之后:
优化之后的costFunction:
function [J grad] = CostFunction(nn_params, ... input_layer_size, ... hidden_layer_size, ... num_labels, ... X, y, lambda) m = size(X, 1); 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)); J = 0; Theta1_grad = zeros(size(Theta1)); Theta2_grad = zeros(size(Theta2));% =========== Feedforward ========== % a1 = [ones(m, 1) X]; %5000 401 z2 = a1 * Theta1'; %5000 25 a2 = [ones(m, 1) sigmoid( z2 )]; %5000 26 z3 = a2 * Theta2'; %5000 10 a3 = sigmoid( z3 ); %5000 10 hx = a3; %5000 10% ====================================== %% =========== cost =================== %% 'for' version% for i = 1 : m% y_vec = zeros(1, num_labels);% y_vec(y(i)) = 1;% J = J + sum( -y_vec .* log(hx(i, :)) - (1 - y_vec) .* log(1 - hx(i, :)) );% end% vectorize y_vec = zeros(m, num_labels); for i = 1 : m y_vec(i, y(i)) = 1; end tmp = -y_vec .* log(hx) - (1 - y_vec) .* log(1 - hx); J = J + sum( tmp(:) ); J = J / m; J = J + lambda/(2*m) * (sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2:end).^2)));% ======================================= % % =========== backpropagation ========== %% 'for' version% for i = 1 : m% y_vec = zeros(1, num_labels);% y_vec(y(i)) = 1;% delta3 = a3(i, :) - y_vec; %1 10% delta2 = delta3 * Theta2 .* [0 sigmoidGradient(z2(i, :))]; %1 26% delta2 = delta2(2 : end); %1 25% Theta2_grad = Theta2_grad + delta3' * a2(i, :);% Theta1_grad = Theta1_grad + delta2' * a1(i, :);% end% vectorize y_vec = zeros(m, num_labels); for i = 1 : m y_vec(i, y(i)) = 1; end delta3 = a3 - y_vec; delta2 = delta3 * Theta2 .* [zeros(m, 1), sigmoidGradient(z2)]; delta2 = delta2(:, 2:end); Theta2_grad = delta3' * a2; Theta1_grad = delta2' * a1;% ====================================== % Theta2_grad = Theta2_grad / m; Theta1_grad = Theta1_grad / m;% regularization Theta1(:, 1) = 0; Theta1_grad = Theta1_grad + lambda / m * Theta1; Theta2(:, 1) = 0; Theta2_grad = Theta2_grad + lambda / m * Theta2; grad = [Theta1_grad(:) ; Theta2_grad(:)];end
- 神经网络笔记(Neural Network)
- 神经网络(Neural Network)概述
- 神经网络(Neural Network)
- 神经网络 neural network
- NN(Neural Network神经网络)
- 【论文笔记】二值化神经网络(Binarized Neural Network)
- 台湾大学机器学习笔记——Neural Network 神经网络
- 深度学习笔记(1)——神经网络(neural network)
- 【论文笔记】二值化神经网络(Binarized Neural Network)
- 卷积神经网络 convolutional neural network
- 脉冲神经网络Spiking neural network
- 神经网络算法Neural Network介绍
- Artificial Neural Network(人工神经网络)
- Neural Network 笔记
- cs231n neural network 笔记
- Neural Network Concept神经网络(一)
- 人工神经网络(ANN, artificial neural network)
- 神经网络(Neural Network)的表示
- ffmpeg将图片序列转为视频
- Android 电话系统框架介绍
- 如何用Swift制作一个简单的画板APP
- leetcode Candy
- Qt将Sqlite中的表数据导出为CSV格式表格数据
- 神经网络笔记(Neural Network)
- compress_mall_special.sh
- 【项目 1 - C/C++语言中函数参数传递的三种方式】
- html学习笔记之Table表格
- 第二周项目3-体验复杂度(2)汉诺塔
- 快速配置Maven到OSChina中央库的教程
- 自动识别浏览器核心加前缀
- java成员内部类
- C#开发学习笔记:C#通过存储过程创建数据表