==========================================================================================

最近一直在看Deep Learning,各类博客、论文看得不少

但是说实话,这样做有些疏于实现,一来呢自己的电脑也不是很好,二来呢我目前也没能力自己去写一个toolbox

只是跟着Andrew Ng的UFLDL tutorial 写了些已有框架的代码(这部分的代码见github)

后来发现了一个matlab的Deep Learning的toolbox,发现其代码很简单,感觉比较适合用来学习算法

再一个就是matlab的实现可以省略掉很多数据结构的代码,使算法思路非常清晰

所以我想在解读这个toolbox的代码的同时来巩固自己学到的,同时也为下一步的实践打好基础

(本文只是从代码的角度解读算法,具体的算法理论步骤还是需要去看paper的

我会在文中给出一些相关的paper的名字,本文旨在梳理一下算法过程,不会深究算法原理和公式)

==========================================================================================

使用的代码:DeepLearnToolbox  ,下载地址:点击打开,感谢该toolbox的作者

==========================================================================================

第一章从分析NN(neural network)开始,因为这是整个deep learning的大框架,参见UFLDL

==========================================================================================

首先看一下\tests\test_example_NN.m ,跳过对数据进行normalize的部分,最关键的就是:

(为了注释显示有颜色,我把matlab代码中的%都改成了//)

[cpp] view plaincopy
  1. nn = nnsetup([784 100 10]);
  2. opts.numepochs =  1;   //  Number of full sweeps through data
  3. opts.batchsize = 100;  //  Take a mean gradient step over this many samples
  4. [nn, L] = nntrain(nn, train_x, train_y, opts);
  5. [er, bad] = nntest(nn, test_x, test_y);

很简单的几步就训练了一个NN,我们发现其中最重要的几个函数就是nnsetup,nntrain和nntest了

那么我们分别来分析着几个函数,\NN\nnsetup.m

nnsetup

[cpp] view plaincopy
  1. function nn = nnsetup(architecture)
  2. //首先从传入的architecture中获得这个网络的整体结构,nn.n表示这个网络有多少层,可以参照上面的样例调用nnsetup([784 100 10])加以理解
  3. nn.size   = architecture;
  4. nn.n      = numel(nn.size);
  5. //接下来是一大堆的参数,这个我们到具体用的时候再加以说明
  6. nn.activation_function              = 'tanh_opt';   //  Activation functions of hidden layers: 'sigm' (sigmoid) or 'tanh_opt' (optimal tanh).
  7. nn.learningRate                     = 2;            //  learning rate Note: typically needs to be lower when using 'sigm' activation function and non-normalized inputs.
  8. nn.momentum                         = 0.5;          //  Momentum
  9. nn.scaling_learningRate             = 1;            //  Scaling factor for the learning rate (each epoch)
  10. nn.weightPenaltyL2                  = 0;            //  L2 regularization
  11. nn.nonSparsityPenalty               = 0;            //  Non sparsity penalty
  12. nn.sparsityTarget                   = 0.05;         //  Sparsity target
  13. nn.inputZeroMaskedFraction          = 0;            //  Used for Denoising AutoEncoders
  14. nn.dropoutFraction                  = 0;            //  Dropout level (http://www.cs.toronto.edu/~hinton/absps/dropout.pdf)
  15. nn.testing                          = 0;            //  Internal variable. nntest sets this to one.
  16. nn.output                           = 'sigm';       //  output unit 'sigm' (=logistic), 'softmax' and 'linear'
  17. //对每一层的网络结构进行初始化,一共三个参数W,vW,p,其中W是主要的参数
  18. //vW是更新参数时的临时参数,p是所谓的sparsity,(等看到代码了再细讲)
  19. for i = 2 : nn.n
  20. // weights and weight momentum
  21. nn.W{i - 1} = (rand(nn.size(i), nn.size(i - 1)+1) - 0.5) * 2 * 4 * sqrt(6 / (nn.size(i) + nn.size(i - 1)));
  22. nn.vW{i - 1} = zeros(size(nn.W{i - 1}));
  23. // average activations (for use with sparsity)
  24. nn.p{i}     = zeros(1, nn.size(i));
  25. end
  26. end

nntrain

setup大概就这样一个过程,下面就到了train了,打开\NN\nntrain.m

我们跳过那些检验传入数据是否正确的代码,直接到关键的部分

denoising 的部分请参考论文:Extracting and Composing Robust Features with Denoising Autoencoders

[cpp] view plaincopy
  1. m = size(train_x, 1);
  2. //m是训练样本的数量
  3. //注意在调用的时候我们设置了opt,batchsize是做batch gradient时候的大小
  4. batchsize = opts.batchsize; numepochs = opts.numepochs;
  5. numbatches = m / batchsize;  //计算batch的数量
  6. assert(rem(numbatches, 1) == 0, 'numbatches must be a integer');
  7. L = zeros(numepochs*numbatches,1);
  8. n = 1;
  9. //numepochs是循环的次数
  10. for i = 1 : numepochs
  11. tic;
  12. kk = randperm(m);
  13. //把batches打乱顺序进行训练,randperm(m)生成一个乱序的1到m的数组
  14. for l = 1 : numbatches
  15. batch_x = train_x(kk((l - 1) * batchsize + 1 : l * batchsize), :);
  16. //Add noise to input (for use in denoising autoencoder)
  17. //加入noise,这是denoising autoencoder需要使用到的部分
  18. //这部分请参见《Extracting and Composing Robust Features with Denoising Autoencoders》这篇论文
  19. //具体加入的方法就是把训练样例中的一些数据调整变为0,inputZeroMaskedFraction表示了调整的比例
  20. if(nn.inputZeroMaskedFraction ~= 0)
  21. batch_x = batch_x.*(rand(size(batch_x))>nn.inputZeroMaskedFraction);
  22. end
  23. batch_y = train_y(kk((l - 1) * batchsize + 1 : l * batchsize), :);
  24. //这三个函数
  25. //nnff是进行前向传播,nnbp是后向传播,nnapplygrads是进行梯度下降
  26. //我们在下面分析这些函数的代码
  27. nn = nnff(nn, batch_x, batch_y);
  28. nn = nnbp(nn);
  29. nn = nnapplygrads(nn);
  30. L(n) = nn.L;
  31. n = n + 1;
  32. end
  33. t = toc;
  34. if ishandle(fhandle)
  35. if opts.validation == 1
  36. loss = nneval(nn, loss, train_x, train_y, val_x, val_y);
  37. else
  38. loss = nneval(nn, loss, train_x, train_y);
  39. end
  40. nnupdatefigures(nn, fhandle, loss, opts, i);
  41. end
  42. disp(['epoch ' num2str(i) '/' num2str(opts.numepochs) '. Took ' num2str(t) ' seconds' '. Mean squared error on training set is ' num2str(mean(L((n-numbatches):(n-1))))]);
  43. nn.learningRate = nn.learningRate * nn.scaling_learningRate;
  44. end

下面分析三个函数nnff,nnbp和nnapplygrads

nnff

nnff就是进行feedforward pass,其实非常简单,就是整个网络正向跑一次就可以了

当然其中有dropout和sparsity的计算

具体的参见论文“Improving Neural Networks with Dropout“和Autoencoders and Sparsity

[cpp] view plaincopy
  1. function nn = nnff(nn, x, y)
  2. //NNFF performs a feedforward pass
  3. // nn = nnff(nn, x, y) returns an neural network structure with updated
  4. // layer activations, error and loss (nn.a, nn.e and nn.L)
  5. n = nn.n;
  6. m = size(x, 1);
  7. x = [ones(m,1) x];
  8. nn.a{1} = x;
  9. //feedforward pass
  10. for i = 2 : n-1
  11. //根据选择的激活函数不同进行正向传播计算
  12. //你可以回过头去看nnsetup里面的第一个参数activation_function
  13. //sigm就是sigmoid函数,tanh_opt就是tanh的函数,这个toolbox好像有一点改变
  14. //tanh_opt是1.7159*tanh(2/3.*A)
  15. switch nn.activation_function
  16. case 'sigm'
  17. // Calculate the unit's outputs (including the bias term)
  18. nn.a{i} = sigm(nn.a{i - 1} * nn.W{i - 1}');
  19. case 'tanh_opt'
  20. nn.a{i} = tanh_opt(nn.a{i - 1} * nn.W{i - 1}');
  21. end
  22. //dropout的计算部分部分 dropoutFraction 是nnsetup中可以设置的一个参数
  23. if(nn.dropoutFraction > 0)
  24. if(nn.testing)
  25. nn.a{i} = nn.a{i}.*(1 - nn.dropoutFraction);
  26. else
  27. nn.dropOutMask{i} = (rand(size(nn.a{i}))>nn.dropoutFraction);
  28. nn.a{i} = nn.a{i}.*nn.dropOutMask{i};
  29. end
  30. end
  31. //计算sparsity,nonSparsityPenalty 是对没达到sparsitytarget的参数的惩罚系数
  32. //calculate running exponential activations for use with sparsity
  33. if(nn.nonSparsityPenalty>0)
  34. nn.p{i} = 0.99 * nn.p{i} + 0.01 * mean(nn.a{i}, 1);
  35. end
  36. //Add the bias term
  37. nn.a{i} = [ones(m,1) nn.a{i}];
  38. end
  39. switch nn.output
  40. case 'sigm'
  41. nn.a{n} = sigm(nn.a{n - 1} * nn.W{n - 1}');
  42. case 'linear'
  43. nn.a{n} = nn.a{n - 1} * nn.W{n - 1}';
  44. case 'softmax'
  45. nn.a{n} = nn.a{n - 1} * nn.W{n - 1}';
  46. nn.a{n} = exp(bsxfun(@minus, nn.a{n}, max(nn.a{n},[],2)));
  47. nn.a{n} = bsxfun(@rdivide, nn.a{n}, sum(nn.a{n}, 2));
  48. end
  49. //error and loss
  50. //计算error
  51. nn.e = y - nn.a{n};
  52. switch nn.output
  53. case {'sigm', 'linear'}
  54. nn.L = 1/2 * sum(sum(nn.e .^ 2)) / m;
  55. case 'softmax'
  56. nn.L = -sum(sum(y .* log(nn.a{n}))) / m;
  57. end
  58. end

nnbp

代码:\NN\nnbp.m

nnbp呢是进行back propagation的过程,过程还是比较中规中矩,和ufldl中的Neural Network讲的基本一致

值得注意的还是dropout和sparsity的部分

[cpp] view plaincopy
  1. if(nn.nonSparsityPenalty>0)
  2. pi = repmat(nn.p{i}, size(nn.a{i}, 1), 1);
  3. sparsityError = [zeros(size(nn.a{i},1),1) nn.nonSparsityPenalty * (-nn.sparsityTarget ./ pi + (1 - nn.sparsityTarget) ./ (1 - pi))];
  4. end
  5. // Backpropagate first derivatives
  6. if i+1==n % in this case in d{n} there is not the bias term to be removed
  7. d{i} = (d{i + 1} * nn.W{i} + sparsityError) .* d_act; // Bishop (5.56)
  8. else // in this case in d{i} the bias term has to be removed
  9. d{i} = (d{i + 1}(:,2:end) * nn.W{i} + sparsityError) .* d_act;
  10. end
  11. if(nn.dropoutFraction>0)
  12. d{i} = d{i} .* [ones(size(d{i},1),1) nn.dropOutMask{i}];
  13. end

这只是实现的内容,代码中的d{i}就是这一层的delta值,在ufldl中有讲的

dW{i}基本就是计算的gradient了,只是后面还要加入一些东西,进行一些修改

具体原理参见论文“Improving Neural Networks with Dropout“ 以及 Autoencoders and Sparsity的内容

nnapplygrads

代码文件:\NN\nnapplygrads.m

[cpp] view plaincopy
  1. for i = 1 : (nn.n - 1)
  2. if(nn.weightPenaltyL2>0)
  3. dW = nn.dW{i} + nn.weightPenaltyL2 * nn.W{i};
  4. else
  5. dW = nn.dW{i};
  6. end
  7. dW = nn.learningRate * dW;
  8. if(nn.momentum>0)
  9. nn.vW{i} = nn.momentum*nn.vW{i} + dW;
  10. dW = nn.vW{i};
  11. end
  12. nn.W{i} = nn.W{i} - dW;
  13. end

这个内容就简单了,nn.weightPenaltyL2 是weight decay的部分,也是nnsetup时可以设置的一个参数

有的话就加入weight Penalty,防止过拟合,然后再根据momentum的大小调整一下,最后改变nn.W{i}即可

nntest

nntest再简单不过了,就是调用一下nnpredict,在和test的集合进行比较

[cpp] view plaincopy
  1. function [er, bad] = nntest(nn, x, y)
  2. labels = nnpredict(nn, x);
  3. [~, expected] = max(y,[],2);
  4. bad = find(labels ~= expected);
  5. er = numel(bad) / size(x, 1);
  6. end

nnpredict

代码文件:\NN\nnpredict.m

[cpp] view plaincopy
  1. function labels = nnpredict(nn, x)
  2. nn.testing = 1;
  3. nn = nnff(nn, x, zeros(size(x,1), nn.size(end)));
  4. nn.testing = 0;
  5. [~, i] = max(nn.a{end},[],2);
  6. labels = i;
  7. end

继续非常简单,predict不过是nnff一次,得到最后的output~~

max(nn.a{end},[],2); 是返回每一行的最大值以及所在的列数,所以labels返回的就是标号啦

(这个test好像是专门用来test 分类问题的,我们知道nnff得到最后的值即可)

总结

总的来说,神经网络的代码比较常规易理解,基本上和UFLDL中的内容相差不大
只是加入了dropout的部分和denoising的部分
本文的目的也不奢望讲清楚这些东西,只是给出一个路线,可以跟着代码去学习,加深对算法的理解和应用能力

【面向代码】学习 Deep Learning(一)Neural Network相关推荐

  1. 【面向代码】学习 Deep Learning Convolution Neural Network(CNN)

    转载自: [面向代码]学习 Deep Learning(三)Convolution Neural Network(CNN) - DarkScope从这里开始 - 博客频道 - CSDN.NET htt ...

  2. 机器学习(Machine Learning)深度学习(Deep Learning)资料(Chapter 2)

    机器学习(Machine Learning)&深度学习(Deep Learning)资料(Chapter 2) - tony的专栏 - 博客频道 - CSDN.NET 注:机器学习资料篇目一共 ...

  3. 【深度学习Deep Learning】资料大全

    感谢关注天善智能,走好数据之路↑↑↑ 欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答.求职一站式搞定! 对商业智能BI.大数据分析挖掘.机器学习, ...

  4. 深度学习Deep Learning 资料大全

    转自:http://www.cnblogs.com/charlotte77/ [深度学习Deep Learning]资料大全 最近在学深度学习相关的东西,在网上搜集到了一些不错的资料,现在汇总一下: ...

  5. [深度学习]DEEP LEARNING(深度学习)学习笔记整理

    转载于博客http://blog.csdn.net/zouxy09 一.概述 Artificial Intelligence,也就是人工智能,就像长生不老和星际漫游一样,是人类最美好的梦想之中的一个. ...

  6. 转【面向代码】学习 Deep Learning(二)Deep Belief Nets(DBNs)

    [面向代码]学习 Deep Learning(二)Deep Belief Nets(DBNs) http://blog.csdn.net/dark_scope/article/details/9447 ...

  7. 台大李宏毅Machine Learning 2017Fall学习笔记 (11)Convolutional Neural Network

    台大李宏毅Machine Learning 2017Fall学习笔记 (11)Convolutional Neural Network 本博客主要整理自: http://blog.csdn.net/x ...

  8. 机器学习(Machine Learning)、深度学习(Deep Learning)、NLP面试中常考到的知识点和代码实现

    网址:https://github.com/NLP-LOVE/ML-NLP 此项目是机器学习(Machine Learning).深度学习(Deep Learning).NLP面试中常考到的知识点和代 ...

  9. 深度学习Deep learning:四十一(Dropout简单理解)

    前言 训练神经网络模型时,如果训练样本较少,为了防止模型过拟合,Dropout可以作为一种trikc供选择.Dropout是hintion最近2年提出的,源于其文章Improving neural n ...

  10. 【github】机器学习(Machine Learning)深度学习(Deep Learning)资料

    转自:https://github.com/ty4z2008/Qix/blob/master/dl.md# <Brief History of Machine Learning> 介绍:这 ...

最新文章

  1. 什么是CPython
  2. UVA 10803 Thunder Mountain
  3. 每日程序C语言3-三个数大小排序
  4. java里的字符流_javaIO流中字符流的应用
  5. cmake编译mysql常用参数
  6. jit 方法内联_JIT编译器,内联和转义分析
  7. Tomcat无需输入项目名,直接用域名访问项目
  8. 金蝶kis专业版公网访问_金蝶KIS云专业版—【账务处理】进阶操作101问
  9. 【Java】浅析equals()和hashCode()
  10. 速进!2000核实计算资源免费领取,名额有限,即开即送!
  11. matlab createtask,Matlab批量与createjob
  12. Variant 数组
  13. (10)Python----numpy.hstack
  14. 【MIKE21】MIKE21笔记-HD
  15. 【LKJ】LKJ2000型记录装置显示界面说明
  16. iphone上下左右手势判断代码
  17. chunk的数据格式
  18. 用 JavaScript 编写日历
  19. WebSSH在线编程 所需工具介绍
  20. 软件测试笔记——3.多种多样的测试类型

热门文章

  1. POJ2063 Investment(完全背包)
  2. Head First Design Pattern: 策略模式
  3. 巧妙排查 揪出堵塞网络通信的祸首
  4. 初步解决网同客户端升级后局域网不能上网的问题
  5. android rfid 数据解析_基于RFID技术的标签数据完整性与安全性解析
  6. js实现删除文章弹窗提示是否确认
  7. mysql经典46_mysql练习46题 PDF 下载
  8. python二维图自动保存_Autodesk Inventor工程图自动保存PDF文件iLogic代码
  9. 孤岛惊魂4服务器稳定吗,《孤岛惊魂5》究竟好不好玩 让我来告诉你(缺点)
  10. 10投屏后没有声音_10年后,学区房有没有可能成为“负资产”?这位专家说了实话...