卷积神经网络全面解析之代码注释

卷积神经网络全面解析之代码注释
卷积神经网络全面解析之代码注释

卷积神经网络全面解析之代码注释

自己平时看了一些论文,但老感觉看完过后就会慢慢的淡忘,某一天重新拾起来的时候又好像没有看过一样。所以想习惯地把一些感觉有用的论文中的知识点总结整理一下,一方面在整理过程中,自己的理解也会更深,另一方面也方便未来自己的勘察。更好的还可以放到博客上面与大家交流。因为基础有限,所以对论文的一些理解可能不太正确,还望大家不吝指正交流.

下面是自己对代码的注释:

cnnexamples.m

[plain]view plain copy

1.clear all; close all; clc;

2.addpath('../data');

3.addpath('../util');

4.load mnist_uint8;

5.

6.train_x = double(reshape(train_x',28,28,60000))/255;

7.test_x = double(reshape(test_x',28,28,10000))/255;

8.train_y = double(train_y');

9.test_y = double(test_y');

10.

11.%% ex1

12.%will run 1 epoch in about 200 second and get around 11% error.

13.%With 100 epochs you'll get around 1.2% error

14.

15.c https://www.360docs.net/doc/7510357765.html,yers = {

16. struct('type', 'i') %input layer

17. struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convol

ution layer

18. struct('type', 's', 'scale', 2) %sub sampling layer

19. struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convo

lution layer

20. struct('type', 's', 'scale', 2) %subsampling layer

21.};

22.

23.%这里把cnn的设置给cnnsetup,它会据此构建一个完整的CNN网络,并返回

24.c nn = cnnsetup(cnn, train_x, train_y);

25.

26.%学习率

27.o pts.alpha = 1;

28.%每次挑出一个batchsize的batch来训练,也就是每用batchsize个样本就调

整一次权值,而不是

29.%把所有样本都输入了,计算所有样本的误差了才调整一次权值

30.o pts.batchsize = 50;

31.%训练次数,用同样的样本集。我训练的时候:

32.% 1的时候 11.41% error

33.% 5的时候 4.2% error

34.% 10的时候 2.73% error

35.o pts.numepochs = 10;

36.

37.%然后开始把训练样本给它,开始训练这个CNN网络

38.c nn = cnntrain(cnn, train_x, train_y, opts);

39.

40.%然后就用测试样本来测试

41.[er, bad] = cnntest(cnn, test_x, test_y);

42.

43.%plot mean squared error

44.p lot(cnn.rL);

45.%show test error

46.d isp([num2str(er*100) '% error']);

cnnsetup.m

[plain]view plain copy

1.function net = cnnsetup(net, x, y)

2. inputmaps = 1;

3. % B=squeeze(A) 返回和矩阵A相同元素但所有单一维都移除的矩阵B,单一

维是满足size(A,dim)=1的维。

4. % train_x中图像的存放方式是三维的reshape(train_x',28,28,60000),

前面两维表示图像的行与列,

5. % 第三维就表示有多少个图像。这样squeeze(x(:, :, 1))就相当于取第一

个图像样本后,再把第三维

6. % 移除,就变成了28x28的矩阵,也就是得到一幅图像,再size一下就得到

了训练样本图像的行数与列数了

7. mapsize = size(squeeze(x(:, :, 1)));

8.

9. % 下面通过传入net这个结构体来逐层构建CNN网络

10. % n = numel(A)返回数组A中元素个数

11. % https://www.360docs.net/doc/7510357765.html,yers中有五个struct类型的元素,实际上就表示CNN共有五层,

这里范围的是5

12. for l = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers) % layer

13. if strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 's') % 如果这层是子采样层

14. % subsampling层的mapsize,最开始mapsize是每张图的大小

28*28

15. % 这里除以scale=2,就是pooling之后图的大小,pooling域之

间没有重叠,所以pooling后的图像为14*14

16. % 注意这里的右边的mapsize保存的都是上一层每张特征map的大

小,它会随着循环进行不断更新

17. mapsize = floor(mapsize / https://www.360docs.net/doc/7510357765.html,yers{l}.scale);

18. for j = 1 : inputmaps % inputmap就是上一层有多少张特征

19. https://www.360docs.net/doc/7510357765.html,yers{l}.b{j} = 0; % 将偏置初始化为0

20. end

21. end

22. if strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 'c') % 如果这层是卷积层

23. % 旧的mapsize保存的是上一层的特征map的大小,那么如果卷积

核的移动步长是1,那用

24. % kernelsize*kernelsize大小的卷积核卷积上一层的特征map

后,得到的新的map的大小就是下面这样

25. mapsize = mapsize - https://www.360docs.net/doc/7510357765.html,yers{l}.kernelsize + 1;

26. % 该层需要学习的参数个数。每张特征map是一个(后层特征图数

量)*(用来卷积的patch图的大小)

27. % 因为是通过用一个核窗口在上一个特征map层中移动(核窗口每

次移动1个像素),遍历上一个特征map

28. % 层的每个神经元。核窗口由kernelsize*kernelsize个元素组

成,每个元素是一个独立的权值,所以

29. % 就有kernelsize*kernelsize个需要学习的权值,再加一个偏

置值。另外,由于是权值共享,也就是

30. % 说同一个特征map层是用同一个具有相同权值元素的

kernelsize*kernelsize的核窗口去感受输入上一

31. % 个特征map层的每个神经元得到的,所以同一个特征map,它的

权值是一样的,共享的,权值只取决于

32. % 核窗口。然后,不同的特征map提取输入上一个特征map层不同

的特征,所以采用的核窗口不一样,也

33. % 就是权值不一样,所以outputmaps个特征map就有

(kernelsize*kernelsize+1)* outputmaps那么多的权值了

34. % 但这里fan_out只保存卷积核的权值W,偏置b在下面独立保存

35. fan_out = https://www.360docs.net/doc/7510357765.html,yers{l}.outputmaps * https://www.360docs.net/doc/7510357765.html,yers{l}.ke

rnelsize ^ 2;

36. for j = 1 : https://www.360docs.net/doc/7510357765.html,yers{l}.outputmaps % output map

37. % fan_out保存的是对于上一层的一张特征map,我在这一层

需要对这一张特征map提取outputmaps种特征,

38. % 提取每种特征用到的卷积核不同,所以fan_out保存的是这

一层输出新的特征需要学习的参数个数

39. % 而,fan_in保存的是,我在这一层,要连接到上一层中所有

的特征map,然后用fan_out保存的提取特征

40. % 的权值来提取他们的特征。也即是对于每一个当前层特征图,

有多少个参数链到前层

41. fan_in = inputmaps * https://www.360docs.net/doc/7510357765.html,yers{l}.kernelsize ^ 2

;

42. for i = 1 : inputmaps % input map

43. % 随机初始化权值,也就是共有outputmaps个卷积核,

对上层的每个特征map,都需要用这么多个卷积核

44. % 去卷积提取特征。

45. % rand(n)是产生n×n的 0-1之间均匀取值的数值的矩

阵,再减去0.5就相当于产生-0.5到0.5之间的随机数

46. % 再 *2 就放大到 [-1, 1]。然后再乘以后面那一数,

why?

47. % 反正就是将卷积核每个元素初始化为

[-sqrt(6 / (fan_in + fan_out)), sqrt(6 / (fan_in + fan_out))] 48. % 之间的随机数。因为这里是权值共享的,也就是对于一

张特征map,所有感受野位置的卷积核都是一样的

49. % 所以只需要保存的是 inputmaps * outputmaps 个

卷积核。

50. https://www.360docs.net/doc/7510357765.html,yers{l}.k{i}{j} = (rand(https://www.360docs.net/doc/7510357765.html,yers{l}.k

ernelsize) - 0.5) * 2 * sqrt(6 / (fan_in + fan_out));

51. end

52. https://www.360docs.net/doc/7510357765.html,yers{l}.b{j} = 0; % 将偏置初始化为0

53. end

54. % 只有在卷积层的时候才会改变特征map的个数,pooling的时候

不会改变个数。这层输出的特征map个数就是

55. % 输入到下一层的特征map个数

56. inputmaps = https://www.360docs.net/doc/7510357765.html,yers{l}.outputmaps;

57. end

58. end

59.

60. % fvnum 是输出层的前面一层的神经元个数。

61. % 这一层的上一层是经过pooling后的层,包含有inputmaps个特征map。

每个特征map的大小是mapsize。

62. % 所以,该层的神经元个数是 inputmaps * (每个特征map的大小)

63. % prod: Product of elements.

64. % For vectors, prod(X) is the product of the elements of X

65. % 在这里 mapsize = [特征map的行数特征map的列数],所以prod后就

是特征map的行*列

66. fvnum = prod(mapsize) * inputmaps;

67. % onum 是标签的个数,也就是输出层神经元的个数。你要分多少个类,自然

就有多少个输出神经元

68. onum = size(y, 1);

69.

70. % 这里是最后一层神经网络的设定

71. % ffb 是输出层每个神经元对应的基biases

72. net.ffb = zeros(onum, 1);

73. % ffW 输出层前一层与输出层连接的权值,这两层之间是全连接的

74. net.ffW = (rand(onum, fvnum) - 0.5) * 2 * sqrt(6 / (onum + fv

num));

75.e nd

cnntrain.m

[plain]view plain copy

1.function net = cnntrain(net, x, y, opts)

2. m = size(x, 3); % m 保存的是训练样本个数

3. numbatches = m / opts.batchsize;

4. % rem: Remainder after division. rem(x,y) is x - n.*y 相当于求

5. % rem(numbatches, 1) 就相当于取其小数部分,如果为0,就是整数

6. if rem(numbatches, 1) ~= 0

7. error('numbatches not integer');

8. end

9.

10. net.rL = [];

11. for i = 1 : opts.numepochs

12. % disp(X) 打印数组元素。如果X是个字符串,那就打印这个字符串

13. disp(['epoch ' num2str(i) '/' num2str(opts.numepochs)]);

14. % tic 和 toc 是用来计时的,计算这两条语句之间所耗的时间

15. tic;

16. % P = randperm(N) 返回[1, N]之间所有整数的一个随机的序列,例

17. % randperm(6) 可能会返回 [2 4 5 6 1 3]

18. % 这样就相当于把原来的样本排列打乱,再挑出一些样本来训练

19. kk = randperm(m);

20. for l = 1 : numbatches

21. % 取出打乱顺序后的batchsize个样本和对应的标签

22. batch_x = x(:, :, kk((l - 1) * opts.batchsize + 1 : l

* opts.batchsize));

23. batch_y = y(:, kk((l - 1) * opts.batchsize + 1 : l

* opts.batchsize));

24.

25. % 在当前的网络权值和网络输入下计算网络的输出

26. net = cnnff(net, batch_x); % Feedforward

27. % 得到上面的网络输出后,通过对应的样本标签用bp算法来得到误

差对网络权值

28. %(也就是那些卷积核的元素)的导数

29. net = cnnbp(net, batch_y); % Backpropagation

30. % 得到误差对权值的导数后,就通过权值更新方法去更新权值

31. net = cnnapplygrads(net, opts);

32. if isempty(net.rL)

33. net.rL(1) = net.L; % 代价函数值,也就是误差值

34. end

35. net.rL(end + 1) = 0.99 * net.rL(end) + 0.01 * net.L;

% 保存历史的误差值,以便画图分析

36. end

37. toc;

38. end

39.

40.e nd

cnnff.m

[plain]view plain copy

1.function net = cnnff(net, x)

2. n = numel(https://www.360docs.net/doc/7510357765.html,yers); % 层数

3. https://www.360docs.net/doc/7510357765.html,yers{1}.a{1} = x; % 网络的第一层就是输入,但这里的输入包含了

多个训练图像

4. inputmaps = 1; % 输入层只有一个特征map,也就是原始的输入图像

5.

6. for l = 2 : n % for each layer

7. if strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 'c') % 卷积层

8. % !!below can probably be handled by insane matrix o

perations

9. % 对每一个输入map,或者说我们需要用outputmaps个不同的卷积

核去卷积图像

10. for j = 1 : https://www.360docs.net/doc/7510357765.html,yers{l}.outputmaps % for each ou

tput map

11. % create temp output map

12. % 对上一层的每一张特征map,卷积后的特征map的大小就

13. % (输入map宽 - 卷积核的宽 + 1)* (输入map高 - 卷

积核高 + 1)

14. % 对于这里的层,因为每层都包含多张特征map,对应的索引

保存在每层map的第三维

15. % 所以,这里的z保存的就是该层中所有的特征map了

16. z = zeros(size(https://www.360docs.net/doc/7510357765.html,yers{l - 1}.a{1}) - [https://www.360docs.net/doc/7510357765.html,y

ers{l}.kernelsize - 1 https://www.360docs.net/doc/7510357765.html,yers{l}.kernelsize - 1 0]);

17. for i = 1 : inputmaps % for each input map

18. % convolve with corresponding kernel and add

to temp output map

19. % 将上一层的每一个特征map(也就是这层的输入map)

与该层的卷积核进行卷积

20. % 然后将对上一层特征map的所有结果加起来。也就是说,

当前层的一张特征map,是

21. % 用一种卷积核去卷积上一层中所有的特征map,然后所

有特征map对应位置的卷积值的和

22. % 另外,有些论文或者实际应用中,并不是与全部的特征

map链接的,有可能只与其中的某几个连接

23. z = z + convn(https://www.360docs.net/doc/7510357765.html,yers{l - 1}.a{i}, https://www.360docs.net/doc/7510357765.html,y

ers{l}.k{i}{j}, 'valid');

24. end

25. % add bias, pass through nonlinearity

26. % 加上对应位置的基b,然后再用sigmoid函数算出特征map

中每个位置的激活值,作为该层输出特征map

27. https://www.360docs.net/doc/7510357765.html,yers{l}.a{j} = sigm(z + https://www.360docs.net/doc/7510357765.html,yers{l}.b{j})

;

28. end

29. % set number of input maps to this layers number of

outputmaps

30. inputmaps = https://www.360docs.net/doc/7510357765.html,yers{l}.outputmaps;

31. elseif strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 's') % 下采样层

32. % downsample

33. for j = 1 : inputmaps

34. % !! replace with variable

35. % 例如我们要在scale=2的域上面执行mean pooling,那么

可以卷积大小为2*2,每个元素都是1/4的卷积核

36. z = convn(https://www.360docs.net/doc/7510357765.html,yers{l - 1}.a{j}, ones(https://www.360docs.net/doc/7510357765.html,yers

{l}.scale) / (https://www.360docs.net/doc/7510357765.html,yers{l}.scale ^ 2), 'valid');

37. % 因为convn函数的默认卷积步长为1,而pooling操作的域

是没有重叠的,所以对于上面的卷积结果

38. % 最终pooling的结果需要从上面得到的卷积结果中以

scale=2为步长,跳着把mean pooling的值读出来

39. https://www.360docs.net/doc/7510357765.html,yers{l}.a{j} = z(1 : https://www.360docs.net/doc/7510357765.html,yers{l}.scale :

end, 1 : https://www.360docs.net/doc/7510357765.html,yers{l}.scale : end, :);

40. end

41. end

42. end

43.

44. % concatenate all end layer feature maps into vector

45. % 把最后一层得到的特征map拉成一条向量,作为最终提取到的特征向量

46. net.fv = [];

47. for j = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{n}.a) % 最后一层的特征map的个数

48. sa = size(https://www.360docs.net/doc/7510357765.html,yers{n}.a{j}); % 第j个特征map的大小

49. % 将所有的特征map拉成一条列向量。还有一维就是对应的样本索引。

每个样本一列,每列为对应的特征向量

50. net.fv = [net.fv; reshape(https://www.360docs.net/doc/7510357765.html,yers{n}.a{j}, sa(1) * sa(

2), sa(3))];

51. end

52. % feedforward into output perceptrons

53. % 计算网络的最终输出值。sigmoid(W*X + b),注意是同时计算了

batchsize个样本的输出值

54. net.o = sigm(net.ffW * net.fv + repmat(net.ffb, 1, size(net.f

v, 2)));

55.

56.e nd

cnnbp.m

[plain]view plain copy

1.function net = cnnbp(net, y)

2. n = numel(https://www.360docs.net/doc/7510357765.html,yers); % 网络层数

3.

4. % error

5. net.e = net.o - y;

6. % loss function

7. % 代价函数是均方误差

8. net.L = 1/2* sum(net.e(:) .^ 2) / size(net.e, 2);

9.

10. %% backprop deltas

11. % 这里可以参考 UFLDL 的反向传导算法的说明

12. % 输出层的灵敏度或者残差

13. net.od = net.e .* (net.o .* (1 - net.o)); % output delta

14. % 残差反向传播回前一层

15. net.fvd = (net.ffW' * net.od); % feature vector

delta

16. if strcmp(https://www.360docs.net/doc/7510357765.html,yers{n}.type, 'c') % only conv layer

s has sigm function

17. net.fvd = net.fvd .* (net.fv .* (1 - net.fv));

18. end

19.

20. % reshape feature vector deltas into output map style

21. sa = size(https://www.360docs.net/doc/7510357765.html,yers{n}.a{1}); % 最后一层特征map的大小。这里的最

后一层都是指输出层的前一层

22. fvnum = sa(1) * sa(2); % 因为是将最后一层特征map拉成一条向量,所

以对于一个样本来说,特征维数是这样

23. for j = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{n}.a) % 最后一层的特征map的个数

24. % 在fvd里面保存的是所有样本的特征向量(在cnnff.m函数中用特征

map拉成的),所以这里需要重新

25. % 变换回来特征map的形式。d 保存的是 delta,也就是灵敏度或

者残差

26. https://www.360docs.net/doc/7510357765.html,yers{n}.d{j} = reshape(net.fvd(((j - 1) * fvnum + 1

) : j * fvnum, :), sa(1), sa(2), sa(3));

27. end

28.

29. % 对于输出层前面的层(与输出层计算残差的方式不同)

30. for l = (n - 1) : -1 : 1

31. if strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 'c')

32. for j = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{l}.a) % 该层特征map的个

33. % https://www.360docs.net/doc/7510357765.html,yers{l}.d{j} 保存的是第l层的第j

个 map 的灵敏度map。也就是每个神经元节点的delta的值

34. % expand的操作相当于对l+1层的灵敏度map进行上采样。

然后前面的操作相当于对该层的输入a进行sigmoid求导

35. % 这条公式请参

考 Notes on Convolutional Neural Networks

36. % for k = 1:size(https://www.360docs.net/doc/7510357765.html,yers{l + 1}.d{j}, 3)

37. % https://www.360docs.net/doc/7510357765.html,yers{l}.d{j}(:,:,k) = https://www.360docs.net/doc/7510357765.html,yers{l}.a

{j}(:,:,k) .* (1 - https://www.360docs.net/doc/7510357765.html,yers{l}.a{j}(:,:,k)) .* kron(https://www.360docs.net/doc/7510357765.html,yers {l + 1}.d{j}(:,:,k), ones(https://www.360docs.net/doc/7510357765.html,yers{l + 1}.scale)) / https://www.360docs.net/doc/7510357765.html,yers{ l + 1}.scale ^ 2;

38. % end

39. https://www.360docs.net/doc/7510357765.html,yers{l}.d{j} = https://www.360docs.net/doc/7510357765.html,yers{l}.a{j} .* (1 - n

https://www.360docs.net/doc/7510357765.html,yers{l}.a{j}) .* (expand(https://www.360docs.net/doc/7510357765.html,yers{l + 1}.d{j}, [https://www.360docs.net/doc/7510357765.html,yers {l + 1}.scale https://www.360docs.net/doc/7510357765.html,yers{l + 1}.scale 1]) / https://www.360docs.net/doc/7510357765.html,yers{l + 1}.sca le ^ 2);

40. end

41. elseif strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 's')

42. for i = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{l}.a) % 第l层特征map的个

43. z = zeros(size(https://www.360docs.net/doc/7510357765.html,yers{l}.a{1}));

44. for j = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{l + 1}.a) % 第l+1层

特征map的个数

45. z = z + convn(https://www.360docs.net/doc/7510357765.html,yers{l + 1}.d{j}, rot180

(https://www.360docs.net/doc/7510357765.html,yers{l + 1}.k{i}{j}), 'full');

46. end

47. https://www.360docs.net/doc/7510357765.html,yers{l}.d{i} = z;

48. end

49. end

50. end

51.

52. %% calc gradients

53. % 这里与 Notes on Convolutional Neural Networks 中不同,这里

的子采样层没有参数,也没有

54. % 激活函数,所以在子采样层是没有需要求解的参数的

55. for l = 2 : n

56. if strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 'c')

57. for j = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{l}.a)

58. for i = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{l - 1}.a)

59. % dk 保存的是误差对卷积核的导数

60. https://www.360docs.net/doc/7510357765.html,yers{l}.dk{i}{j} = convn(flipall(https://www.360docs.net/doc/7510357765.html,

yers{l - 1}.a{i}), https://www.360docs.net/doc/7510357765.html,yers{l}.d{j}, 'valid') / size(https://www.360docs.net/doc/7510357765.html,yers {l}.d{j}, 3);

61. end

62. % db 保存的是误差对于bias基的导数

63. https://www.360docs.net/doc/7510357765.html,yers{l}.db{j} = sum(https://www.360docs.net/doc/7510357765.html,yers{l}.d{j}(:))

/ size(https://www.360docs.net/doc/7510357765.html,yers{l}.d{j}, 3);

64. end

65. end

66. end

67. % 最后一层perceptron的gradient的计算

68. net.dffW = net.od * (net.fv)' / size(net.od, 2);

69. net.dffb = mean(net.od, 2);

70.

71. function X = rot180(X)

72. X = flipdim(flipdim(X, 1), 2);

73. end

74.e nd

cnnapplygrads.m

[plain]view plain copy

1.function net = cnnapplygrads(net, opts)

2. for l = 2 : numel(https://www.360docs.net/doc/7510357765.html,yers)

3. if strcmp(https://www.360docs.net/doc/7510357765.html,yers{l}.type, 'c')

4. for j = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{l}.a)

5. for ii = 1 : numel(https://www.360docs.net/doc/7510357765.html,yers{l - 1}.a)

6. % 这里没什么好说的,就是普通的权值更新的公式:

W_new = W_old - alpha * de/dW(误差对权值导数)

7. https://www.360docs.net/doc/7510357765.html,yers{l}.k{ii}{j} = https://www.360docs.net/doc/7510357765.html,yers{l}.k{ii}{

j} - opts.alpha * https://www.360docs.net/doc/7510357765.html,yers{l}.dk{ii}{j};

8. end

9. end

10. https://www.360docs.net/doc/7510357765.html,yers{l}.b{j} = https://www.360docs.net/doc/7510357765.html,yers{l}.b{j} - opts.alpha

* https://www.360docs.net/doc/7510357765.html,yers{l}.db{j};

11. end

12. end

13.

14. net.ffW = net.ffW - opts.alpha * net.dffW;

15. net.ffb = net.ffb - opts.alpha * net.dffb;

16.e nd

cnntest.m

[plain]view plain copy

1.function [er, bad] = cnntest(net, x, y)

2. % feedforward

3. net = cnnff(net, x); % 前向传播得到输出

4. % [Y,I] = max(X) returns the indices of the maximum values in

vector I

5. [~, h] = max(net.o); % 找到最大的输出对应的标签

6. [~, a] = max(y); % 找到最大的期望输出对应的索引

7. bad = find(h ~= a); % 找到他们不相同的个数,也就是错误的次数8.

9. er = numel(bad) / size(y, 2); % 计算错误率

10.e nd

卷积神经网络CNN从入门到精通

卷积神经网络CNN从入门到精通 卷积神经网络算法的一个实现 前言 从理解卷积神经到实现它,前后花了一个月时间,现在也还有一些地方没有理解透彻,CNN还是有一定难度的,不是看哪个的博客和一两篇论文就明白了,主要还是靠自己去专研,阅读推荐列表在末尾的参考文献。目前实现的CNN在MINIT数据集上效果还不错,但是还有一些bug,因为最近比较忙,先把之前做的总结一下,以后再继续优化。 卷积神经网络CNN是Deep Learning的一个重要算法,在很多应用上表现出卓越的效果,[1]中对比多重算法在文档字符识别的效果,结论是CNN优于其他所有的算法。CNN在手写体识别取得最好的效果,[2]将CNN应用在基于人脸的性别识别,效果也非常不错。前段时间我用BP神经网络对手机拍照图片的数字进行识别,效果还算不错,接近98%,但在汉字识别上表现不佳,于是想试试卷积神经网络。 1、CNN的整体网络结构 卷积神经网络是在BP神经网络的改进,与BP类似,都采用了前向传播计算输出值,反向传播调整权重和偏置;CNN与标准的BP最大的不同是:CNN中相邻层之间的神经单元并不是全连接,而是部分连接,也就是某个神经单元的感知区域来自于上层的部分神经单元,而不是像BP那样与所有的神经单元相连接。CNN的有三个重要的思想架构: 局部区域感知 权重共享 空间或时间上的采样 局部区域感知能够发现数据的一些局部特征,比如图片上的一个角,一段弧,这些基本特征是构成动物视觉的基础[3];而BP中,所有的像素点是一堆混乱的点,相互之间的关系没有被挖掘。 CNN中每一层的由多个map组成,每个map由多个神经单元组成,同一个map 的所有神经单元共用一个卷积核(即权重),卷积核往往代表一个特征,比如某个卷积和代表一段弧,那么把这个卷积核在整个图片上滚一下,卷积值较大的区域就很有可能是一段弧。注意卷积核其实就是权重,我们并不需要单独去计算一个卷积,而是一个固定大小的权重矩阵去图像上匹配时,这个操作与卷积类似,因此我们称为卷积神经网络,实际上,BP也可以看做一种特殊的卷积神经网络,只是这个卷积核就是某层的所有权重,即感知区域是整个图像。权重共享策略减少了需要训练的参数,使得训练出来的模型的泛华能力更强。 采样的目的主要是混淆特征的具体位置,因为某个特征找出来后,它的具体位置已经不重要了,我们只需要这个特征与其他的相对位置,比如一个“8”,当我们得到了上面一个"o"时,我们不需要知道它在图像的具体位置,只需要知道它下面又是一个“o”我们就可以知道是一个'8'了,因为图片中"8"在图片中偏左或者偏右都不影响我们认识它,这种混淆具体位置的策略能对变形和扭曲的图片进行识别。 CNN的这三个特点是其对输入数据在空间(主要针对图像数据)上和时间(主要针对时间序列数据,参考TDNN)上的扭曲有很强的鲁棒性。CNN一般采用卷积层与

卷积神经网络CNN原理、改进及应用

一、简介 卷积神经网络(Convolutional Neural Networks,简称CNN)是近年发展起来,并引起广泛重视的一种高效的识别方法。 1962年,Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的局部互连网络结构可以有效地降低反馈神经网络的复杂性,继而提出了卷积神经网络[1](Convolutional Neural Networks-简称CNN)7863。现在,CNN已经成为众多科学领域的研究热点之一,特别是在模式分类领域,由于该网络避免了对图像的复杂前期预处理,可以直接输入原始图像,因而得到了更为广泛的应用。 Fukushima在1980年基于神经元间的局部连通性和图像的层次组织转换,为解决模式识别问题,提出的新识别机(Neocognitron)是卷积神经网络的第一个实现网络[2]。他指出,当在不同位置应用具有相同参数的神经元作为前一层的patches时,能够实现平移不变性1296。随着1986年BP算法以及T-C问题[3](即权值共享和池化)9508的提出,LeCun和其合作者遵循这一想法,使用误差梯度(the error gradient)设计和训练卷积神经网络,在一些模式识别任务中获得了最先进的性能[4][5]。在1998年,他们建立了一个多层人工神经网络,被称为LeNet-5[5],用于手写数字分类,这是第一个正式的卷积神经网络模型3579。类似于一般的神经网络,LeNet-5有多层,利用BP算法来训练参数。它可以获得原始图像的有效表示,使得直接从原始像素(几乎不经过预处理)中识别视觉模式成为可能。然而,由于当时大型训练数据和计算能力的缺乏,使得LeNet-5在面对更复杂的问题时,如大规模图像和视频分类,不能表现出良好的性能。 因此,在接下来近十年的时间里,卷积神经网络的相关研究趋于停滞,原因有两个:一是研究人员意识到多层神经网络在进行BP训练时的计算量极其之大,当时的硬件计算能力完全不可能实现;二是包括SVM在内的浅层机器学习算法也渐渐开始暂露头脚。直到2006年,Hinton终于一鸣惊人,在《科学》上发表文章,使得CNN再度觉醒,并取得长足发展。随后,更多的科研工作者对该网络进行了改进。其中,值得注意的是Krizhevsky等人提出的一个经典的CNN架构,相对于图像分类任务之前的方法,在性能方面表现出了显著的改善2674。他们方法的整体架构,即AlexNet[9](也叫ImageNet),与LeNet-5相似,但具有更深的结构。它包括8个学习层(5个卷积与池化层和3个全连接层),前边的几层划分到2个GPU上,(和ImageNet是同一个)并且它在卷积层使用ReLU作为非线性激活函数,在全连接层使用Dropout减少过拟合。该深度网络在ImageNet 大赛上夺冠,进一步掀起了CNN学习热潮。 一般地,CNN包括两种基本的计算,其一为特征提取,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;其二是特征映射,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性。此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数的个数。这两种操作形成了CNN的卷积层。此外,卷积神经网络中的每一个卷积层都紧跟着一个用来求局部平均与二次提取的计算层,即池化层,这种特有的两次特征提取结构减小了特征分辨率。

卷积神经网络总结

卷积神经网络总结-标准化文件发布号:(9556-EUATWK-MWUB-WUNN-INNUL-DDQTY-KII

1 卷积神经网络 卷积神经网络是深度学习的一种,已成为当前图像理解领域的研究热点它的权值共享网络结构使之更类似于生物神经网络,降低了网络模型的复杂度,减少了权值的数量。这个优点在网络的输入是多维图像时表现得更为明显, 图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建过程. 卷积网络是为识别二维形状而特殊设计的一个多层感知器,这种网络结构对平移、比例缩放以及其他形式的变形具有一定不变性. 在典型的CNN 中,开始几层通常是卷积层和下采样层的交替, 在靠近输出层的最后几层网络通常是全连接网络。卷积神经网络的训练过程主要是学习卷积层的卷积核参数和层间连接权重等网络参数, 预测过程主要是基于输入图像和网络参数计算类别标签。卷积神经网络的关键是:网络结构(含卷积层、下采样层、全连接层等) 和反向传播算法等。在本节中, 我们先介绍典型CNN 的网络结构和反向传播算法, 然后概述常用的其他CNN 网络结构和方法。神经网络参数的中文名称主要参考文献[18] 卷积神经网络的结构和反向传播算法主要参考文献[17] 。 1.1 网络结构 1.1.1 卷积层 在卷积层, 上一层的特征图(Feature map) 被一个可学习的卷积核进行卷积, 然后通过一个激活函数(Activation function), 就可以得到输出特征图. 每个输出特征图可以组合卷积多个特征图的值[17] : ()l l j j x f u = 1j l l l l j j ij j i M u x k b -∈= *+∑ 其中, l j u 称为卷积层l 的第j 个通道的净激活(Netactivation), 它通过对前一层 输出特征图1l j x -进行卷积求和与偏置后得到的, l j x 是卷积层l 的第j 个通道的输 出。()f 称为激活函数, 通常可使用sigmoid 和tanh 等函数。j M 表示用于计算l j u 的输入特征图子集, l ij k 是卷积核矩阵, l j b 是对卷积后特征图的偏置。对于一个输 出特征图l j x ,每个输入特征图1l j x -对应的卷积核l ij k 可能不同,“*”是卷积符号。 1.1.2 下采样层 下采样层将每个输入特征图通过下面的公式下采样输出特征图[17]: ()l l j j x f u = 1()l l l l j j j j u down x b β-=+ 其中, l j u 称为下采样层l 的第j 通道的净激活, 它由前一层输出特征图1l j x -进行 下采样加权、偏置后得到, β是下采样层的权重系数, l j b 是下采样层的偏置项. 符

一文读懂卷积神经网络

一文读懂卷积神经网络 自今年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet、 cuda-convnet2。为了增进CNN的理解和使用,特写此博文,以其与人交流,互有增益。正文之前,先说几点自己对于CNN的感触。先明确一点就是,Deep Learning是全部深度学习算法的总称,CNN是深度学习算法在图像处理领域的一个应用。 第一点,在学习Deep learning和CNN之前,总以为它们是很了不得的知识,总以为它们能解决很多问题,学习了之后,才知道它们不过与其他机器学习算法如svm等相似,仍然可以把它当做一个分类器,仍然可以像使用一个黑盒子那样使用它。 第二点,Deep Learning强大的地方就是可以利用网络中间某一层的输出当做是数据的另一种表达,从而可以将其认为是经过网络学习到的特征。基于该特征,可以进行进一步的相似度比较等。 第三点,Deep Learning算法能够有效的关键其实是大规模的数据,这一点原因在于每个DL都有众多的参数,少量数据无法将参数训练充分。 接下来话不多说,直接奔入主题开始CNN之旅。 卷积神经网络简介(Convolutional Neural Networks,简称CNN) 卷积神经网络是近年发展起来,并引起广泛重视的一种高效识别方法。20世纪60年代,Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出了卷积神经网络(Convolutional Neural Networks-简称CNN)。现在,CNN已经成为众多科学领域的研究热点之一,特别是在模式分类领域,由于该网络避免了对图像的复杂前期预处理,可以直接输入原始图像,因而得到了更为广泛的应用。K.Fukushima在1980年提出的新识别机是卷积神经网络的第一个实现网络。随后,更多的科研工作者对该网络进行了改进。其中,具有代表性的研究成果是Alexander和Taylor提出的“改进认知机”,该方法综合了各种改进方法的优点并避免了耗时的误差反向传播。 一般地,CNN的基本结构包括两层,其一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;其二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性。此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数的个数。卷积神经网络中的每一个卷积层都紧跟着一个

(完整word版)深度学习-卷积神经网络算法简介

深度学习 卷积神经网络算法简介 李宗贤 北京信息科技大学智能科学与技术系 卷积神经网络是近年来广泛应用在模式识别、图像处理领域的一种高效识别算法,具有简单结构、训练参数少和适应性强的特点。它的权值共享网络结构使之更类似与生物神经网络,降低了网络的复杂度,减少了权值的数量。以二维图像直接作为网络的输入,避免了传统是被算法中复杂的特征提取和数据重建过程。卷积神经网络是为识别二维形状特殊设计的一个多层感知器,这种网络结构对于平移、比例缩放、倾斜和其他形式的变形有着高度的不变形。 ?卷积神经网络的结构 卷积神经网络是一种多层的感知器,每层由二维平面组成,而每个平面由多个独立的神经元组成,网络中包含一些简单元和复杂元,分别记为C元和S元。C元聚合在一起构成卷积层,S元聚合在一起构成下采样层。输入图像通过和滤波器和可加偏置进行卷积,在C层产生N个特征图(N值可人为设定),然后特征映射图经过求和、加权值和偏置,再通过一个激活函数(通常选用Sigmoid函数)得到S层的特征映射图。根据人为设定C层和S层的数量,以上工作依次循环进行。最终,对最尾部的下采样和输出层进行全连接,得到最后的输出。

卷积的过程:用一个可训练的滤波器fx去卷积一个输入的图像(在C1层是输入图像,之后的卷积层输入则是前一层的卷积特征图),通过一个激活函数(一般使用的是Sigmoid函数),然后加一个偏置bx,得到卷积层Cx。具体运算如下式,式中Mj是输入特征图的值: X j l=f?(∑X i l?1?k ij l+b j l i∈Mj) 子采样的过程包括:每邻域的m个像素(m是人为设定)求和变为一个像素,然后通过标量Wx+1加权,再增加偏置bx+1,然后通过激活函数Sigmoid产生特征映射图。从一个平面到下一个平面的映射可以看作是作卷积运算,S层可看作是模糊滤波器,起到了二次特征提取的作用。隐层与隐层之间的空间分辨率递减,而每层所含的平面数递增,这样可用于检测更多的特征信息。对于子采样层来说,有N 个输入特征图,就有N个输出特征图,只是每个特征图的的尺寸得到了相应的改变,具体运算如下式,式中down()表示下采样函数。 X j l=f?(βj l down (X j l?1) +b j l)X j l) ?卷积神经网络的训练过程 卷积神经网络在本质上是一种输入到输出的映射,它能够学习大量的输入和输出之间的映射关系,而不需要任何输入和输出之间的精确数学表达式。用已知的模式对卷积网络加以训练,网络就具有了输

一文读懂卷积神经网络CNN

一文读懂卷积神经网络CNN ★据说阿尔法狗战胜李世乭靠的是卷积神经网络算法,所以小编找到了一篇介绍该算法的文章,大家可以看一看。★ 自去年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet、cuda-convnet2。为了增进CNN的理解和使用,特写此博文,以其与人交流,互有增益。正文之前,先说几点自己对于CNN的感触。先明确一点就是,Deep Learning是全部深度学习算法的总称,CNN是深度学习算法在图像处理领域的一个应用。第一点,在学习Deep learning 和CNN之前,总以为它们是很了不得的知识,总以为它们能解决很多问题,学习了之后,才知道它们不过与其他机器学习算法如svm等相似,仍然可以把它当做一个分类器,仍然可以像使用一个黑盒子那样使用它。第二点,Deep Learning强大的地方就是可以利用网络中间某一层的输出当做是数据的另一种表达,从而可以将其认为是经过网络学习到的特征。基于该特征,可以进行进一步的相似度比较等。第三点,Deep Learning算法能够有效的关键其实是大规模的数据,这一点原因在于每个DL都有众多的参数,少量数据无法将参数训练充分。接下来话不多说,直接奔入主题开始

CNN之旅。卷积神经网络简介(Convolutional Neural Networks,简称CNN)卷积神经网络是近年发展起来,并引起广泛重视的一种高效识别方法。20世纪60年代,Hubel 和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网 络的复杂性,继而提出了卷积神经网络(Convolutional Neural Networks-简称CNN)。现在,CNN已经成为众多科学领域的研究热点之一,特别是在模式分类领域,由于该网络避免了对图像的复杂前期预处理,可以直接输入原始图像,因而得到了更为广泛的应用。K.Fukushima在1980年提出的新识别机是卷积神经网络的第一个实现网络。随后,更多的科研工作者对该网络进行了改进。其中,具有代表性的研究成果是Alexander和Taylor提出的“改进认知机”,该方法综合了各种改进方法的优点并避免了耗时的误差反向传播。一般地,CNN的基本结构包括两层,其一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;其二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid 函数作为卷积网络的激活函数,使得特征映射具有位移不变性。此外,由于一个映射面上的神经元共享权值,因而减少

卷积神经网络(CNN)学习笔记

CNN卷积神经网络 卷积神经网络是人工神经网络的一种,已成为当前语音分析和图像识别领域的研究热点。它的权值共享网络结构使之更类似于生物神经网络,降低了网络模型的复杂度,减少了权值的数量。该优点在网络的输入是多维图像时表现的更为明显,使图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建过程。卷积网络是为识别二维形状而特殊设计的一个多层感知器,这种网络结构对平移、比例缩放、倾斜或者共他形式的变形具有高度不变性。 CNNs是受早期的延时神经网络(TDNN)的影响。延时神经网络通过在时间维度上共享权值降低学习复杂度,适用于语音和时间序列信号的处理。 CNNs是第一个真正成功训练多层网络结构的学习算法。它利用空间关系减少需要学习的参数数目以提高一般前向BP算法的训练性能。CNNs作为一个深度学习架构提出是为了最小化数据的预处理要求。在CNN中,图像的一小部分(局部感受区域)作为层级结构的最低层的输入,信息再依次传输到不同的层,每层通过一个数字滤波器去获得观测数据的最显著的特征。这个方法能够获取对平移、缩放和旋转不变的观测数据的显著特征,因为图像的局部感受区域允许神经元或者处理单元可以访问到最基础的特征,例如定向边缘或者角点。 2)卷积神经网络的网络结构

图:卷积神经网络的概念示范:输入图像通过和三个可训练的滤波器和可加偏置进行卷积,滤波过程如图一,卷积后在C1层产生三个特征映射图,然后特征映射图中每组的四个像素再进行求和,加权值,加偏置,通过一个Sigmoid函数得到三个S2层的特征映射图。这些映射图再进过滤波得到C3层。这个层级结构再和S2一样产生S4。最终,这些像素值被光栅化,并连接成一个向量输入到传统的神经网络,得到输出。 一般地,C层为特征提取层,每个神经元的输入与前一层的局部感受野相连,并提取该局部的特征,一旦该局部特征被提取后,它与其他特征间的位置关系也随之确定下来;S层是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射为一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性。 此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数

卷积神经网络全面解析之算法实现

卷积神经网络全面解析之算法实现 前言 从理解卷积神经到实现它,前后花了一个月时间,现在也还有一些地方没有理解透彻,CNN还是有一定难度的,不是看哪个的博客和一两篇论文就明白了,主要还是靠自己去专研,阅读推荐列表在末尾的参考文献。目前实现的CNN在MINIT数据集上效果还不错,但是还有一些bug,因为最近比较忙,先把之前做的总结一下,以后再继续优化。 卷积神经网络CNN是Deep Learning的一个重要算法,在很多应用上表现出卓越的效果,[1]中对比多重算法在文档字符识别的效果,结论是CNN优于其他所有的算法。CNN 在手写体识别取得最好的效果,[2]将CNN应用在基于人脸的性别识别,效果也非常不错。前段时间我用BP神经网络对手机拍照图片的数字进行识别,效果还算不错,接近98%,但在汉字识别上表现不佳,于是想试试卷积神经网络。 1、CNN的整体网络结构 卷积神经网络是在BP神经网络的改进,与BP类似,都采用了前向传播计算输出值,反向传播调整权重和偏置;CNN与标准的BP最大的不同是:CNN中相邻层之间的神经单元并不是全连接,而是部分连接,也就是某个神经单元的感知区域来自于上层的部分神经单元,而不是像BP那样与所有的神经单元相连接。CNN的有三个重要的思想架构: ?局部区域感知 ?权重共享 ?空间或时间上的采样 局部区域感知能够发现数据的一些局部特征,比如图片上的一个角,一段弧,这些基本特征是构成动物视觉的基础[3];而BP中,所有的像素点是一堆混乱的点,相互之间的关系没有被挖掘。 CNN中每一层的由多个map组成,每个map由多个神经单元组成,同一个map的所有神经单元共用一个卷积核(即权重),卷积核往往代表一个特征,比如某个卷积和代表一段弧,那么把这个卷积核在整个图片上滚一下,卷积值较大的区域就很有可能是一段弧。注意卷积核其实就是权重,我们并不需要单独去计算一个卷积,而是一个固定大小的权重矩阵去图像上匹配时,这个操作与卷积类似,因此我们称为卷积神经网络,实际上,BP也可以看做一种特殊的卷积神经网络,只是这个卷积核就是某层的所有权重,即感知区域是整个图像。权重共享策略减少了需要训练的参数,使得训练出来的模型的泛华能力更强。 采样的目的主要是混淆特征的具体位置,因为某个特征找出来后,它的具体位置已经不重要了,我们只需要这个特征与其他的相对位置,比如一个“8”,当我们得到了上面一个"o"时,我们不需要知道它在图像的具体位置,只需要知道它下面又是一个“o”我们就可以知道是一个'8'了,因为图片中"8"在图片中偏左或者偏右都不影响我们认识它,这种混淆具体位置的策略能对变形和扭曲的图片进行识别。 CNN的这三个特点是其对输入数据在空间(主要针对图像数据)上和时间(主要针对时间序列数据,参考TDNN)上的扭曲有很强的鲁棒性。CNN一般采用卷积层与采样层交

卷积神经网络n代码解析

deepLearnToolbox-master是一个深度学习matlab包,里面含有很多机器学习算法,如卷积神经网络CNN,深度信念网络DBN,自动编码AutoEncoder(堆栈SAE,卷积CAE)的作者是Rasmus Berg Palm)代码下载:rasmusbergpalm/DeepLearnToolbox 这里我们介绍deepLearnToolbox-master中的CNN部分。 DeepLearnToolbox-master中CNN内的函数: 调用关系为: 该模型使用了mnist的数字作为训练样本,作为cnn的一个使用样例, 每个样本特征为一个28*28=的向量。 网络结构为: 让我们来看看各个函数: 一、Test_example_CNN: (1) 三、 (2) 四、 (2) 五、 (2) 五、 (2) 六、 (3) 一、Test_example_CNN: Test_example_CNN: 1设置CNN的基本参数规格,如卷积、降采样层的数量,卷积核的大小、降采样的降幅 2cnnsetup函数初始化卷积核、偏置等

