本文参考吴恩达教授2010年机器学习课程中bp神经网络的实现思路。
代价函数
误差项计算
反向传播伪代码
理解反向传播
在此基础上采用梯度下降法等优化算法即可实现神经网络参数估计。下面给出matlab解决鸢尾花分类问题的代码。
神经网络参数预测
function [ w1,w2] = NN( x, y, lamda,units, alpha )
% 实现一个包含一个隐含层,隐含层中非偏置单元数为units的bp神经网络,用于分类问题
% 激活函数采用sigmoid
% lamda为正则率(学习率),units为隐含层单元数
% 要求y的类别用1~k的连续整数表示
m=size(x,1);%记录训练集样本总数
n=size(x,2);%记录输入层非偏置单元数
k=length(unique(y));%记录输出单元数
yy=zeros(m,k);%对y进行扩展,以便计算误差
for i=1:m
for j=1:k
if y(i)==j
yy(i,j)=1;
end
end
end
%将x归一化至0,1区间内(这步很重要)
for i=1:n
maxx=max(x(:,i));
minx=min(x(:,i));
for j=1:m
xxx(j,i)=(maxx-x(j,i))/(maxx-minx);
end
end
x=xxx;
w1=rand(units, n+1)*0.01;%输入层到隐藏层的权重矩阵
w2=rand(k,units+1)*0.01;%隐藏层到输出层的权重矩阵
delta2=zeros(k,units+1);
delta1=zeros(units,n+1);
count=0;
max_loop=1000;%设置最大循环次数
while count<max_loop
count=count+1;
for i=1:m
%%前向传播
a1=[1,x(i,:)];
z2=w1*a1';%计算隐含层的z
for j=1:units
a2(j)=1/(1+exp(-z2(j)));%激活函数为sigmod函数
end
z3=w2*[1,a2]';%计算输出层的a
for j=1:k
a3(j)=1/(1+exp(-z3(j)));%激活函数为sigmod函数
end
error3=yy(i,:)-a3;%计算输出层误差
error2=error3*w2.*[1,a2].*(1-[1,a2]);%计算隐藏层误差
delta2=delta2+error3'*[1,a2];
p=error2'*a1;
delta1=delta1+p(2:units+1,:);
D2=delta2./m+lamda.*w2;
D1=delta1./m+lamda.*w1;
end
w1=w1+alpha.*D1;
w2=w2+alpha.*D2;%梯度下降
end
end
预测
function [ y_predict, accuracy ] = predictNN( x,y,w1,w2,units )
% 神经网络预测
%units记录隐藏层非偏置单元数
m=size(x,1);%记录测试集样本总数
n=size(x,2);%记录输入层非偏置单元数
k=length(unique(y));%记录输出单元数
for i=1:m
zz1(i,:)=w1*[1,x(i,:)]';
for j=1:units
aa1(i,j)=1/(1+exp(-zz1(i,j)));
end
zz2(i,:)=w2*[1,aa1(i,:)]';
for j=1:k
aa2(i,j)=1/(1+exp(-zz2(i,j)));
end
end
count=0;
for i=1:m
[probability(i), y_predict(i)]=max(aa2(i,:));
if y_predict(i)==y(i)
count=count+1;
end
end
y_predict=y_predict';
accuracy=count/m;
end
main
%导入数据
load fisheriris
x=meas;
y(1:50,1)=1;
y(51:100,1)=2;
y(101:150,1)=3;
%设置参数
units=2;%隐含层单元数
lamda=0.01;%正则化参数
alpha=0.01;%步长
paixu=randperm(length(x));
a=0.2;%设置训练集规模
for i=1:floor(a*length(x))
x_train(i,:)=x(paixu(i),:);
y_train(i,1)=y(paixu(i));
end
for i=floor(a*length(x))+1:length(x)
x_test(i-floor(a*length(x)),:)=x(paixu(i),:);
y_test(i-floor(a*length(x)),1)=y(paixu(i));
end
[ w1,w2 ] = NN2( x_train, y_train, lamda,units, alpha );
[ y_predict, accuracy ] = predictNN( x_test,y_test,w1,w2,units );
预测准确率: