神经网络

神经网络介绍

神经网络(Neural Network)是机器学习中一类实用的算法,来源于与人脑的类比,但是它并不新,最早出现在20世纪80年代,至今在许多领域得到广泛使用。

神经网络的作用是可以用线性运算表征变量之间复杂的非线性关系,可以理解成逻辑回归中使用的 x2,x3,x1x2 等高次项,从而减少所使用特征的数量。具体在计算机视觉中,对于物体识别问题,假如用图像像素点作为特征学习,那么对于50x50像素的图像,其特征数量是2500个,如果结果与这些变量之间存在非线性关系,则要用到的特征数量会更多。


car detection
features

神经网络的基本结构如图所示


神经网络结构图

每一个逻辑单元称为神经元(Neuron),其中 x0 a(2)0 称为偏置单元(bias unit),恒等于1,在大多数神经网络结构示意图中不画出来,但在计算中要用到。

神经网络的数学模型计算类似于逻辑回归的升级版,在上图中

a(2)1=g(Θ(1)10x0+Θ(1)11x1+Θ(1)12x2+Θ(1)13x3)
a(2)2=g(Θ(1)20x0+Θ(1)21x1+Θ(1)22x2+Θ(1)23x3)
a(2)3=g(Θ(1)30x0+Θ(1)31x1+Θ(1)32x2+Θ(1)33x3)
hΘ(x)=a(3)1=g(Θ(2)10a(2)0+Θ(2)11a(2)1+Θ(2)12a(2)2+Θ(2)13a(2)3)

这里,
a(j)i 表示第 j 层第i个神经元的“激励”(activation)
Θ(j) 表示从第 j 层到第j+1层的加权矩阵(matrix of weights),考虑偏置单元时,如果第 j 层有sj个神经元,第 j+1 层有 sj+1 个神经元,则 Θ(j) 的维数是 sj+1×(sj+1)
g(z)=11+ez 即S型函数,在神经网络中也称为激励函数(activation function)。

图示的神经网络分为三层:输入层(input layer),隐含层(hidden layer)和输出层(output layer)。在其它更复杂神经网络中通常不止三层,实际上是隐含层不止一层。


这里写图片描述

从一个例子看看神经网络如何表示变量间的非线性关系,以同或关系为例,记作 x1 XNOR x2

先依次看看基本逻辑运算与或非在两层神经网络中的实现

Θ(1)=[302020] ,可以得到 hΘ(x)=g(30+20x1+20x2) ,对于 x1,x2{0,1} ,可以计算得到如图真值表,从而实现和运算


AND

类似的,令 Θ(1)=[102020] ,实现或运算


OR

Θ(1)=[1020] ,实现非运算


NOT

这样,理论上就可以通过组合实现任意逻辑运算。


XNOR

如图,按以上选择权值,则实现了 a(2)1= x1 AND x2 a(2)2= x1 NAND x2 hΘ(x)= a(2)1 OR a(2)2 ,从而实现了 hΘ(x)= x1 XOR x2

另外,在多分类问题中,通常把 y{1,2,3,4} 改写成 y=1000,010000100001 ,这样表示就把多分类问题表示成输出层大于一个神经元的形式,可以进行一般化的运算。

反向传播算法(Backpropagation Algorithm)

反向传播算法是神经网络中用于优化代价函数,求得合适参数的算法,类似于逻辑回归中梯度下降法等方法。
神经网络中代价函数的表达式与逻辑回归中的比较:


这里写图片描述

显而易见其中每一项的意义,其中包含正规化。

明确一点,对于要调用训练算法去计算合适的参数 Θ ,需要计算代价函数的值 J(Θ) 和梯度值 Θ(l)ijJ(Θ) ,代价函数的值由定义可以计算得出,梯度值则由反向传播算法计算得出,算法如下:


Backpropagation algorithm

Training set {(x(1),y(1)),...,(x(m),y(m))}
Set (l)ij=0 (for all l,i,j ).
For i=1 to m
  Set a(1)=x(i)
  Perform forward propagation to compute a(l) for l=2,3,...,L
  Compute δ(L)=a(L)y(i)
   δ(L1)=(Θ(L1))Tδ(4).g(z(3)) , compute δ(L1),δ(L2),...,δ(2)
   (l)ij:=(l)ij+a(l)jδ(l+1)i
D(l)ij:=1m(l)ij+λΘ(l)ij1m(l)ij if j0 if j=0
Θ(l)ijJ(Θ)=D(l)ij


其中,前向传播(forward propagation)是


a(1)=x
z(l)=Θ(l1)a(l1)l2
a(l)=g(z(2))(add a(l)0)l2
hΘ(x)=a(L)=g(z(L))