3cnntrain函数训练cnn,把训练数据分成batch,然后调用 cnnff完成训练的前向过程, cnnbp计算并传递神经网络的error,并计算梯度(权重的修改量) cnnapplygrads把计算出来的梯度加到原始模型上去 4cnntest函数,测试当前模型的准确率 该模型采用的数据为, 含有70000个手写数字样本其中60000作为训练样本,10000作为测试样本。 把数据转成相应的格式,并归一化。 设置网络结构及训练参数 初始化网络,对数据进行批训练,验证模型准确率 绘制均方误差曲线 二、 该函数你用于初始化CNN的参数。 设置各层的mapsize大小, 初始化卷积层的卷积核、bias 尾部单层感知机的参数设置 * bias统一设置为0 权重设置为:-1~1之间的随机数/sqrt(6/(输入神经元数量+输出神经元数量))

深度神经网络全面概述

深度神经网络全面概述从基本概念到实际模型和硬件基础 深度神经网络(DNN)所代表的人工智能技术被认为是这一次技术变革的基石(之一)。近日,由 IEEE Fellow Joel Emer 领导的一个团队发布了一篇题为《深度神经网络的有效处理:教程和调研(Efficient Processing of Deep Neural Networks: A Tutorial and Survey)》的综述论文,从算法、模型、硬件和架构等多个角度对深度神经网络进行了较为全面的梳理和总结。鉴于该论文的篇幅较长,机器之心在此文中提炼了原论文的主干和部分重要内容。 目前,包括计算机视觉、语音识别和机器人在内的诸多人工智能应用已广泛使用了深度神经网络(deep neural networks,DNN)。DNN 在很多人工智能任务之中表现出了当前最佳的准确度,但同时也存在着计算复杂度高的问题。因此,那些能帮助 DNN 高效处理并提升效率和吞吐量,同时又无损于表现准确度或不会增加硬件成本的技术是在人工智能系统之中广泛部署 DNN 的关键。 论文地址: 本文旨在提供一个关于实现 DNN 的有效处理(efficient processing)的目标的最新进展的全面性教程和调查。特别地,本文还给出了一个 DNN 综述——讨论了支持 DNN 的多种平台和架构,并强调了最新的有效处理的技术的关键趋势,这些技术或者只是通过改善硬件设计或者同时改善硬件设计和网络算法以降低 DNN 计算成本。本文也会对帮助研究者和从业者快速上手 DNN 设计的开发资源做一个总结,并凸显重要的基准指标和设计考量以评估数量快速增长的 DNN 硬件设计,还包括学界和产业界共同推荐的算法联合设计。 读者将从本文中了解到以下概念:理解 DNN 的关键设计考量;通过基准和对比指标评估不同的 DNN 硬件实现;理解不同架构和平台之间的权衡;评估不同 DNN 有效处理技术的设计有效性;理解最新的实现趋势和机遇。 一、导语 深度神经网络(DNN)目前是许多人工智能应用的基础 [1]。由于 DNN 在语音识别 [2] 和图像识别 [3] 上的突破性应用,使用DNN 的应用量有了爆炸性的增长。这些 DNN 被部署到了从自动驾驶汽车 [4]、癌症检测 [5] 到复杂游戏 [6] 等各种应用中。在这许多领域中,DNN 能够超越人类的准确率。而 DNN 的出众表现源于它能使用统计学习方法从原始感官数据中提取高层特征,在大量的数据中获得输入空间的有效表征。这与之前使用手动提取特征或专家设计规则的方法不同。 然而 DNN 获得出众准确率的代价是高计算复杂性成本。虽然通用计算引擎(尤其是 GPU),已经成为许多 DNN 处理的砥柱,但提供对 DNN 计算更专门化的加速方法也越来越热门。本文的目标是提供对 DNN、理解 DNN 行为的各种工具、有效加速计算的各项技术的概述。 该论文的结构如下: Section II 给出了 DNN 为什么很重要的背景、历史和应用。 Section III 给出了 DNN 基础组件的概述,还有目前流行使用的 DNN 模型。 Section IV 描述了 DNN 研发所能用到的各种资源。 Section V 描述了处理 DNN 用到的各种硬件平台,以及在不影响准确率的情况下改进吞吐量(thoughtput)和能量的各种优化方法(即产生 bit-wise identical 结果)。 Section VI 讨论了混合信号回路和新的存储技术如何被用于近数据处理(near-data processing),从而解决 DNN 中数据流通时面临的吞吐量和能量消耗难题。 Section VII 描述了各种用来改进 DNN 吞吐量和能耗的联合算法和硬件优化,同时最小化对准确率的影响。 Section VIII 描述了对比 DNN 设计时应该考虑的关键标准。

