根据我的理解,简单介绍一个DeepLearn Toolbox工具箱的NN里面各个函数都有什么作用,其中可能有个别表述或者理解的错误。哈哈哈哈哈,先随便写着玩吧 ( ⊙ o ⊙ )!
参考博客:代码详解
简单介绍
前向传播和反向传播
这个工具箱下载链接:点击下载
首先你要知道如何训练一个NN。打开tests文件夹下的test_example_NN.m文件,第13行的注释vanilla neural net表示原始神经网络。代码15到20行这几步就训练了一个NN。
下面代码是一般的网络模型,这里咱们称这个是主程序
load mnist_uint8;
train_x = double(train_x) / 255;
test_x = double(test_x) / 255;
train_y = double(train_y);
test_y = double(test_y);
% normalize
[train_x, mu, sigma] = zscore(train_x);
test_x = normalize(test_x, mu, sigma);
%% ex1 vanilla neural net
rand('state',0)
nn = nnsetup([784 100 10]);
opts.numepochs = 1; % Number of full sweeps through data
opts.batchsize = 100; % Take a mean gradient step over this many samples
[nn, L] = nntrain(nn, train_x, train_y, opts);
[er, bad] = nntest(nn, test_x, test_y);
assert(er < 0.08, 'Too big error');
其中用到了3个 函数nnsetup、nntrain、nntest,下面会介绍。用到两个参数opts.numepochs、opts.batchsize。opts.numepochs表示训练(循环)的次数,等于1表示训练一次。opts.batchsize表示用到的数据(样本)多少,等于100表示用到100组数据,或者称为100张图片。
nnsetup:从architecture中获得网络的整体结构,还有各个参数的初始化数值等等。
比如architecture=[784 100 10],表示输入层是784维输入,一张手写体的图片是28*28的,所以是784。100个隐含层,这可以任意修改,10个输出层,因为手写体有0-9这10个解过,所以是10。
nn.n表示这个网络多少层
之后是一大堆参数
然后那个for循环是对每一层的网络结构初始化,有三个参数w、vw、p,其中w是主要的参数
vw是更新参数时的临时参数,p是sparsity(稀疏编码里面的名词,可以自己查查)
nnsetup就这么多了
nntrain:训练神经网络。主函数第4行要调用
返回更新的神经网络nn。nn.a nn.e nn.W nn.b表示更新之后的激活、误差、权重、偏差,L是每个训练的平方误差。
其中m代表训练样本的数量,opts的后缀是我们设置的各种参数
assert(rem(numbatches, 1) == 0, 'numbatches must be a integer');
rem是取余数,assert是断言,我感觉类似判断一样,那一句就是要求numbatches是整数
zeros(m,n)表示生成一个m*n的零矩阵
for循环代表训练numepochs次
tic是一个秒表计时器,从tic计时到toc结束
randperm(m)是生成一个乱序的1到m的数组,表示要对batchs乱序进行训练
嵌套的for循环代表表示训练的样本个数
if语句是加入noise,就是把一些数据调整为0,inputZeroMaskedFraction表示了调整的比例
下面有又有3个函数,nnff表示前向传播,nnbp是后向传播,nnapplygrads表示梯度下降
nn = nnff(nn, batch_x, batch_y);
nn = nnbp(nn);
nn = nnapplygrads(nn);
nnff表示网络正向运行一次,会计算出dropou、 sparsity 、误差(error)、loss
dropout会防止过拟合,sparsity表示稀疏
后向传播算法的核心是代价函数CC对网络中参数(各层的权重ww和偏置bb)的偏导。BP算法的思路是:如果当前代价函数值距离预期值较远,那么我们通过调整ww和bb的值使新的代价函数值更接近预期值(和预期值相差越大,则ww和bb调整的幅度就越大)。一直重复该过程,直到最终的代价函数值在误差范围内,则算法停止
梯度下降:nn.weightPenaltyL2 是weight decay的部分,也是nnsetup时可以设置的一个参数
有的话就加入weight Penalty,防止过拟合,然后再根据momentum的大小调整一下,最后改变nn.W{i}即可
nntest是最后一个函数,调用nnpredict,和test的集合比较。函数需要的是测试数据x和标签y,如果有y的话可以计算准确率,没有y的话你可以直接调用labels=nnpredict(nn,x)可以得到预测的标签
nnpredict是nnff一次,得到返回的标签labels(列数),就是返回每一行的最大值及其所在的列数
程序操作如下
你直接运行主程序
如果出现如下错误
>> untitled
错误使用 load
无法读取文件 'mnist_uint8'。没有此类文件或目录。
出错 untitled (line 1)
load mnist_uint8;
表示你没有把数据文件添加到路径,mnist_uint8在data文件夹下面,用如下命令添加
>> addpath data
再运行untitled,如果又出现了如下错误:
>> untitled
错误使用 normalize>parseInputs (line 218)
维度必须为正整数。
出错 normalize (line 83)
[dim,method,methodType,dataVars,AisTablular] = parseInputs(A,varargin{:});
出错 untitled (line 9)
test_x = normalize(test_x, mu, sigma);
你需要把util文件夹添加到路径,
>> addpath util
再运行untitled,如果又出现错误如下
未定义函数或变量 'nntrain'。
出错 untitled (line 16)
[nn, L] = nntrain(nn, train_x, train_y, opts);
这。。。。。还是因为缺少路径,你再添加NN文件夹路径,
>> addpath NN
这应该就会成功的,咱们能做的都做的,尽力了。。。
会出现如下结果:
>> untitled
epoch 1/1. Took 1.5443 seconds. Mini-batch mean squared error on training
set is 0.16243; Full-batch train err = 0.075586
结果的意思就是:花了1.5443秒。训练集上的小批量均方误差为0.16243;全批量训练误差为0.075586
因为咱们就训练了一个,所以就只有一个结果。
更多的训练在tests\test_example_NN中,这个会输出好几个结果,更多的自己去运行试试吧