对于反向传播算法的理解,可以理解为每一个节点的当前值与最优值之间的偏差,即对 δ(l)j ,表示第 l 层第j个节点的“误差”,最后计算的 (l)ij 则是累计的“误差”。这里省略了所有的数学推导,最终只要理解在算法中对梯度的计算是一种偏差的计算,会用即可。

梯度检查(Gradient Checking)

在实际算法实现过程中,往往很难做检验算法实现的对错,这里用一种叫梯度检查的方法用于检查梯度算得是否正确,直接来源于导数的极限定义。在一维中,导数的极限定义是

ddθJ(θ)=limϵ0J(θ+ϵ)J(θϵ)2ϵ

所以当检验梯度时,可以用
θ1J(θ)J(θ1+ϵ,θ2,...,θn)J(θ1ϵ,θ2,...,θn)2ϵ
θ2J(θ)J(θ1,θ2+ϵ,...,θn)J(θ1,θ2ϵ,...,θn)2ϵ
...
θnJ(θ)J(θ1,θ2,...,θn+ϵ)J(θ1,θ2,...,θnϵ)2ϵ

检验梯度的近似值。需要注意的是这种计算方法比起前面的反向传播算法要慢很多,所以只是用于检验,一旦确定算法实现没有问题,就要把这段检验的代码注释。另外,这种检查方法适合一切需要计算梯度的情况。

随机初始化(Random Initialization)

由于在神经网络中,对于每一层的各个节点进行相同的操作,因此,假如像逻辑回归时那样把全部参数初始化为0,则最后经过训练得到的每一层参数必然是相同的,这就减弱了神经网络的作用,带来误差。因此,初始化权值参数时需要随机初始化。随机初始化的操作和原因都很好理解,但在算法实现中是必要的细节步骤。

总结

综合来说,神经网络的训练算法如下:


1.随机初始化权值 Θ
2.实现前向传播算法对每一个输入的样本 x(i) 计算 hΘ(x(i)) ,包括每一层每个节点的 a(l)j z(l)j
3.实现代价函数 J(Θ)
4.实现反向传播算法计算梯度 Θ(l)jkJ(Θ)
5.用梯度检查方法比较反向传播算法得到 Θ(l)jkJ(Θ) J(Θ) 梯度的数值估计
6.用梯度下降法或者其它优化方法,由 J(Θ) Θ(l)jkJ(Θ) 计算得到最优参数 Θ


实现代码如下:(只给出核心部分,省略初始化等细节计算)

% 初始化权值,L_in、L_out分别为权值两端的节点个数,如L_in = input_layer_size, L_out = hidden_layer_size
epsilon_init = 0.12;
W = rand(L_out, 1 + L_in) * 2 * epsilon_init - epsilon_init;

% 前向传播算法计算假设函数
X = [ones(m,1) X];
a1 = X;
z2 = X * Theta1';
a2 = [ones(size(z2,1),1) sigmoid(z2)];
z3 = a2 * Theta2';
hyp = sigmoid(z3);

% 计算代价函数以及正规化
y_temp = zeros(m,num_labels);
for i = 1:m
    y_temp(i,y(i)) = 1;
end
J = 1/m*sum(sum(-y_temp.*log(hyp) - (1-y_temp).*log(1-hyp)));
J = J + lambda/2/m*(sum(sum(Theta1(:,2:end).^2)) + sum(sum(Theta2(:,2:end).^2)));

% 反向传播算法计算梯度
sigma3 = hyp - y_temp;
sigma2 = sigma3 * Theta2(:,2:end) .* sigmoidGradient(z2);
delta1 = sigma2' * a1;
delta2 = sigma3' * a2;
Theta1_grad = 1/m*delta1 + lambda/m*[zeros(size(Theta1,1),1) Theta1(:,2:end)];
Theta2_grad = 1/m*delta2 + lambda/m*[zeros(size(Theta2,1),1) Theta2(:,2:end)];

% 梯度方法数值检查
numgrad = zeros(size(theta));
perturb = zeros(size(theta));
e = 1e-4;
for p = 1:numel(theta)
    % Set perturbation vector
    perturb(p) = e;
    loss1 = J(theta - perturb);
    loss2 = J(theta + perturb);
    % Compute Numerical Gradient
    numgrad(p) = (loss2 - loss1) / (2*e);
    perturb(p) = 0;
end

% 优化计算得到权值
options = optimset('MaxIter', 50);
lambda = 1;
% Create "short hand" for the cost function to be minimized
costFunction = @(p) nnCostFunction(p, ...
                                   input_layer_size, ...
                                   hidden_layer_size, ...
                                   num_labels, X, y, lambda);
% Now, costFunction is a function that takes in only one argument (the
% neural network parameters)
[nn_params, cost] = fmincg(costFunction, initial_nn_params, options);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值