关于深度学习应用技术的学习体会报告

关于深度学习应用技术的 学习体会报告 学院:计算机学院 专业:计算机科学与技术 班级:XXXX 姓名:XXX 学号:XXXXXXXX 时间:XXXXXXX

目录 概述--------------------------------------- 2 对于深度学习的理解------------------------- 2 对于卷积网络的认识------------------------- 6 对于深度学习的认识和心得------------------- 12 参考论文----------------------------------- 15

关于深度学习应用技术的学习体会报告一.概述 在本学期,有幸选择了xxx老师的深度学习应用技术这门选修课,通过吴老师的介绍,给我打开了人工智能的大门,对于老师课上所讲授的关于人工智能方面的知识有了一定的认识,通过对相关论文和资料的查找学习,对于该领域有了一点自己粗浅的认识,下面就主要是从我对人工智能应用现状和背景,利用卷积进行图像识别、卷积层的相关知识以及自己的心得来汇报一下我的收获 二.对于深度学习的理解 如果把一个具有深度学习的神经网络比作一台机器,那么要让这个机器把输入数据变成理想的结果,就得先让这台机器自我训练,然后把最理想输出结果时的各个权重值以及阈值给保存下来,正常工作时,我们只要把数据输入给这台机器,那么就可以获得最理想的输出结果,而这个机器的自我训练方法就是:事先组织一批输入数据和与其对应的理想输出结果数据,例如输入【1,0】->【1】,【1,1】->【2】,【1,2】->【3】,把这些数据通过机器的学习端口灌入给这台机器,让其自己先进行学习处理,并把学习的最终结果(机器的各种权重值和阈值)保存下来。这台机器的工作原理就是基于神经网络,卷积运算,池化处理。其中神经网络又分为卷积神经网络(CNN),循环神经网络(RNN,又称为前馈型神经网络)等。

