神经网络

来源:互联网 发布:中铁采购网络交易平台 编辑:程序博客网 时间:2024/06/04 19:45

神经网络介绍

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

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


car detection
features

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


神经网络结构图

每一个逻辑单元称为神经元(Neuron),其中x0a(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 x2a(2)2= x1 NAND x2hΘ(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)jz(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_sizeepsilon_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;endJ = 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 minimizedcostFunction = @(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 0
原创粉丝点击