关闭

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

标签: 神经网络深度学习
2546人阅读 评论(0) 收藏 举报
分类:

声明:参考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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:29360次
    • 积分:604
    • 等级:
    • 排名:千里之外
    • 原创:32篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条