卷积神经网络全面解析之代码注释

卷积神经网络全面解析之代码注释 自己平时看了一些论文,但老感觉看完过后就会慢慢的淡忘,某一天重新拾起来的时候又好像没有看过一样。所以想习惯地把一些感觉有用的论文中的知识点总结整理一下,一方面在整理过程中,自己的理解也会更深,另一方面也方便未来自己的勘察。更好的还可以放到博客上面与大家交流。因为基础有限,所以对论文的一些理解可能不太正确,还望大家不吝指正交流. 下面是自己对代码的注释: cnnexamples.m [plain]view plain copy 1.clear all; close all; clc; 2.addpath('../data'); 3.addpath('../util'); 4.load mnist_uint8; 5. 6.train_x = double(reshape(train_x',28,28,60000))/255; 7.test_x = double(reshape(test_x',28,28,10000))/255; 8.train_y = double(train_y'); 9.test_y = double(test_y'); 10. 11.%% ex1 12.%will run 1 epoch in about 200 second and get around 11% error. 13.%With 100 epochs you'll get around 1.2% error 14. 15.c https://www.360docs.net/doc/7510357765.html,yers = { 16. struct('type', 'i') %input layer 17. struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convol ution layer 18. struct('type', 's', 'scale', 2) %sub sampling layer

