三层神经网络自编码算法推导和MATLAB实现

来源:互联网 发布:淘宝更换类目有影响吗 编辑:程序博客网 时间:2024/06/05 20:19

声明:参考Andrew Ng深度学习课件以及tornadomeet博文的代码。

自编码算法定义

有监督的神经网络需要我们的数据是有标注(Labeled)的,然而神经网络并不止限于处理有标注的数据,同时还能处理无标注的数据,形如:
x(1),x(2),x(3),...x(i)Rn
AutoEncoder-自编码网络可以处理此类算法。

这里写图片描述

自编码神经网络尝试学习一个hw,b(x)x 的函数。

参数设置

输入:x
输出:a(l)j l层j个节点的激活度
权重:w,b

平均活跃度

隐藏神经元j的平均活跃度

ρ^j=1mi=1m[a(2)j(xi)].

加入限制条件ρ^=ρ,其中ρ是稀疏性参数,通常是一个接近于0的较小值,换句话说是要让隐藏神经元j的平均活跃度接近ρ,为实现这一限制,可以通过求解优化函数相对熵的和最小来保证

j=1s2KL(ρ||ρ^j)=j=1s2ρlogρρ^+(1ρ)log1ρ1ρ^j.

设置ρ=0.2KL(ρ||ρ^j)ρ^j的变化趋势:
这里写图片描述

代价函数

对于固定子集(x(1),y(1)),,(x(m),y(m))包含m个样例。

单个样例的代价函数

J(ω,b;x,y)=12||hω,b(x)y||2.
其中,
hω,b(x)=a(3)=f(z(3))
z(3)=W(2)a(2)+b(2)
a(2)=f(z(2))
z(2)=W(1)x+b(1)

整体样例代价函数

这里写图片描述

cost公式

cost=Jcost+λJweight+βJsparse

matlab代码实现

数据为10000张8*8的图像,三层神经网络,隐藏层25个节点,输入和输出都是64个节点。

W1 = reshape(theta(1:hiddenSize*visibleSize), hiddenSize, visibleSize);W2 = reshape(theta(hiddenSize*visibleSize+1:2*hiddenSize*visibleSize), visibleSize, hiddenSize);b1 = theta(2*hiddenSize*visibleSize+1:2*hiddenSize*visibleSize+hiddenSize);b2 = theta(2*hiddenSize*visibleSize+hiddenSize+1:end);cost = 0;Jcost = 0;%直接误差Jweight = 0;%权值惩罚Jsparse = 0;%稀疏性惩罚[n m] = size(data);%m为样本的个数,n为样本的特征数%前向算法计算各神经网络节点的线性组合值和active值z2 = W1*data+repmat(b1,1,m);%注意这里一定要将b1向量复制扩展成m列的矩阵a2 = sigmoid(z2);z3 = W2*a2+repmat(b2,1,m);a3 = sigmoid(z3);% 计算预测产生的误差Jcost = (0.5/m)*sum(sum((a3-data).^2));%计算权值惩罚项Jweight = (1/2)*(sum(sum(W1.^2))+sum(sum(W2.^2)));%计算稀释性规则项rho = (1/m).*sum(a2,2);%求出第一个隐含层的平均值向量Jsparse = sum(sparsityParam.*log(sparsityParam./rho)+ ...        (1-sparsityParam).*log((1-sparsityParam)./(1-rho)));%损失函数的总表达式cost = Jcost+lambda*Jweight+beta*Jsparse;

反向传播

整体思路

这里写图片描述

计算偏导数

这里写图片描述
这里写图片描述

整体代价函数偏导

这里写图片描述

更新公式

这里写图片描述

MATLAB代码

%反向算法求出每个节点的误差值d3 = -(data-a3).*sigmoidInv(z3);sterm = beta*(-sparsityParam./rho+(1-sparsityParam)./(1-rho));%因为加入了稀疏规则项,所以                                                             %计算偏导时需要引入该项d2 = (W2'*d3+repmat(sterm,1,m)).*sigmoidInv(z2); %计算W1grad W1grad = W1grad+d2*data';W1grad = (1/m)*W1grad+lambda*W1;%计算W2grad  W2grad = W2grad+d3*a2';W2grad = (1/m).*W2grad+lambda*W2;%计算b1grad b1grad = b1grad+sum(d2,2);b1grad = (1/m)*b1grad;%注意b的偏导是一个向量,所以这里应该把每一行的值累加起来%计算b2grad b2grad = b2grad+sum(d3,2);b2grad = (1/m)*b2grad;
2 0