https://github.com/100/Cranium 一个FNN神经网络库
通过vs2013,无法正确编译,由于vs2013对C99的支持不是很好。在window环境下,使用这个库,可用eclipse IDE测试这个库的例子。注意问题以下
- eclipse导入项目,import->General->File System
- eclipse设置支持c99,项目Properities->C/C++ Build->Settings->GCC C Compiler->Miscellaneous->Other flags加入-std=c99
- 这样设置出现问题,编译问题undefined reference to `WinMain@16',解决方法Properities->C/C++ Build->Settings->MinGW C Linker->Libraries->Libraries(-l)添加mingw32
http://www.mymathlib.com/ 数值分析
Spyder代码无法自动补齐,可能原因:
- http://blog.youkuaiyun.com/baixue6269/article/details/60132470如这个链接,设置不对
反向传播详解:
首先参考这个链接http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html
其算法步骤如下:
- 前向传播
- 误差反向传播: 计算反向层与层误差->是个层层传递过程
- 权值与偏置更新
这里重点阐明2与3点,先附上matlab代码
startDir=fileparts(which('testNeural'));
addpath(startDir);
%str1=strcat(startDir,'\netW\');
inputs=[0 0 1 1;0 1 0 1];
[m,n]=size(inputs);
learnRate=0.5;
targets=[0 1 1 0];
hiddenLayersize=1;
w1=rands(3,2);
b1=rands(3,1);
y1=zeros(3,1);
delta1=zeros(3,1);
[w1_m,w1_n]=size(w1);
w2=rands(1,3);
b2=rands(1,1);
y2=zeros(1,1);
delta2=zeros(1,1);
iter=100;
precison=1e-8;
err=zeros(3,1);%3为样本个数
y=zeros(3,1);
epoch=5;
for ii=1:epoch
for j=1:iter
for i=1: n-1
y1=1./(1+exp(-(w1*inputs(:,i)+b1)));%前向传播
y2=w2*y1+b2;%前向传播
delta2=targets(i)-y2;%反向传播之计算误差
delta1=w2'*delta2;%反向传播之计算误差
w1=learnRate*y1.*(1-y1).*delta1*inputs(:,i)'+w1;%权值更新,y1.*(1-y1)代表导数,sigmod求导为y*(1-y)
b1=learnRate*1.*delta1+b1;
w2=learnRate*1.*delta2*y1'+w2;%线性x求导为1
b2=learnRate*1.*delta2+b2;
err(i)=0.5*sum(delta2.^2);%单个样本误差,二范数
y(i)=y2;
end
Error=sum(err);%多个样本的总误差,也是二范数
if(Error<precison)
break;
end
end
if(Error<precison)
break;
end
end
我们看看这个流程:
首先定义神经网络有N+1层,N表示有多少个权值矩阵,比如3层神经网络,有2个权值矩阵;
从编程角度看,从第2层到N+1层,每一层保存了哪些量?
1.我们从输出层看起,输出y向量,对应了一个delta向量,这2个向量维数相同,接着是第N层,delta_n向量同第N层向量维数同。。。由此递推,误差向量与输出向量维数同
2.看看每个权值矩阵,涉及w为m*n维数,m代表的是输出维数,n代表的是输入维数,我们都知道m*1的向量与1*n的向量相乘,得到m*n的矩阵;同时,误差向量delta是m维的,所以delta*输入向量同权值维数同,这样就可以更新w了,当然再乘以学习率,学习率是梯度下降步长,它越大,学习快,但是要注意有的问题其学习率有个收敛范围。