卷积神经网络总结

1 卷积神经网络 卷积神经网络是深度学习的一种,已成为当前图像理解领域的研究热点它的权值共享网络结构使之更类似于生物神经网络,降低了网络模型的复杂度,减少了权值的数量。这个优点在网络的输入是多维图像时表现得更为明显, 图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建过程. 卷积网络是为识别二维形状而特殊设计的一个多层感知器,这种网络结构对平移、比例缩放以及其他形式的变形具有一定不变性. 在典型的CNN 中,开始几层通常是卷积层和下采样层的交替, 在靠近输出层的最后几层网络通常是全连接网络。卷积神经网络的训练过程主要是学习卷积层的卷积核参数和层间连接权重等网络参数, 预测过程主要是基于输入图像和网络参数计算类别标签。卷积神经网络的关键是:网络结构(含卷积层、下采样层、全连接层等) 和反向传播算法等。在本节中, 我们先介绍典型CNN 的网络结构和反向传播算法, 然后概述常用的其他CNN 网络结构和方法。神经网络参数的中文名称主要参考文献 [18] 卷积神经网络的结构和反向传播算法主要参考文献[17] 。 网络结构 卷积层 在卷积层, 上一层的特征图(Feature map) 被一个可学习的卷积核进行卷积, 然后通过一个激活函数(Activation function), 就可以得到输出特征图. 每个输出特征图可以组 合卷积多个特征图的值[17] : ()l l j j x f u = 1j l l l l j j ij j i M u x k b -∈= *+∑ 其中, l j u 称为卷积层l 的第j 个通道的净激活(Netactivation), 它通过对前一层输出 特征图1l j x -进行卷积求和与偏置后得到的, l j x 是卷积层l 的第j 个通道的输出。()f 称为激活函数, 通常可使用sigmoid 和tanh 等函数。j M 表示用于计算l j u 的输入特征图子集, l ij k 是卷积核矩阵, l j b 是对卷积后特征图的偏置。对于一个输出特征图l j x ,每个输入特征图1l j x -对应的卷积核l ij k 可能不同,“*”是卷积符号。 ; 下采样层 下采样层将每个输入特征图通过下面的公式下采样输出特征图[17]: ()l l j j x f u = 1()l l l l j j j j u down x b β-=+ 其中, l j u 称为下采样层l 的第j 通道的净激活, 它由前一层输出特征图1 l j x -进行下采样

