卷积神经网络全面解析之代码注释
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
卷积神经网络全面解析之代码注释
自己平时看了一些论文,但老感觉看完过后就会慢慢的淡忘,某一天重新拾起来的时候又好像没有看过一样。所以想习惯地把一些感觉有用的论文中的知识点总结整理一下,一方面在整理过程中,自己的理解也会更深,另一方面也方便未来自己的勘察。更好的还可以放到博客上面与大家交流。因为基础有限,所以对论文的一些理解可能不太正确,还望大家不吝指正交流.
下面是自己对代码的注释:
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 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. % yers中有五个struct类型的元素,实际上就表示CNN共有五层,
这里范围的是5
12. for l = 1 : numel(yers) % layer
13. if strcmp(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 / yers{l}.scale);
18. for j = 1 : inputmaps % inputmap就是上一层有多少张特征
图
19. yers{l}.b{j} = 0; % 将偏置初始化为0
20. end
21. end
22. if strcmp(yers{l}.type, 'c') % 如果这层是卷积层
23. % 旧的mapsize保存的是上一层的特征map的大小,那么如果卷
积核的移动步长是1,那用
24. % kernelsize*kernelsize大小的卷积核卷积上一层的特征map
后,得到的新的map的大小就是下面这样
25. mapsize = mapsize - yers{l}.kernelsize + 1;
26. % 该层需要学习的参数个数。每张特征map是一个(后层特征图数
量)*(用来卷积的patch图的大小)
27. % 因为是通过用一个核窗口在上一个特征map层中移动(核窗口每
次移动1个像素),遍历上一个特征map
28. % 层的每个神经元。核窗口由kernelsize*kernelsize个元素组
成,每个元素是一个独立的权值,所以
29. % 就有kernelsize*kernelsize个需要学习的权值,再加一个偏
置值。另外,由于是权值共享,也就是
30. % 说同一个特征map层是用同一个具有相同权值元素的
kernelsize*kernelsize的核窗口去感受输入上一
31. % 个特征map层的每个神经元得到的,所以同一个特征map,它的
权值是一样的,共享的,权值只取决于