输出连续值的深度学习神经网络_20170504

输出连续值的深度学习神经网络_20170504
输出连续值的深度学习神经网络_20170504

输出连续值的深度神经网络

1.前言

本文设计并实现了输出连续值的深度神经网络。可用于自动构图特征线位置判断等需要连续值的场合。特征线的位置可以是垂直的,也可以是水平的。即特征线有垂直和水平两种特征线。

所设计的深度神经网络基于Deeplearning Toolbox中的神经神经网络修改而来。主要修改内容为将输出节点数由原来的10个调整为3个。每个节点的输出值也进行重新定义。原节点输出值表示属于某个分类的概率值。而新的节点输出值表示特征线所位于的图像中位置在整幅图像中的比例值。

深度神经网络共5层,包含两层卷积层。每层卷积层后会加一层sigmoid函数层作为卷积层的激活函数。

本文所涉及的代码已经在UFLDL教程的相关它模块中被调试通过并保存。并且与

CNN_matlab_code一文中的代码相对应。

2.经验总结

深度神经网络就像是一个具备很强学习能力的学生,对深度神经网络进行训练的样本就像是教学生用的教材。选用什么教材,能教会学生什么样的技能。在教学生的过程中,还要注意方式方法。对于同样的教材和同样的学生,如果采用不同的教学方式方法,可能获得完全不同的教学结果。

对于自动构图而言,如果需要使得同一个深度神经网络能识别水平和垂直两种特征线位置,首先要收集足够的具备两种特征线的图片样本。其次就是设计3个输出节点的输出值的含义。有两种方案,能取得截然不同的训练效果。第一种方案:令节点1表示水平特征线位置在整幅图像中的比例,令节点2表示垂直特征线位置在整幅图像中的比例,那么训练效果会很差;节点1和节点2的输出值无法准确反映水平或垂直特征线位置在整幅图像中的比例。第二种方案:令节点1区分水平特征线还是垂直特征线;如果节点1输出值为1,那么表示是水平特征线;如果节点1输出值为0,那么表示是垂直特征线。而节点2所输出的值表示特征线的位置在整幅图像中的比例;当节点1输出的值为1时,节点2输出值表示水平特征线的位置在整幅图像中的比例;当节点1输出的值为0时,节点2输出值表示垂直特征线的位置在整幅图像中的比例;这种训练效果良好;节点1输出的值能准确反映图像中包含水平特征线还是垂直特征线;节点2输出的值能准确反映图像中包含水平特征线或垂直特征线的位置在图像中所处的比例。

对于深度神经网络,如果出现过拟合现象,那么可减少深度神经网络的层数,从而减少网络中可调整的参数,使得神经网络能正确处理训练样本之外的样本。如果出现欠拟合现象,那么可增加深度神经网络的层数,从而增加网络中可调整的参数,使得神经网络能准确拟合所有的训练样本。

当深度网络的层数较少时,sigmoid函数能很好地使得网络收敛。当深度网络的层数较多时,sigmoid函数无法使得网络很好地收敛。此时需要采用Relu等改进的激活函数以及层之间的归一化处理等方式,使得深度神经网络尽快收敛。

3.代码更新部分

3.1测试代码

% 1. 2017.04.11:perfect test results: the continuous output results incided with their % exptected values.

% 2. 2017.04.12:test my samples

% 3. horitizatal or vertical characteritic identification;

% 4. reduce the cnn parameters to solve the problem of overfitting

% 5. reduce the precision of parameter to single precision

clear all

clc

close all

for k=1:8