卷积神经网络全面解析之代码详细讲解

卷积神经网络全面解析之代码详解 本文介绍多层感知机算法,特别是详细解读其代码实现,基于python theano,代码来自:Convolutional Neural Networks (LeNet)。 一、CNN卷积神经网络原理简介 要讲明白卷积神经网络,估计得长篇大论,网上有很多博文已经写得很好了,所以本文就不重复了,如果你了解CNN,那可以往下看,本文主要是详细地解读CNN的实现代码。 CNN的最大特点就是稀疏连接(局部感受)和权值共享,如下面两图所示,左为稀疏连接,右为权值共享。稀疏连接和权值共享可以减少所要训练的参数,减少计算复杂度。 至于CNN的结构,以经典的LeNet5来说明:

这个图真是无处不在,一谈CNN,必说LeNet5,这图来自于这篇论文:Gradient-Based Learning Applied to Document Recognition,论文很长,第7页那里开始讲LeNet5这个结构,建议看看那部分。 我这里简单说一下,LeNet5这张图从左到右,先是input,这是输入层,即输入的图片。input-layer到C1这部分就是一个卷积层(convolution 运算),C1到S2是一个子采样层(pooling运算),关于卷积和子采样的具体过程可以参考下图: 然后,S2到C3又是卷积,C3到S4又是子采样,可以发现,卷积和子采样都是成对出现的,卷积后面一般跟着子采样。S4到C5之间是全连接的,这就相当于一个MLP的隐含层了(如果你不清楚MLP,参考《DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解》)。C5到F6同样是全连接,也是相当于一个MLP的隐含层。最后从F6到输出output,其实就是一个分类器,这一层就叫分类层。 ok,CNN的基本结构大概就是这样,由输入、卷积层、子采样层、全连接层、分类层、输出这些基本“构件”组成,一般根据具体的应用或者

卷积神经网络全面解析(2)

卷积神经网络全面解析(2) 一、介绍 这个文档讨论的是CNNs的推导和实现。CNN架构的连接比权值要多很多,这实际上就隐含着实现了某种形式的规则化。这种特别的网络假定了我们希望通过数据驱动的方式学习到一些滤波器,作为提取输入的特征的一种方法。 本文中,我们先对训练全连接网络的经典BP算法做一个描述,然后推导2D CNN网络的卷积层和子采样层的BP权值更新方法。在推导过程中,我们更强调实现的效率,所以会给出一些Matlab代码。最后,我们转向讨论如何自动地学习组合前一层的特征maps,特别地,我们还学习特征maps的稀疏组合。 二、全连接的反向传播算法 典型的CNN中,开始几层都是卷积和下采样的交替,然后在最后一些层(靠近输出层的),都是全连接的一维网络。这时候我们已经将所有两维2D的特征maps转化为全连接的一维网络的输入。这样,当你准备好将最终的2D特征maps输入到1D网络中时,一个非常方便的方法就是把所有输出的特征maps连接成一个长的输入向量。然后我们

回到BP算法的讨论。(更详细的基础推导可以参考UFLDL中“反向传导算法”)。 2.1、Feedforward Pass前向传播 在下面的推导中,我们采用平方误差代价函数。我们讨论的是多类问题,共c类,共N个训练样本。 这里表示第n个样本对应的标签的第k维。表示第n个样本对应的网络输出的第k个输出。对于多类问题,输出一般组织为“one-of-c”的形式,也就是只有该输入对应的类的输出节点输出为正,其他类的位或者节点为0或者负数,这个取决于你输出层的激活函数。sigmoid就是0,tanh就是-1. 因为在全部训练集上的误差只是每个训练样本的误差的总和,所以这里我们先考虑对于一个样本的BP。对于第n个样本的误差,表示为: 传统的全连接神经网络中,我们需要根据BP规则计算代价函数E 关于网络每一个权值的偏导数。我们用l来表示当前层,那么当前层的输出可以表示为:

深度学习系列 自己手写一个卷积神经网络

深度学习系列自己手写一个卷积神经网络 首先我们来看一个最简单的卷积神经网络:1.输入层---->卷积层以上一节的例子为例,输入是一个4*4 的image,经过两个2*2的卷积核进行卷积运算后,变成两个3*3的feature_map以卷积核filter1为例(stride = 1 ):计算第一个卷积层神经元o11的输入:神经元o11的输出:(此处使用Relu 激活函数)其他神经元计算方式相同2.卷积层---->池化层计 算池化层m11 的输入(取窗口为2 * 2),池化层没有激活函 数3.池化层---->全连接层池化层的输出到flatten层把所有元素“拍平”,然后到全连接层。4.全连接层---->输出层全连接层到输出层就是正常的神经元与神经元之间的邻接相连,通过softmax函数计算后输出到output,得到不同类别的概率值,输出概率值最大的即为该图片的类别。卷积神经网络的反向传播传统的神经网络是全连接形式的,如果进行反向传播,只需要由下一层对前一层不断的求偏导,即求链式偏导就可以求出每一层的误差敏感项,然后求出权重和偏置项的梯度,即可更新权重。而卷积神经网络有两个特殊的层:卷积层和池化层。池化层输出时不需要经过激活函数,是一个滑动窗口的最大值,一个常数,那么它的偏导是1。池化层相当于对上层图片做了一个压缩,这个反向求误差敏感项时与传统的反向传播方式不同。从卷积后的feature_map反向传播到

前一层时,由于前向传播时是通过卷积核做卷积运算得到的feature_map,所以反向传播与传统的也不一样,需要更新卷积核的参数。下面我们介绍一下池化层和卷积层是如何做反向传播的。在介绍之前,首先回顾一下传统的反向传播方法:卷积层的反向传播由前向传播可得:首先计算输入层的误差项δ11:观察一下上面几个式子的规律,归纳一下,可以得到如下表达式:此时我们的误差敏感矩阵就求完了,得到误差敏感矩阵后,即可求权重的梯度。推论出权重的梯度:误差项的梯度:可以看出,偏置项的偏导等于这一层所有误差敏感项之和。得到了权重和偏置项的梯度后,就可以根据梯度下降法更新权重和梯度了。池化层的反向传播池化层的反向传播就比较好求了,看着下面的图,左边是上一层的输出,也就是卷积层的输出feature_map,右边是池化层的输入,还是先根据前向传播,把式子都写出来,方便计算:这样就求出了池化层的误差敏感项矩阵。同理可以求出每个神经元的梯度并更新权重。手写一个卷积神经网络1.定义一个卷积层首先我们通过ConvLayer来实现一个卷积层,定义卷积层的超参数其中calculate_output_size用来计算通过卷积运算后输出的feature_map大小2.构造一个激活函数此处用的是RELU激活函数,因此我们在activators.py里定义,forward是前向计算,backforward是计算公式的导数:其他常见的激活函数我们也可以放到activators里,如sigmoid

卷积神经网络CNN代码解析-matlab

卷积神经网络CNN代码解析 deepLearnToolbox-master是一个深度学习matlab包,里面含有很多机器学习算法,如卷积神经网络CNN,深度信念网络DBN,自动编码AutoEncoder(堆栈SAE,卷积CAE)的作者是Rasmus Berg Palm (rasmusbergpalm@https://www.360docs.net/doc/7510357765.html,) 代码下载:https://https://www.360docs.net/doc/7510357765.html,/rasmusbergpalm/DeepLearnToolbox 这里我们介绍deepLearnToolbox-master中的CNN部分。 DeepLearnToolbox-master中CNN内的函数: 调用关系为: 该模型使用了mnist的数字mnist_uint8.mat作为训练样本,作为cnn的一个使用样例, 每个样本特征为一个28*28=的向量。

网络结构为: 让我们来看看各个函数: 一、Test_example_CNN: (2) 三、cnntrain.m (5) 四、cnnff.m (6) 五、cnnbp.m (7) 五、cnnapplygrads.m (10) 六、cnntest.m (11) 一、Test_example_CNN: Test_example_CNN: 1设置CNN的基本参数规格,如卷积、降采样层的数量,卷积核的大小、降采样的降幅 2 cnnsetup函数初始化卷积核、偏置等 3 cnntrain函数训练cnn,把训练数据分成batch,然后调用 3.1 cnnff 完成训练的前向过程,

3.2 cnnbp计算并传递神经网络的error,并计算梯度(权重的修改量) 3.3 cnnapplygrads 把计算出来的梯度加到原始模型上去 4 cnntest 函数,测试当前模型的准确率 该模型采用的数据为mnist_uint8.mat, 含有70000个手写数字样本其中60000作为训练样本,10000作为测试样本。把数据转成相应的格式,并归一化。 设置网络结构及训练参数 初始化网络,对数据进行批训练,验证模型准确率 绘制均方误差曲线 二、Cnnsetup.m 该函数你用于初始化CNN的参数。 设置各层的mapsize大小, 初始化卷积层的卷积核、bias 尾部单层感知机的参数设置 * bias统一设置为0

相关文档
最新文档