temp=imread(['img_sample_h',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k)=img1(:,:,1);

train_y(1:3,k)=single(k)/10;

end

for k=1:8

temp=imread(['sample_folder\sample3_',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k+8)=img1(:,:,1);

% train_y(1:3,k)=double(k)/10;

train_y(1:3,k+8)=single(k)/10;

end

for k=1:8

temp=imread(['sample_folder\sample_',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k+16)=img1(:,:,1);

% train_y(1:3,k)=double(k)/10;

train_y(1:3,k+16)=single(k)/10;

end

for k=1:8

temp=imread(['sample_folder\sample4_',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k+24)=img1(:,:,1);

% train_y(1:3,k)=double(k)/10;

train_y(1:3,k+24)=single(k)/10;

end

train_x1 = single(reshape(train_x,96,96,32))/255; train_y1 = single(train_y);

figure

for i=1:32

subplot(4,8,i)

imshow(train_x1(:,:,i))

title(sprintf('h=%.2f',train_y1(1,i)))

end

% v_cnn=cnn

loadcnn_epoch_500.mat

% num_train_samples=30000;

opts.alpha = 1;

opts.batchsize =4;

% opts.numepochs = 1;

opts.numepochs =1000;

% cnn = cnntrain(cnn, train_x1, train_y1, opts); cnn = cnntrain(cnn, train_x1, train_y1, opts);

save('cnn_epoch_500.mat','cnn')

% test_x(:,:,1)=imread('img_sample_h3.jpg');

% test_x(:,:,2)=imread('img_sample_h34.jpg');

% test_x(:,:,3)=imread('img_sample_h37.jpg');

% test_x(:,:,4)=imread('img_sample_h4.jpg');

test_x(:,:,1)=imread('sample_folder\sample3_4.jpg'); test_x(:,:,2)=imread('sample_folder\sample3_8.jpg'); test_x(:,:,3)=imread('sample_folder\sample_6.jpg'); test_x(:,:,4)=imread('sample_folder\sample_3.jpg');

test_y(1:3,1)=0.3;

test_y(1:3,2)=0.34;

test_y(1:3,3)=0.37;

test_y(1:3,4)=0.4;

% test_x1 = double(reshape(test_x,28,28,4))/255;

% test_y1 = double(test_y);

test_x1 = single(reshape(test_x,96,96,4))/255;

test_y1 = single(test_y);

[er, bad] = cnntest(cnn, test_x1, test_y1);

3.2 训练部分

% 1. 2017.04.11:perfect test results: the continuous output results incided with theirexpected values.

% 2. 2017.04.12:test my samples

% 3. horitizatal or vertical characteritic identification;

% 4. reduce the cnn parameters to solve the problem of overfitting

% 5. reduce the precision of parameter to single precision

clear all

clc

close all

for k=1:8

temp=imread(['img_sample_h',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k)=img1(:,:,1);

% train_y(1:3,k)=double(k)/10;

train_y(1:3,k)=single(k)/10;

end

for k=1:8

temp=imread(['sample_folder\sample3_',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k+8)=img1(:,:,1);

% train_y(1:3,k)=double(k)/10;

train_y(1:3,k+8)=single(k)/10;

end

for k=1:8

temp=imread(['sample_folder\sample_',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k+16)=img1(:,:,1);

% train_y(1:3,k)=double(k)/10;

train_y(1:3,k+16)=single(k)/10;

end

for k=1:8

temp=imread(['sample_folder\sample4_',num2str(k),'.jpg']);

img1=repmat(temp,1,1,2);

train_x(:,:,k+24)=img1(:,:,1);

% train_y(1:3,k)=double(k)/10;

train_y(1:3,k+24)=single(k)/10;

end

train_x1 = single(reshape(train_x,96,96,32))/255;

train_y1 = single(train_y);

figure

for i=1:32

subplot(4,8,i)

imshow(train_x1(:,:,i))

title(sprintf('h=%.2f',train_y1(1,i)))

end

rand('state',0)

% https://www.360docs.net/doc/d49482517.html,yers = {

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

% struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer % struct('type', 's', 'scale', 2) %sub sampling layer

% struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer % struct('type', 's', 'scale', 2) %subsampling layer

% };

https://www.360docs.net/doc/d49482517.html,yers = {

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

struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer

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

struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer

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

struct('type', 'c', 'outputmaps', 7, 'kernelsize',4) %convolution layer

struct('type', 's', 'scale', 3) %subsampling layer

};

cnn = cnnsetup(cnn, train_x, train_y);

opts.alpha = 1;

opts.batchsize =4;

opts.numepochs =1000;

cnn = cnntrain(cnn, train_x1, train_y1, opts);

save('cnn_epoch_500.mat','cnn')

test_x(:,:,1)=imread('sample_folder\sample3_4.jpg');

test_x(:,:,2)=imread('sample_folder\sample3_8.jpg');

test_x(:,:,3)=imread('sample_folder\sample_6.jpg');

test_x(:,:,4)=imread('sample_folder\sample_3.jpg');

test_y(1:3,1)=0.3; % the number of output nodes is equal to 3.

test_y(1:3,2)=0.34;

test_y(1:3,3)=0.37;

test_y(1:3,4)=0.4;

test_x1 = single(reshape(test_x,96,96,4))/255;

test_y1 = single(test_y);

[er, bad] = cnntest(cnn, test_x1, test_y1);

3.2cnnsetup

这部分中的onum应该修改为输出节点的数目。

function net = cnnsetup(net, x, y)

assert(~isOctave() || compare_versions(OCTAVE_VERSION, '3.8.0', '>='), ['Octave 3.8.0 or greater is required for CNNs as there is a bug in convolution in previous versions. See https://www.360docs.net/doc/d49482517.html,/bugs/?39314. Your version is ' myOctaveVersion]);

inputmaps = 1;

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

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

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

mapsize = mapsize / https://www.360docs.net/doc/d49482517.html,yers{l}.scale;

assert(all(floor(mapsize)==mapsize), ['Layer ' num2str(l) ' size must be integer. Actual: 'num2str(mapsize)]);

for j = 1 : inputmaps

https://www.360docs.net/doc/d49482517.html,yers{l}.b{j} = 0;

end

end

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

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

fan_out = https://www.360docs.net/doc/d49482517.html,yers{l}.outputmaps * https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize ^ 2;

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

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

for i = 1 : inputmaps % input map

https://www.360docs.net/doc/d49482517.html,yers{l}.k{i}{j} = (rand(https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize) - 0.5) * 2 * sqrt(6 / (fan_in + fan_out));

end

https://www.360docs.net/doc/d49482517.html,yers{l}.b{j} = 0;

end

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

end

end

% 'onum' is the number of labels, that's why it is calculated using size(y, 1). If

you have 20 labels so the output of the network will be 20 neurons.

% 'fvnum' is the number of output neurons at the last layer, the layer just before the output layer.

% 'ffb' is the biases of the output neurons.

% 'ffW' is the weights between the last layer and the output neurons. Note that the last layer is fully connected to the output layer, that's why the size of the weights is (onum * fvnum)

fvnum = prod(mapsize) * inputmaps;

% onum = size(y, 1);

% the onum is same with the nout in the test_example_CNN2.m

onum = 3;

net.ffb = zeros(onum, 1);

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

end

4.采用Relu激活函数代替Sigmoid函数

4.1 cnnff

function net = cnnff(net, x)

n = numel(https://www.360docs.net/doc/d49482517.html,yers);

https://www.360docs.net/doc/d49482517.html,yers{1}.a{1} = x;

inputmaps = 1;

for l = 2 : n % for each layer

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

% !!below can probably be handled by insane matrix operations

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

% create temp output map

z = zeros(size(https://www.360docs.net/doc/d49482517.html,yers{l - 1}.a{1}) - [https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize - 1 https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize - 1 0]);

for i = 1 : inputmaps % for each input map

% convolve with corresponding kernel and add to temp output map

z = z + convn(https://www.360docs.net/doc/d49482517.html,yers{l - 1}.a{i}, https://www.360docs.net/doc/d49482517.html,yers{l}.k{i}{j}, 'valid');

end

% add bias, pass through nonlinearity

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

https://www.360docs.net/doc/d49482517.html,yers{l}.a{j} = sigm_new(z + https://www.360docs.net/doc/d49482517.html,yers{l}.b{j});

end

% set number of input maps to this layers number of outputmaps

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

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

% downsample

for j = 1 : inputmaps

z = convn(https://www.360docs.net/doc/d49482517.html,yers{l - 1}.a{j}, ones(https://www.360docs.net/doc/d49482517.html,yers{l}.scale) / (https://www.360docs.net/doc/d49482517.html,yers{l}.scale ^ 2), 'valid'); % !!

replace with variable

https://www.360docs.net/doc/d49482517.html,yers{l}.a{j} = z(1 : https://www.360docs.net/doc/d49482517.html,yers{l}.scale : end, 1 : https://www.360docs.net/doc/d49482517.html,yers{l}.scale : end, :);

end

end

end

% concatenate all end layer feature maps into vector

net.fv = [];

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

sa = size(https://www.360docs.net/doc/d49482517.html,yers{n}.a{j});

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

end

% feedforward into output perceptrons

net.o = sigm(net.ffW * net.fv + repmat(net.ffb, 1, size(net.fv, 2)));

end

4.2 cnnbp

function net = cnnbp(net, y)

n = numel(https://www.360docs.net/doc/d49482517.html,yers);

net.e = net.o - y;

% loss function

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

%% backprop deltas

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

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

if strcmp(https://www.360docs.net/doc/d49482517.html,yers{n}.type, 'c') % only conv layers has sigm function

net_fv=zeros(size(net.fv));

net_fv(net.fv>0)=1;

net_fv(net.fv==0)=0.5;

net.fvd = net.fvd .* net_fv;

end

% reshape feature vector deltas into output map style

sa = size(https://www.360docs.net/doc/d49482517.html,yers{n}.a{1});

fvnum = sa(1) * sa(2);

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

https://www.360docs.net/doc/d49482517.html,yers{n}.d{j} = reshape(net.fvd(((j - 1) * fvnum + 1) : j * fvnum, :), sa(1), sa(2), sa(3)); end

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

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

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

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

end

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

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

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

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

z = z + convn(https://www.360docs.net/doc/d49482517.html,yers{l + 1}.d{j}, rot180(https://www.360docs.net/doc/d49482517.html,yers{l + 1}.k{i}{j}), 'full');

end

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

end

end

end

%% calc gradients

for l = 2 : n

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

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

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

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

end

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

end

end

end

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

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

function X = rot180(X)

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

end

end

4.3 sigm_new

function X = sigm_new(P)

X = max(P,0);

end

5.Appendix

Deep Learning论文笔记之(五)CNN卷积神经网络代码理解

zouxy09@https://www.360docs.net/doc/d49482517.html,

https://www.360docs.net/doc/d49482517.html,/zouxy09

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

本文的代码来自githup的Deep Learning的toolbox,(在这里,先感谢该toolbox的作者)里面包含了很多Deep Learning方法的代码。是用Matlab编写的(另外,有人翻译成了C++和Python的版本了)。本文中我们主要解读下CNN的代码。详细的注释见代码。

在读代码之前,最好先阅读下我的上一个博文:

Deep Learning论文笔记之(四)CNN卷积神经网络推导和实现

https://www.360docs.net/doc/d49482517.html,/zouxy09/article/details/9993371

里面包含的是我对一个作者的CNN笔记的翻译性的理解,对CNN的推导和实现做了详细的介绍,看明白这个笔记对代码的理解非常重要,所以强烈建议先看懂上面这篇文章。

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

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.

https://www.360docs.net/doc/d49482517.html,yers = {

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

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

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

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

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

21.};

22.

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

https://www.360docs.net/doc/d49482517.html,n = cnnsetup(cnn, train_x, train_y);

25.

26.% 学习率

27.opts.alpha = 1;

% 每次挑出一个batchsize的batch来训练,也就是每用batchsize个样本就调整一次权值,而不是把所有样本都输入了,计算所有样本的误差了才调整一次权值

28.opts.batchsize = 50;

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

30.% 1的时候 11.41% error

31.% 5的时候 4.2% error

32.% 10的时候 2.73% error

33.opts.numepochs = 10;

34.

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

https://www.360docs.net/doc/d49482517.html,n = cnntrain(cnn, train_x, train_y, opts);

37.

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

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

40.

41.%plot mean squared error

42.plot(cnn.rL);

43.%show test error

44.disp([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.

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

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

% https://www.360docs.net/doc/d49482517.html,yers中有五个struct类型的元素,实际上就表示CNN共有五层,这里范围的是5

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

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

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

12.% 这里除以scale=2,就是pooling之后图的大小,pooling域之间没有重叠,所以pooling 后的图像为14*14,注意这里的右边的mapsize保存的都是上一层每张特征map的大小,它会随着循环进行不断更新

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

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

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

16. end

17. end

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

19.% 旧的mapsize保存的是上一层的特征map的大小,那么如果卷积核的移动步长是1,那用kernelsize*kernelsize大小的卷积核卷积上一层的特征map后,得到的新的map的大小就是下面这样

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

% 该层需要学习的参数个数。每张特征map是一个(后层特征图数量)*(用来卷积的patch图的大小)。因为是通过用一个核窗口在上一个特征map层中移动(核窗口每次移动1个像素),遍历上一个特征map 层的每个神经元。核窗口由kernelsize*kernelsize个元素组成,每个元素是一个独立的权值,所以就有kernelsize*kernelsize个需要学习的权值,再加一个偏置值。另外,由于是权值共享,也就是说同一个特征map层是用同一个具有相同权值元素的

kernelsize*kernelsize的核窗口去感受输入上一个特征map层的每个神经元得到的,所以同一个特征map,它的权值是一样的,共享的,权值只取决于核窗口。然后,不同的特征map提取输入上一个特征map层不同的特征,所以采用的核窗口不一样,也就是权值不一样,所以outputmaps个特征map就有(kernelsize*kernelsize+1)* outputmaps那么多的权值了。但这里fan_out只保存卷积核的权值W,偏置b在下面独立保存。

21. fan_out = https://www.360docs.net/doc/d49482517.html,yers{l}.outputmaps * https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize ^ 2;

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

23. % fan_out保存的是对于上一层的一张特征map,我在这一层需要对这一张特征map提取outputmaps种特征,提取每种特征用到的卷积核不同,所以fan_out保存的是这一层输出新的特征需要学习的参数个数。而,fan_in保存的是,我在这一层,要连接到上一层中所有的特征map,然后用fan_out保存的提取特征的权值来提取他们的特征。也即是对于每一个当前层特征图,有多少个参数链到前层

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

25. for i = 1 : inputmaps % input map

26.% 随机初始化权值,也就是共有outputmaps个卷积核,对上层的每个特征map,都需要用这么多个卷积核

27.% 去卷积提取特征。

28.% rand(n)是产生n×n的 0-1之间均匀取值的数值的矩阵,再减去0.5就相当于产生-0.5到0.5之间的随机数,再 *2 就放大到 [-1, 1]。然后再乘以后面那一数,why?

% 反正就是将卷积核每个元素初始化为[-sqrt(6 / (fan_in + fan_out)), sqrt(6 / (fan_in + fan_out))]之间的随机数。因为这里是权值共享的,也就是对于一张特征map,所有感受野位置的卷积核都是一样的,所以只需要保存的是 inputmaps * outputmaps 个卷积核。

https://www.360docs.net/doc/d49482517.html,yers{l}.k{i}{j} = (rand(https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize) - 0.5) * 2 * sqrt(6 / (fan_in + fan_out));

30. end

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

32. end

33. % 只有在卷积层的时候才会改变特征map的个数,pooling的时候不会改变个数。这层输出的特征map个数就是输入到下一层的特征map个数

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

35. end

36. end

37.

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

39. % 这一层的上一层是经过pooling后的层,包含有inputmaps个特征map。每个特征map的大小是mapsize。所以,该层的神经元个数是 inputmaps * (每个特征map的大小)

40. % prod: Product of elements.

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

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

43. fvnum = prod(mapsize) * inputmaps;

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

45. onum = size(y, 1);

46.

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

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

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

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

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

52.end

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.end

cnnff.m

[plain]view plain copy

function net = cnnff(net, x)

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

2. https://www.360docs.net/doc/d49482517.html,yers{1}.a{1} = x; % 网络的第一层就是输入,但这里的输入包含了多个训练图像

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

4.

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

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

7. % !!below can probably be handled by insane matrix operations

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

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

10. % create temp output map

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

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

% 对于这里的层,因为每层都包含多张特征map,对应的索引保存在每层map的第三维

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

z = zeros(size(https://www.360docs.net/doc/d49482517.html,yers{l - 1}.a{1}) - [https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize - 1 https://www.360docs.net/doc/d49482517.html,yers{l}.kernelsize - 1 0]); for i = 1 : inputmaps % for each input map

13. % convolve with corresponding kernel and add to temp output map

14. % 将上一层的每一个特征map(也就是这层的输入map)与该层的卷积核进行卷积,

然后将对上一层特征map的所有结果加起来。也就是说,当前层的一张特征map,是用一种

卷积核去卷积上一层中所有的特征map,然后所有特征map对应位置的卷积值的和。另外,

有些论文或者实际应用中,并不是与全部的特征map链接的,有可能只与其中的某几个连接。

15. z = z + convn(https://www.360docs.net/doc/d49482517.html,yers{l - 1}.a{i}, https://www.360docs.net/doc/d49482517.html,yers{l}.k{i}{j}, 'valid');

16. end

17. % add bias, pass through nonlinearity

18. % 加上对应位置的基b,然后再用sigmoid函数算出特征map中每个位置的激活值,作为该层输出特征map

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

20. end

21. % set number of input maps to this layers number of outputmaps

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

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

24. % downsample

25. for j = 1 : inputmaps

26. % !! replace with variable

27. % 例如我们要在scale=2的域上面执行mean pooling,那么可以卷积大小为2*2,每个元素都是1/4的卷积核

28. z = convn(https://www.360docs.net/doc/d49482517.html,yers{l - 1}.a{j}, ones(https://www.360docs.net/doc/d49482517.html,yers{l}.scale) / (https://www.360docs.net/doc/d49482517.html,yers{l}.scale ^ 2), 'valid');

29. % 因为convn函数的默认卷积步长为1,而pooling操作的域是没有重叠的,所以对于上面的卷积结果,最终pooling的结果需要从上面得到的卷积结果中以scale=2为步长,跳着

把mean pooling的值读出来

30. https://www.360docs.net/doc/d49482517.html,yers{l}.a{j} = z(1 : https://www.360docs.net/doc/d49482517.html,yers{l}.scale : end, 1 : https://www.360docs.net/doc/d49482517.html,yers{l}.scale : end, :);

31. end

32. end

33. end

34.

35. % concatenate all end layer feature maps into vector

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

37. net.fv = [];

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

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

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

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

41. net.fv = [net.fv; reshape(https://www.360docs.net/doc/d49482517.html,yers{n}.a{j}, sa(1) * sa(2), sa(3))];

42. end

43. % feedforward into output perceptrons

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

45. net.o = sigm(net.ffW * net.fv + repmat(net.ffb, 1, size(net.fv, 2)));

46.end

cnnbp.m

[plain]view plain copy

1.function net = cnnbp(net, y)

2. n = numel(https://www.360docs.net/doc/d49482517.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/d49482517.html,yers{n}.type, 'c') % only conv layers 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/d49482517.html,yers{n}.a{1}); % 最后一层特征map的大小。这里的最后一层都是指输出层的前一层

22. fvnum = sa(1) * sa(2); % 因为是将最后一层特征map拉成一条向量,所以对于一个样本来说,特征维数是这样

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

24. % 在fvd里面保存的是所有样本的特征向量(在cnnff.m函数中用特征map拉成的),所以这里需要重新

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

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

27.

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

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

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

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

% https://www.360docs.net/doc/d49482517.html,yers{l}.d{j} 保存的是第l层的第j个 map 的灵敏度map。也就是每个神经元节点的delta的值。expand的操作相当于对l+1层的灵敏度map进行上采样。然后前面的操作相当于对该层的输入a进行sigmoid求导

32. % 这条公式请参考 Notes on Convolutional Neural Networks

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

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

35. % end

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

37. end

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

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

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

41. for j = 1 : numel(https://www.360docs.net/doc/d49482517.html,yers{l + 1}.a) % 第l+1层特征map的个数

42. z = z + convn(https://www.360docs.net/doc/d49482517.html,yers{l + 1}.d{j}, rot180(https://www.360docs.net/doc/d49482517.html,yers{l + 1}.k{i}{j}), 'full');

43. end

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

45. end

46. end

47. end

48.

49. %% calc gradients

50. % 这里与 Notes on Convolutional Neural Networks 中不同,这里的子采样层没有参数,也没有激活函数,所以在子采样层是没有需要求解的参数的

51. for l = 2 : n

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

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

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

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

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

57. end

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

59. https://www.360docs.net/doc/d49482517.html,yers{l}.db{j} = sum(https://www.360docs.net/doc/d49482517.html,yers{l}.d{j}(:)) / size(https://www.360docs.net/doc/d49482517.html,yers{l}.d{j}, 3);

60. end

61. end

62. end

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

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

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

66.

67. function X = rot180(X)

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

69. end

70.end

cnnapplygrads.m

[plain]view plain copy

1.function net = cnnapplygrads(net, opts)

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

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

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

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

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

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

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

8. end

9. end

10. https://www.360docs.net/doc/d49482517.html,yers{l}.b{j} = https://www.360docs.net/doc/d49482517.html,yers{l}.b{j} - opts.alpha * https://www.360docs.net/doc/d49482517.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.end

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.end 88888888888888888888888888888888888888888888888888888888888888888888888888888888 Deep Learning论文笔记之(四)CNN卷积神经网络推导和实现

zouxy09@https://www.360docs.net/doc/d49482517.html,

https://www.360docs.net/doc/d49482517.html,/zouxy09

本文的论文来自:

Notes on Convolutional Neural Networks, Jake Bouvrie。

这个主要是CNN的推导和实现的一些笔记,再看懂这个笔记之前,最好具有CNN的一些基础。这里也先列出一个资料供参考:

[1] Deep Learning(深度学习)学习笔记整理系列之(七)

[2] LeNet-5, convolutional neural networks

[3]卷积神经网络

[4] Neural Network for Recognition of Handwritten Digits

[5] Deep learning:三十八(Stacked CNN简单介绍)

[6] Gradient-based learning applied to document recognition.

[7]Imagenet classification with deep convolutional neural networks.

[8] UFLDL中的“卷积特征提取”和“池化”。

另外,这里有个matlab的Deep Learning的toolbox,里面包含了CNN的代码,在下一个博文中,我将会详细注释这个代码。这个笔记对这个代码的理解非常重要。

下面是自己对其中的一些知识点的理解:

《Notes on Convolutional Neural Networks》

一、介绍

这个文档讨论的是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来表示当前层,那么当前层的输出可以表示为:

输出激活函数f(.)可以有很多种,一般是sigmoid函数或者双曲线正切函数。sigmoid将输出压缩到[0, 1],所以最后的输出平均值一般趋于0 。所以如果将我们的训练数据归一化为零均值和方差为1,可以在梯度下降的过程中增加收敛性。对于归一化的数据集来说,双曲线正切函数也是不错的选择。

2.2、Backpropagation Pass反向传播

反向传播回来的误差可以看做是每个神经元的基的灵敏度sensitivities(灵敏度的意思就是我们的基b变化多少,误差会变化多少,也就是误差对基的变化率,也就是导数了),定义如下:(第二个等号是根据求导的链式法则得到的)

因为?u/?b=1,所以?E/?b=?E/?u=δ,也就是说bias基的灵敏度?E/?b=δ和误差E对一个节点全部输入u的导数?E/?u是相等的。这个导数就是让高层误差反向传播到底层的神来之笔。反向传播就是用下面这条关系式:(下面这条式子表达的就是第l层的灵敏度,就是)

公式(1)

这里的“?”表示每个元素相乘。输出层的神经元的灵敏度是不一样的:

最后,对每个神经元运用delta(即δ)规则进行权值更新。具体来说就是,对一个给定的神经元,得到它的输入,然后用这个神经元的delta(即δ)来进行缩放。用向量的形式表述就是,对于第l层,误差对于该层每一个权值(组合为矩阵)的导数是该层的输入(等于上一层的输出)与该层的灵敏度(该层每个神经元的δ组合成一个向量的形式)的叉乘。然后得到的偏导数乘以一个负学习率就是该层的神经元的权值的更新了:

公式(2)

对于bias基的更新表达式差不多。实际上,对于每一个权值(W)ij都有一个特定的学习率ηIj。

三、Convolutional Neural Networks 卷积神经网络

3.1、Convolution Layers 卷积层

我们现在关注网络中卷积层的BP更新。在一个卷积层,上一层的特征maps被一个可学习的卷积核进行卷积,然后通过一个激活函数,就可以得到输出特征map。每一个输出map

可能是组合卷积多个输入maps的值:

零基础入门深度学习(5) - 循环神经网络

[关闭] 零基础入门深度学习(5) - 循环神经网络 机器学习深度学习入门 无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理想有追求的程序员,不懂深度学习(Deep Learning)这个超热的技术,会不会感觉马上就out了?现在救命稻草来了,《零基础入门深度学习》系列文章旨在讲帮助爱编程的你从零基础达到入门级水平。零基础意味着你不需要太多的数学知识,只要会写程序就行了,没错,这是专门为程序员写的文章。虽然文中会有很多公式你也许看不懂,但同时也会有更多的代码,程序员的你一定能看懂的(我周围是一群狂热的Clean Code程序员,所以我写的代码也不会很差)。 文章列表 零基础入门深度学习(1) - 感知器 零基础入门深度学习(2) - 线性单元和梯度下降 零基础入门深度学习(3) - 神经网络和反向传播算法 零基础入门深度学习(4) - 卷积神经网络 零基础入门深度学习(5) - 循环神经网络 零基础入门深度学习(6) - 长短时记忆网络(LSTM) 零基础入门深度学习(7) - 递归神经网络 往期回顾 在前面的文章系列文章中,我们介绍了全连接神经网络和卷积神经网络,以及它们的训练和使用。他们都只能单独的取处理一个个的输入,前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。比如,当我们在理解一句话意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列;当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。这时,就需要用到深度学习领域中另一类非常重要神经网络:循环神经网络(Recurrent Neural Network)。RNN种类很多,也比较绕脑子。不过读者不用担心,本文将一如既往的对复杂的东西剥茧抽丝,帮助您理解RNNs以及它的训练算法,并动手实现一个循环神经网络。 语言模型 RNN是在自然语言处理领域中最先被用起来的,比如,RNN可以为语言模型来建模。那么,什么是语言模型呢? 我们可以和电脑玩一个游戏,我们写出一个句子前面的一些词,然后,让电脑帮我们写下接下来的一个词。比如下面这句:我昨天上学迟到了,老师批评了____。 我们给电脑展示了这句话前面这些词,然后,让电脑写下接下来的一个词。在这个例子中,接下来的这个词最有可能是『我』,而不太可能是『小明』,甚至是『吃饭』。 语言模型就是这样的东西:给定一个一句话前面的部分,预测接下来最有可能的一个词是什么。 语言模型是对一种语言的特征进行建模,它有很多很多用处。比如在语音转文本(STT)的应用中,声学模型输出的结果,往往是若干个可能的候选词,这时候就需要语言模型来从这些候选词中选择一个最可能的。当然,它同样也可以用在图像到文本的识别中(OCR)。 使用RNN之前,语言模型主要是采用N-Gram。N可以是一个自然数,比如2或者3。它的含义是,假设一个词出现的概率只与前面N个词相关。我

(完整版)深度神经网络及目标检测学习笔记(2)

深度神经网络及目标检测学习笔记 https://youtu.be/MPU2HistivI 上面是一段实时目标识别的演示,计算机在视频流上标注出物体的类别,包括人、汽车、自行车、狗、背包、领带、椅子等。 今天的计算机视觉技术已经可以在图片、视频中识别出大量类别的物体,甚至可以初步理解图片或者视频中的内容,在这方面,人工智能已经达到了3岁儿童的智力水平。这是一个很了不起的成就,毕竟人工智能用了几十年的时间,就走完了人类几十万年的进化之路,并且还在加速发展。 道路总是曲折的,也是有迹可循的。在尝试了其它方法之后,计算机视觉在仿生学里找到了正确的道路(至少目前看是正确的)。通过研究人类的视觉原理,计算机利用深度神经网络(Deep Neural Network,NN)实现了对图片的识别,包 括文字识别、物体分类、图像理解等。在这个过程中,神经元和神经网络模型、大数据技术的发展,以及处理器(尤其是GPU)强大的算力,给人工智能技术 的发展提供了很大的支持。 本文是一篇学习笔记,以深度优先的思路,记录了对深度学习(Deep Learning)的简单梳理,主要针对计算机视觉应用领域。 一、神经网络 1.1 神经元和神经网络 神经元是生物学概念,用数学描述就是:对多个输入进行加权求和,并经过激活函数进行非线性输出。 由多个神经元作为输入节点,则构成了简单的单层神经网络(感知器),可以进行线性分类。两层神经网络则可以完成复杂一些的工作,比如解决异或问题,而且具有非常好的非线性分类效果。而多层(两层以上)神经网络,就是所谓的深度神经网络。 神经网络的工作原理就是神经元的计算,一层一层的加权求和、激活,最终输出结果。深度神经网络中的参数太多(可达亿级),必须靠大量数据的训练来“这是苹在父母一遍遍的重复中学习训练的过程就好像是刚出生的婴儿,设置。.果”、“那是汽车”。有人说,人工智能很傻嘛,到现在还不如三岁小孩。其实可以换个角度想:刚出生婴儿就好像是一个裸机,这是经过几十万年的进化才形成的,然后经过几年的学习,就会认识图片和文字了;而深度学习这个“裸机”用了几十年就被设计出来,并且经过几个小时的“学习”,就可以达到这个水平了。 1.2 BP算法 神经网络的训练就是它的参数不断变化收敛的过程。像父母教婴儿识图认字一样,给神经网络看一张图并告诉它这是苹果,它就把所有参数做一些调整,使得它的计算结果比之前更接近“苹果”这个结果。经过上百万张图片的训练,它就可以达到和人差不多的识别能力,可以认出一定种类的物体。这个过程是通过反向传播(Back Propagation,BP)算法来实现的。 建议仔细看一下BP算法的计算原理,以及跟踪一个简单的神经网络来体会训练的过程。

深度学习系列(7):神经网络的优化方法

机器?学习中,梯度下降法常?用来对相应的算法进?行行训练。常?用的梯度下降法包含三种不不同的形式,分别是BGD 、SGD 和MBGD ,它们的不不同之处在于我们在对?目标函数进?行行梯度更更新时所使?用的样本量量的多少。 以线性回归算法来对三种梯度下降法进?行行?比较。 ?一般线性回归函数的假设函数为: (即有n 个特征)对应的损失函数为下图即为?一个?二维参数和组对应的损失函数可视化图像:批量量梯度下降法(Batch Gradient Descent ,简称BGD )是梯度下降法最原始的形式,它的具体思路路是在更更新每?一参数时都使?用所有的样本来进?行行更更新,其数学形式如下: 深度学习系列列(7):神经?网络的优化?方法?一、Gradient Descent [Robbins and Monro, 1951,Kiefer et al., 1952] = h θ∑j =0n θj x j L (θ)=12m ∑i =1 m (h ()?)x i y i 2θ0θ11.1 BGD (Batch Gradient Descent )

还是以上?面?小球的例例?子来看,momentum ?方式下?小球完全是盲?目被动的?方式滚下的。这样有个缺 三、NAG (Nesterov accelerated gradient )[Nesterov, 1983]

点就是在邻近最优点附近是控制不不住速度的。我们希望?小球可以预判后?面的“地形”,要是后?面地形还是很陡峭,那就继续坚定不不移地?大胆?走下去,不不然的话就减缓速度。 当然,?小球?自?己也不不知道真正要?走到哪?里里,这?里里以 作为下?一个位置的近似,将动量量的公式更更改为: 相?比于动量量?方式考虑的是上?一时刻的动能和当前点的梯度,?而NAG 考虑的是上?一时刻的梯度和近似下?一点的梯度,这使得它可以先往前探探路路,然后慎重前进。 Hinton 的slides 是这样给出的: 其中两个blue vectors 分别理理解为梯度和动能,两个向量量和即为momentum ?方式的作?用结果。?而靠左边的brown vector 是动能,可以看出它那条blue vector 是平?行行的,但它预测了了下?一阶段的梯度是red vector ,因此向量量和就是green vector ,即NAG ?方式的作?用结果。 momentum 项和nesterov 项都是为了了使梯度更更新更更加灵活,对不不同情况有针对性。但是,?人?工设置?一些学习率总还是有些?生硬,接下来介绍?几种?自适应学习率的?方法 训练深度?网络的时候,可以让学习率随着时间退?火。因为如果学习率很?高,系统的动能就过?大,参数向量量就会?无规律律地变动,?无法稳定到损失函数更更深更更窄的部分去。对学习率衰减的时机把握很有技巧:如果慢慢减?小,可能在很?长时间内只能浪费计算资源然后看着它混沌地跳动,实际进展很少;但如果快速地减少,系统可能过快地失去能量量,不不能到达原本可以到达的最好位置。通常,实现学习率退?火有三种?方式: θ?γv t ?1 =γ+ηJ (θ?γ) v t v t ?1?θv t ?1θ=θ?v t 四、学习率退?火

吴恩达深度学习课程:神经网络和深度学习

吴恩达深度学习课程:神经网络和深度学习[中英文字幕+ppt课件] 内容简介 吴恩达(Andrew Ng)相信大家都不陌生了。2017年8 月8 日,吴恩达在他自己创办的在线教育平台Coursera 上线了他的人工智能专项课程(Deep Learning Specialization)。此课程广受好评,通过视频讲解、作业与测验等让更多的人对人工智能有了了解与启蒙,国外媒体报道称:吴恩达这次深度学习课程是迄今为止,最全面、系统和容易获取的深度学习课程,堪称普通人的人工智能第一课。 关注微信公众号datayx 然后回复“深度学习”即可获取。 第一周深度学习概论: 学习驱动神经网络兴起的主要技术趋势,了解现今深度学习在哪里应用、如何应用。 1.1 欢迎来到深度学习工程师微专业 1.2 什么是神经网络? 1.3 用神经网络进行监督学习 1.4 为什么深度学习会兴起? 1.5 关于这门课

1.6 课程资源 第二周神经网络基础: 学习如何用神经网络的思维模式提出机器学习问题、如何使用向量化加速你的模型。 2.1 二分分类 2.2 logistic 回归 2.3 logistic 回归损失函数 2.4 梯度下降法 2.5 导数 2.6 更多导数的例子 2.7 计算图 2.8 计算图的导数计算 2.9 logistic 回归中的梯度下降法 2.10 m 个样本的梯度下降 2.11 向量化 2.12 向量化的更多例子 2.13 向量化logistic 回归 2.14 向量化logistic 回归的梯度输出 2.15 Python 中的广播 2.16 关于python / numpy 向量的说明 2.17 Jupyter / Ipython 笔记本的快速指南 2.18 (选修)logistic 损失函数的解释 第三周浅层神经网络:

神经网络及深度学习

可用于自动驾驶的神经网络及深度学习 高级辅助驾驶系统(ADAS)可提供解决方案,用以满足驾乘人员对道路安全及出行体验的更高要求。诸如车道偏离警告、自动刹车及泊车辅助等系统广泛应用于当前的车型,甚至是功能更为强大的车道保持、塞车辅助及自适应巡航控制等系统的配套使用也让未来的全自动驾驶车辆成为现实。 作者:来源:电子产品世界|2017-02-27 13:55 收藏 分享 高级辅助驾驶系统(ADAS)可提供解决方案,用以满足驾乘人员对道路安全及出行体验的更高要求。诸如车道偏离警告、自动刹车及泊车辅助等系统广泛应用于当前的车型,甚至是功能更为强大的车道保持、塞车辅助及自适应巡航控制等系统的配套使用也让未来的全自动驾驶车辆成为现实。 如今,车辆的很多系统使用的都是机器视觉。机器视觉采用传统信号处理技术来检测识别物体。对于正热衷于进一步提高拓展ADAS功能的汽车制造业而言,深度学习神经网络开辟了令人兴奋的研究途径。为了实现从诸如高速公路全程自动驾驶仪的短时辅助模式到专职无人驾驶旅行的自动驾驶,汽车制造业一直在寻求让响应速度更快、识别准确度更高的方法,而深度学习技术无疑为其指明了道路。 以知名品牌为首的汽车制造业正在深度学习神经网络技术上进行投资,并向先进的计算企业、硅谷等技术引擎及学术界看齐。在中国,百度一直在此技术上保持领先。百度计划在2019 年将全自动汽车投入商用,并加大全自动汽车的批量生产力度,使其在2021 年可广泛投入使用。汽车制造业及技术领军者之间的密切合作是嵌入式系统神经网络发展的催化剂。这类神经网络需要满足汽车应用环境对系统大小、成本及功耗的要求。 1轻型嵌入式神经网络 卷积式神经网络(CNN)的应用可分为三个阶段:训练、转化及CNN在生产就绪解决方案中的执行。要想获得一个高性价比、针对大规模车辆应用的高效结果,必须在每阶段使用最为有利的系统。 训练往往在线下通过基于CPU的系统、图形处理器(GPU)或现场可编程门阵列(FPGA)来完成。由于计算功能强大且设计人员对其很熟悉,这些是用于神经网络训练的最为理想的系统。 在训练阶段,开发商利用诸如Caffe(Convolution Architecture For Feature Extraction,卷积神经网络架构)等的框架对CNN 进行训练及优化。参考图像数据库用于确定网络中神经元的最佳权重参数。训练结束即可采用传统方法在CPU、GPU 或FPGA上生成网络及原型,尤其是执行浮点运算以确保最高的精确度。 作为一种车载使用解决方案,这种方法有一些明显的缺点。运算效率低及成本高使其无法在大批量量产系统中使用。 CEVA已经推出了另一种解决方案。这种解决方案可降低浮点运算的工作负荷,并在汽车应用可接受的功耗水平上获得实时的处理性能表现。随着全自动驾驶所需的计算技术的进一步发展,对关键功能进行加速的策略才能保证这些系统得到广泛应用。 利用被称为CDNN的框架对网络生成策略进行改进。经过改进的策略采用在高功耗浮点计算平台上(利用诸如Caffe的传统网络生成器)开发的受训网络结构和权重,并将其转化为基于定点运算,结构紧凑的轻型的定制网络模型。接下来,此模型会在一个基于专门优化的成像和视觉DSP芯片的低功耗嵌入式平台上运行。图1显示了轻型嵌入式神经网络的生成

(完整版)深度神经网络全面概述

深度神经网络全面概述从基本概念到实际模型和硬件基础 深度神经网络(DNN)所代表的人工智能技术被认为是这一次技术变革的基石(之一)。近日,由IEEE Fellow Joel Emer 领导的一个团队发布了一篇题为《深度神经网络的有效处理:教程和调研(Efficient Processing of Deep Neural Networks: A Tutorial and Survey)》的综述论文,从算法、模型、硬件和架构等多个角度对深度神经网络进行了较为全面的梳理和总结。鉴于该论文的篇幅较长,机器之心在此文中提炼了原论文的主干和部分重要内容。 目前,包括计算机视觉、语音识别和机器人在内的诸多人工智能应用已广泛使用了深度神经网络(deep neural networks,DNN)。DNN 在很多人工智能任务之中表现出了当前最佳的准确度,但同时也存在着计算复杂度高的问题。因此,那些能帮助DNN 高效处理并提升效率和吞吐量,同时又无损于表现准确度或不会增加硬件成本的技术是在人工智能系统之中广泛部署DNN 的关键。 论文地址:https://https://www.360docs.net/doc/d49482517.html,/pdf/1703.09039.pdf 本文旨在提供一个关于实现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 行为的各种工具、有效加速计算的各项技术的概述。 该论文的结构如下:

深度神经网络及目标检测学习笔记

深度神经网络及目标检测学习笔记 https://youtu.be/MPU2HistivI 上面是一段实时目标识别的演示,计算机在视频流上标注出物体的类别,包括人、汽车、自行车、狗、背包、领带、椅子等。 今天的计算机视觉技术已经可以在图片、视频中识别出大量类别的物体,甚至可以初步理解图片或者视频中的内容,在这方面,人工智能已经达到了3岁儿童的智力水平。这是一个很了不起的成就,毕竟人工智能用了几十年的时间,就走完了人类几十万年的进化之路,并且还在加速发展。 道路总是曲折的,也是有迹可循的。在尝试了其它方法之后,计算机视觉在仿生学里找到了正确的道路(至少目前看是正确的)。通过研究人类的视觉原理,计算机利用深度神经网络(DeepNeural Network,NN)实现了对图片的识别,包括文字识别、物体分类、图像理解等。在这个过程中,神经元和神经网络模型、大数据技术的发展,以及处理器(尤其是GPU)强大的算力,给人工智能技术的发展提供了很大的支持。 本文是一篇学习笔记,以深度优先的思路,记录了对深度学习(Deep Learning)的简单梳理,主要针对计算机视觉应用领域。 一、神经网络 1.1 神经元和神经网络 神经元是生物学概念,用数学描述就是:对多个输入进行加权求和,并经过激活函数进行非线性输出。 由多个神经元作为输入节点,则构成了简单的单层神经网络(感知器),可以进行线性分类。两层神经网络则可以完成复杂一些的工作,比如解决异或问题,而且具有非常好的非线性分类效果。而多层(两层以上)神经网络,就是所谓的深度神经网络。 神经网络的工作原理就是神经元的计算,一层一层的加权求和、激活,最终输出结果。深度神经网络中的参数太多(可达亿级),必须靠大量数据的训练来设置。训练的过程就好像是刚出生的婴儿,在父母一遍遍的重复中学习“这是苹

深度学习与全连接神经网络

统计建模与R语言 全连接神经网络 学院航空航天学院 专业机械电子工程 年级 2019级 学生学号 19920191151134 学生姓名梅子阳

一、绪论 1、人工智能背景 信息技术是人类历史上的第三次工业革命,计算机、互联网、智能家居等技术的普及极大地方便了人们的日常生活。通过编程的方式,人类可以将提前设计好的交互逻辑交给机器重复且快速地执行,从而将人类从简单枯燥的重复劳动工作中解脱出来。但是对于需要较高智能水平的任务,如人脸识别、聊天机器人、自动驾驶等任务,很难设计明确的逻辑规则,传统的编程方式显得力不从心,而人工智能(Artificial Intelligence,简称 AI)是有望解决此问题的关键技术。 随着深度学习算法的崛起,人工智能在部分任务上取得了类人甚至超人的智力水平,如围棋上 AlphaGo 智能程序已经击败人类最强围棋专家之一柯洁,在 Dota2 游戏上OpenAI Five 智能程序击败冠军队伍 OG,同时人脸识别、智能语音、机器翻译等一项项实用的技术已经进入到人们的日常生活中。现在我们的生活处处被人工智能所环绕,尽管目前能达到的智能水平离通用人工智能(Artificial General Intelligence,简称 AGI)还有一段距离,但是我们仍坚定地相信人工智能的时代已经来临。 怎么实现人工智能是一个非常广袤的问题。人工智能的发展主要经历过三个阶段,每个阶段都代表了人们从不同的角度尝试实现人工智能的探索足迹。早期,人们试图通过总结、归纳出一些逻辑规则,并将逻辑规则以计算机程序的方式实现,来开发出智能系统。但是这种显式的规则往往过于简单,并且很难表达复杂、抽象的概念和规则。这一阶段被称为推理期。 1970 年代,科学家们尝试通过知识库加推理的方式解决人工智能,通过建庞大复杂的专家系统来模拟人类专家的智能水平。这些明确指定规则的方式存在一个最大的难题,就是很多复杂、抽象的概念无法用具体的代码实现。比如人类对图片的识别、对语言的理解过程,根本无法通过既定规则模拟。为了解决这类问题,一门通过让机器自动从数据中学习规则的研究学科诞生了,称为机器学习,并在 1980 年代成为人工智能中的热门学科。在机器学习中,有一门通过神经网络来学习复杂、抽象逻辑的方向,称为神经网络。神经网络方向的研究经历了两起两落。2012 年开始,由于效果极为显著,应用深层神经网络技术在计算机视觉、自然语言处理、机器人等领域取得了重大突破,部分任务上甚至超越了人类智能水平,开启了以深层神经网络为代表的人工智能的第三次复兴。深层神经网络有了一个新名字:深度学习。一般来讲,神经网络和深度学习的本质区别并不大,深度学习特指基于深层神经网络实现的模型或算法。 2、神经网络与深度学习 将神经网络的发展历程大致分为浅层神经网络阶段和深度学习阶段,以2006 年为分割点。2006 年以前,深度学习以神经网络和连接主义名义发展,

深度学习与神经网络

CDA数据分析研究院出品,转载需授权 深度学习是机器学习的一个子领域,研究的算法灵感来自于大脑的结构和功能,称为人工神经网络。 如果你现在刚刚开始进入深度学习领域,或者你曾经有过一些神经网络的经验,你可能会感到困惑。因为我知道我刚开始的时候有很多的困惑,我的许多同事和朋友也是这样。因为他们在20世纪90年代和21世纪初就已经学习和使用神经网络了。 该领域的领导者和专家对深度学习的观点都有自己的见解,这些具体而细微的观点为深度学习的内容提供了很多依据。 在这篇文章中,您将通过听取该领域的一系列专家和领导者的意见,来了解什么是深度学习以及它的内容。 来让我们一探究竟吧。 深度学习是一种大型的神经网络 Coursera的Andrew Ng和百度研究的首席科学家正式创立了Google Brain,最终导致了大量Google服务中的深度学习技术的产品化。 他已经说了很多关于深度学习的内容并且也写了很多,这是一个很好的开始。 在深度学习的早期讨论中,Andrew描述了传统人工神经网络背景下的深度学习。在2013年的题为“ 深度学习,自学习和无监督特征学习”的演讲中“他将深度学习的理念描述为: 这是我在大脑中模拟的对深度学习的希望: - 使学习算法更好,更容易使用。 - 在机器学习和人工智能方面取得革命性进展。 我相信这是我们迈向真正人工智能的最好机会

后来他的评论变得更加细致入微了。 Andrew认为的深度学习的核心是我们现在拥有足够快的计算机和足够多的数据来实际训练大型神经网络。在2015年ExtractConf大会上,当他的题目“科学家应该了解深度学习的数据”讨论到为什么现在是深度学习起飞的时候,他评论道: 我们现在拥有的非常大的神经网络......以及我们可以访问的大量数据 他还评论了一个重要的观点,那就是一切都与规模有关。当我们构建更大的神经网络并用越来越多的数据训练它们时,它们的性能会不断提高。这通常与其他在性能上达到稳定水平的机器学习技术不同。 对于大多数旧时代的学习算法来说......性能将达到稳定水平。......深度学习......是第一类算法......是可以扩展的。...当你给它们提供更多的数据时,它的性能会不断提高 他在幻灯片中提供了一个漂亮的卡通片: 最后,他清楚地指出,我们在实践中看到的深度学习的好处来自有监督的学习。从2015年的ExtractConf演讲中,他评论道: 如今的深度学习几乎所有价值都是通过有监督的学习或从有标记的数据中学习 在2014年的早些时候,在接受斯坦福大学的题为“深度学习”的演讲时,他也发出了类似的评论。 深度学习疯狂发展的一个原因是它非常擅长监督学习

神经网络11大常见陷阱及应对方法

深度学习的这些坑你都遇到过吗?神 经网络11 大常见陷阱及应对方法【新智元导读】如果你的神经网络不工作,该怎么办?本文作者列举了搭建神经网络时可能遇到的11个常见问题,包括预处理数据、正则化、学习率、激活函数、网络权重设置等,并提供解决方法和原因解释,是深度学习实践的有用资料。 如果你的神经网络不工作,该怎么办?作者在这里列出了建神经网络时所有可能做错的事情,以及他自己的解决经验。 1.忘记规范化数据 2.忘记检查结果 3.忘记预处理数据 4.忘记使用正则化 5.使用的batch太大 6.使用了不正确的学习率 7.在最后层使用了错误的激活函数 8.你的网络包含了Bad Gradients 9.初始化网络权重不正确 10.你使用的网络太深了 11.使用隐藏单元的数量不对 忘记规范化数据了

问题描述 在使用神经网络时,思考如何正确地规范化数据是非常重要的。这是一个无法改变的步骤——假如这一步骤没有小心、正确地做,你的网络就几乎不可能工作。由于这个步骤非常重要,在深度学习社区中也是众所周知的,所以它很少在论文中被提及,因此初学者常常在这一步出错。 怎样解决? 一般来说,规范化(normalization)的意思是:将数据减去均值,再除以其方差。通常这是对每个输入和输出特征单独做的,但你可能经常会希望对特征组做或特别主翼处理某些特征的规范化。 为什么? 我们需要对数据进行规范化的主要原因是大部分的神经网络流程假设输入和输出数据都以一个约是1的标准差和约是0的均值分布。这些假设在深度学习文献中到处都是,从权重初始化、激活函数到训练网络的优化算法。 还需要注意 未训练的神经网络通常会输出约在-1到1范围之间的值。如果你希望输出其他范围的值(例如RBG图像以0-255范围的字节存储)会出现一些问题。在开始训练时,网络会非常不稳定,因为比如说预期值是255,网络产生的值是-1或1——这会被大多数用于训练神经网络的优化算法认为是严重的错误。这会产生过大的梯度,可能导致梯度爆炸。如果不爆炸,那么训练的前几个阶段就是浪费的,因为网络首先学习的是将输出值缩小到大致是预期的范围。如果规范化了数据(在这种情况下,你可以简单地将数值除以128再减去1),就不会发生这些问题。 一般来说,神经网络中特征的规模也决定了其重要性。如果输出中的有一个特征规模很大,那么与其他特征相比它会产生更大的错误。类似地,输入中的大规模特征将主导网络并导致下游发生更大的变化。因此,使用神经网络库的自动规范化往往是不够的,这些神经网络库会在每个特征的基础上盲目地减去平均值并除以方差。你可能有一个输入特征,通常范围在0.0到0.001之间——这个特征的范围如此之小,因为它是一个不重要的特征(在这种情况下,你可能不想重新scale),或者因为与其他特征相比它有一些小的单元(在这种情

深度神经网络

1. 自联想神经网络与深度网络 自联想神经网络是很古老的神经网络模型,简单的说,它就是三层BP网络,只不过它的输出等于输入。很多时候我们并不要求输出精确的等于输入,而是允许一定的误差存在。所以,我们说,输出是对输入的一种重构。其网络结构可以很简单的表示如下: 如果我们在上述网络中不使用sigmoid函数,而使用线性函数,这就是PCA模型。中间网络节点个数就是PCA模型中的主分量个数。不用担心学习算法会收敛到局部最优,因为线性BP网络有唯一的极小值。

在深度学习的术语中,上述结构被称作自编码神经网络。从历史的角度看,自编码神经网络是几十年前的事情,没有什么新奇的地方。 既然自联想神经网络能够实现对输入数据的重构,如果这个网络结构已经训练好了,那么其中间层,就可以看过是对原始输入数据的某种特征表示。如果我们把它的第三层去掉,这样就是一个两层的网络。如果,我们把这个学习到特征再用同样的方法创建一个自联想的三层BP网络,如上图所示。换言之,第二次创建的三层自联想网络的输入是上一个网络的中间层的输出。用同样的训练算法,对第二个自联想网络进行学习。那么,第二个自联想网络的中间层是对其输入的某种特征表示。如果我们按照这种方法,依次创建很多这样的由自联想网络组成的网络结构,这就是深度神经网络,如下图所示:

注意,上图中组成深度网络的最后一层是级联了一个softmax分类器。 深度神经网络在每一层是对最原始输入数据在不同概念的粒度表示,也就是不同级别的特征描述。 这种层叠多个自联想网络的方法,最早被Hinton想到了。 从上面的描述中,可以看出,深度网络是分层训练的,包括最后一层的分类器也是单独训练的,最后一层分类器可以换成任何一种分类器,例如SVM,HMM等。上面的每一层单独训练使用的都是BP算法。相信这一思路,Hinton早就实验过了。 2. DBN神经网络模型 使用BP算法单独训练每一层的时候,我们发现,必须丢掉网络的第三层,才能级联自联想神经网络。然而,有一种更好的神经网络模型,这就是受限玻尔兹曼机。使用层叠波尔兹曼机组成深度神经网络的方法,在深度学习里被称作深度信念网络DBN,这是目前非

BP神经网络及深度学习研究-综述(最新整理)

BP神经网络及深度学习研究 摘要:人工神经网络是一门交叉性学科,已广泛于医学、生物学、生理学、哲学、信息学、计算机科学、认知学等多学科交叉技术领域,并取得了重要成果。BP(Back Propagation)神经网络是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。本文将主要介绍神经网络结构,重点研究BP神经网络原理、BP神经网络算法分析及改进和深度学习的研究。 关键词:BP神经网络、算法分析、应用 1 引言 人工神经网络(Artificial Neural Network,即ANN ),作为对人脑最简单的一种抽象和模拟,是人们模仿人的大脑神经系统信息处理功能的一个智能化系统,是20世纪80 年代以来人工智能领域兴起的研究热点。人工神经网络以数学和物理方法以及信息处理的角度对人脑神经网络进行抽象,并建立某种简化模型,旨在模仿人脑结构及其功能的信息处理系统。 人工神经网络最有吸引力的特点就是它的学习能力。因此从20世纪40年代人工神经网络萌芽开始,历经两个高潮期及一个反思期至1991年后进入再认识与应用研究期,涌现出无数的相关研究理论及成果,包括理论研究及应用研究。最富有成果的研究工作是多层网络BP算法,Hopfield网络模型,自适应共振理论,自组织特征映射理论等。因为其应用价值,该研究呈愈演愈烈的趋势,学者们在多领域中应用[1]人工神经网络模型对问题进行研究优化解决。 人工神经网络是由多个神经元连接构成,因此欲建立人工神经网络模型必先建立人工神经元模型,再根据神经元的连接方式及控制方式不同建立不同类型的人工神经网络模型。现在分别介绍人工神经元模型及人工神经网络模型。 1.1 人工神经元模型 仿生学在科技发展中起着重要作用,人工神经元模型的建立来源于生物神经元结构的仿生模拟,用来模拟人工神经网络[2]。人们提出的神经元模型有很多,其中最早提出并且影响较大的是1943年心理学家McCulloch和数学家W. Pitts 在分析总结神经元基本特性的基础上首先提出的MP模型。该模型经过不断改进后,形成现在广泛应用的BP神经元模型。人工神经元模型是由人量处理单元厂泛互连而成的网络,是人脑的抽象、简化、模拟,反映人脑的基本特性。一般来说,作为人工神经元模型应具备三个要素: (1)具有一组突触或连接,常用表示神经元i和神经元j之间的连接强度。 w ij (2)具有反映生物神经元时空整合功能的输入信号累加器。

机器学习算法汇总:人工神经网络、深度学习及其它

学习方式 根据数据类型的不同,对一个问题的建模有不同的方式。在机器学习或者人工智能领域,人们首先会考虑算法的学习方式。在机器学习领域,有几种主要的学习方式。将算法按照学习方式分类是一个不错的想法,这样可以让人们在建模和算法选择的时候考虑能根据输入数据来选择最合适的算法来获得最好的结果。 监督式学习: 在监督式学习下,输入数据被称为“训练数据”,每组训练数据有一个明确的标识或结果,如对防垃圾邮件系统中“垃圾邮件”“非垃圾邮件”,对手写数字识别中的“1“,”2“,”3“,”4“等。在建立预测模型的时候,监督式学习建立一个学习过程,将预测结果与“训练数据”的实际结果进行比较,不断的调整预测模型,直到模型的预测结果达到一个预期的准确率。监督式学习的常见应用场景如分类问题和回归问题。常见算法有逻辑回归(Logistic Regression)和反向传递神经网络(Back Propagation Neural Network) 非监督式学习:

在非监督式学习中,数据并不被特别标识,学习模型是为了推断出数据的一些内在结构。常见的应用场景包括关联规则的学习以及聚类等。常见算法包括Apriori算法以及k-Means算法。 半监督式学习: 在此学习方式下,输入数据部分被标识,部分没有被标识,这种学习模型可以用来进行预测,但是模型首先需要学习数据的内在结构以便合理的组织数据来进行预测。应用场景包括分类和回归,算法包括一些对常用监督式学习算法的延伸,这些算法首先试图对未标识数据进行建模,在此基础上再对标识的数据进行预测。如图论推理算法(Graph Inference)或者拉普拉斯支持向量机(Laplacian SVM.)等。 强化学习:

《神经网络与深度学习综述DeepLearning15May2014

Draft:Deep Learning in Neural Networks:An Overview Technical Report IDSIA-03-14/arXiv:1404.7828(v1.5)[cs.NE] J¨u rgen Schmidhuber The Swiss AI Lab IDSIA Istituto Dalle Molle di Studi sull’Intelligenza Arti?ciale University of Lugano&SUPSI Galleria2,6928Manno-Lugano Switzerland 15May2014 Abstract In recent years,deep arti?cial neural networks(including recurrent ones)have won numerous con-tests in pattern recognition and machine learning.This historical survey compactly summarises relevant work,much of it from the previous millennium.Shallow and deep learners are distinguished by the depth of their credit assignment paths,which are chains of possibly learnable,causal links between ac- tions and effects.I review deep supervised learning(also recapitulating the history of backpropagation), unsupervised learning,reinforcement learning&evolutionary computation,and indirect search for short programs encoding deep and large networks. PDF of earlier draft(v1):http://www.idsia.ch/~juergen/DeepLearning30April2014.pdf LATEX source:http://www.idsia.ch/~juergen/DeepLearning30April2014.tex Complete BIBTEX?le:http://www.idsia.ch/~juergen/bib.bib Preface This is the draft of an invited Deep Learning(DL)overview.One of its goals is to assign credit to those who contributed to the present state of the art.I acknowledge the limitations of attempting to achieve this goal.The DL research community itself may be viewed as a continually evolving,deep network of scientists who have in?uenced each other in complex ways.Starting from recent DL results,I tried to trace back the origins of relevant ideas through the past half century and beyond,sometimes using“local search”to follow citations of citations backwards in time.Since not all DL publications properly acknowledge earlier relevant work,additional global search strategies were employed,aided by consulting numerous neural network experts.As a result,the present draft mostly consists of references(about800entries so far).Nevertheless,through an expert selection bias I may have missed important work.A related bias was surely introduced by my special familiarity with the work of my own DL research group in the past quarter-century.For these reasons,the present draft should be viewed as merely a snapshot of an ongoing credit assignment process.To help improve it,please do not hesitate to send corrections and suggestions to juergen@idsia.ch.

深度神经网络的关键技术及其在自动驾驶领域的应用

ISSN 1674-8484 CN 11-5904/U 汽车安全与节能学报, 第10卷第2期, 2019年 J Automotive Safety and Energy, Vol. 10 No. 2, 2019 1/13 119—145 深度神经网络的关键技术及其在自动驾驶领域的应用 李升波1,关?阳1,侯?廉1,高洪波1,段京良2,梁?爽3,汪?玉3,成?波1, 李克强1,任?伟4,李?骏1 (1. 清华大学车辆与运载学院,北京100084,中国;2. 加州大学伯克利分校机械系,加州 94720,美国; 3. 清华大学电子工程系,北京100084,中国; 4. 加州大学河滨分校电子计算机系,加州92521,美国) 摘?要:?智能化是汽车的三大变革技术之一,深度学习具有拟合能力优、表征能力强和适用范围广的 特点,是进一步提升汽车智能性的重要途径。该文系统性总结了用于自动驾驶汽车的深度神经网络(DNN)技术,包括发展历史、主流算法以及感知、决策与控制技术应用。回顾了神经网络的历史及现状, 总结DNN的“神经元-层-网络”3级结构,重点介绍卷积网络和循环网络的特点以及代表性模型; 阐述了以反向传播(BP)为核心的深度网络训练算法,列举用于深度学习的常用数据集与开源框架,概 括了网络计算平台和模型优化设计技术;讨论DNN在自动驾驶汽车的环境感知、自主决策和运动控 制3大方向的应用现状及其优缺点,具体包括物体检测和语义分割、分层式和端到端决策、汽车纵 横向运动控制等;针对用于自动驾驶汽车的DNN技术,指明了不同问题的适用方法以及关键问题的 未来发展方向。 关键词:?智能汽车;自动驾驶;深度神经网络(DNN);深度学习;环境感知;自主决策;运动控制 中图分类号:?TP 18;U 463.6 文献标志码:?A DOI:?10.3969/j.issn.1674-8484.2019.02.001 Key technique of deep neural network and its applications in autonomous driving LI Shengbo1, GUAN Yang1, HOU Lian1, GAO Hongbo1, DUAN Jingliang2, LIANG Shuang3, WANG Yu3, CHENG Bo1, LI Keqiang1, REN Wei4, LI Jun1 (1. School of Vehicle and Mobility, Tsinghua University, Beijing 100084, China; 2. Mechanical Engineering, University of California Berkeley, Berkeley, CA 94720, USA; 3. Electronic Engineering, Tsinghua University, Beijing 100084, China; 4. Electrical and Computer Engineering, University of California Riverside, Riverside, CA 92521, USA) Abstract: Autonomous driving is one of the three major innovations in automotive industry. Deep learning is a crucial method to improve automotive intelligence due to its outstanding abilities of data fitting, feature representation and model generalization. This paper reviewed the technologies of deep neural network (DNN) 收稿日期?/?Received?:?2019-01-19。 基金项目?/?Supported?by?: “十三五”国家重点研发计划(2016YFB0100906);国家自然科学基金面上项目(51575293);国家自然科学基金优秀青年科学基金项目(U1664263);国家自然科学基金重点项目(51622504);北京市自然科学基金杰出青 年科学基金项目(JQ18010);汽车安全与节能国家重点实验室开放基金课题(KF1828)。 第一作者?/?First?author?:?李升波(1982—),男(汉),山东,副教授。E-mail: lishbo@https://www.360docs.net/doc/d49482517.html,。

相关文档
最新文档