function [net, L] = cnntrain(net, x, y, opts)
m = size(x, 3);
numbatches = m / opts.batchsize;
if rem(numbatches, 1) ~= 0
error('numbatches not integer');
end
L = zeros(opts.numepochs*numbatches,1);
n = 1;
for i = 1 : opts.numepochs
tic;
kk = randperm(m);
for k = 1 : numbatches
batch_x = x(:, :, kk((k - 1) * opts.batchsize + 1 : k * opts.batchsize));
batch_y = y(:, kk((k - 1) * opts.batchsize + 1 : k * opts.batchsize));
net = cnnff(net, batch_x);
net = cnnbp(net, batch_y);
net = cnngrads(net, opts);
L(n) = net.loss;
n = n + 1;
end
t = toc;
str_perf = sprintf('; Full-batch train err = %f', net.loss);
disp(['CNN train: epoch ' num2str(i) '/' num2str(opts.numepochs) '. Took ' num2str(t) ' seconds' '. Mini-batch mean squared error on training set is ' num2str(mean(L((n-numbatches):(n-1)))) str_perf]);
end
end
function net = cnnff(net, x)
n = numel(net.layers);
net.layers{1}.a{1} = x;
inputmaps = 1;
for l = 2 : n % for each layer
if strcmp(net.layers{l}.type, 'c')
% !!below can probably be handled by insane matrix operations
for j = 1 : net.layers{l}.outputmaps % for each output map
% create temp output map
z = zeros(size(net.layers{l - 1}.a{1}) - [net.layers{l}.kernelsize - 1 net.layers{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(net.layers{l - 1}.a{i}, net.layers{l}.k{i}{j}, 'valid');
end
% add bias, pass through nonlinearity
net.layers{l}.a{j} = sigm(z + net.layers{l}.b{j});
end
% set number of input maps to this layers number of outputmaps
inputmaps = net.layers{l}.outputmaps;
elseif strcmp(net.layers{l}.type, 's')
% downsample
for j = 1 : inputmaps
z = convn(net.layers{l - 1}.a{j}, ones(net.layers{l}.scale) / (net.layers{l}.scale ^ 2), 'valid'); % !! replace with variable
net.layers{l}.a{j} = z(1 : net.layers{l}.scale : end, 1 : net.layers{l}.scale : end, :);
end
end
end
% concatenate all end layer feature maps into vector
net.fv = [];
for j = 1 : numel(net.layers{n}.a)
sa = size(net.layers{n}.a{j});
net.fv = [net.fv; reshape(net.layers{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
function X = sigm(P)
X = 1./(1+exp(-P));
end
function net = cnnbp(net, y)
n = numel(net.layers);
% error
net.e = net.o - y;
% loss function
net.loss = 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(net.layers{n}.type, 'c') % only conv layers has sigm function
net.fvd = net.fvd .* (net.fv .* (1 - net.fv));
end
% reshape feature vector deltas into output map style
sa = size(net.layers{n}.a{1});
fvnum = sa(1) * sa(2);
for j = 1 : numel(net.layers{n}.a)
net.layers{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(net.layers{l}.type, 'c')
for j = 1 : numel(net.layers{l}.a)
net.layers{l}.d{j} = net.layers{l}.a{j} .* (1 - net.layers{l}.a{j}) .* (expand(net.layers{l + 1}.d{j}, [net.layers{l + 1}.scale net.layers{l + 1}.scale 1]) / net.layers{l + 1}.scale ^ 2);
end
elseif strcmp(net.layers{l}.type, 's')
for i = 1 : numel(net.layers{l}.a)
z = zeros(size(net.layers{l}.a{1}));
for j = 1 : numel(net.layers{l + 1}.a)
z = z + convn(net.layers{l + 1}.d{j}, rot180(net.layers{l + 1}.k{i}{j}), 'full');
end
net.layers{l}.d{i} = z;
end
end
end
%% calc gradients
for l = 2 : n
if strcmp(net.layers{l}.type, 'c')
for j = 1 : numel(net.layers{l}.a)
for i = 1 : numel(net.layers{l - 1}.a)
net.layers{l}.dk{i}{j} = convn(flipall(net.layers{l - 1}.a{i}), net.layers{l}.d{j}, 'valid') / size(net.layers{l}.d{j}, 3);
end
net.layers{l}.db{j} = sum(net.layers{l}.d{j}(:)) / size(net.layers{l}.d{j}, 3);
end
end
end
net.dffW = net.od * (net.fv)' / size(net.od, 2);
net.dffb = mean(net.od, 2);
end
function X = rot180(X)
X = flip(flip(X, 1), 2);
end
function B = expand(A, S)
SA = size(A); % Get the size (and number of dimensions) of input.
if length(SA) ~= length(S)
error('Length of size vector must equal ndims(A). See help.')
elseif any(S ~= floor(S))
error('The size vector must contain integers only. See help.')
end
T = cell(length(SA), 1);
for ii = length(SA) : -1 : 1
H = zeros(SA(ii) * S(ii), 1); % One index vector into A for each dim.
H(1 : S(ii) : SA(ii) * S(ii)) = 1; % Put ones in correct places.
T{ii} = cumsum(H); % Cumsumming creates the correct order.
end
B = A(T{:}); % Feed the indices into A.
end
function X=flipall(X)
for i=1:ndims(X)
X = flip(X,i);
end
end
function net = cnngrads(net, opts)
for l = 2 : numel(net.layers)
if strcmp(net.layers{l}.type, 'c')
for j = 1 : numel(net.layers{l}.a)
for ii = 1 : numel(net.layers{l - 1}.a)
net.layers{l}.k{ii}{j} = net.layers{l}.k{ii}{j} - opts.alpha * net.layers{l}.dk{ii}{j};
end
net.layers{l}.b{j} = net.layers{l}.b{j} - opts.alpha * net.layers{l}.db{j};
end
end
end
net.ffW = net.ffW - opts.alpha * net.dffW;
net.ffb = net.ffb - opts.alpha * net.dffb;
end
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
计算机视觉-CNN学习MATLAB源码 卷积神经网络(CNN 或 ConvNet)是一种深度学习网络架构,它直接从数据中学习,不需要手动提取特征。 CNN 特别适合在图像中寻找模式以识别物品、人脸和场景。这类网络也能很好地对一些非图像数据进行分类,如音频、时间序列和信号数据。 需要目标识别和计算机视觉的应用(如自动驾驶汽车和人脸识别应用)高度依赖 CNN。 卷积神经网络CNN的结构一般包含这几个层: (1)输入层:用于数据的输入 (2)卷积层:使用卷积核进行特征提取和特征映射 (3)激励层:由于卷积也是一种线性运算,因此需要增加非线性映射 (4)池化层:进行下采样,对特征图稀疏处理,减少数据运算量。 (5)全连接层:通常在CNN的尾部进行重新拟合,减少特征信息的损失 CNN的三个特点: (1)局部连接:这个是最容易想到的,每个神经元不再和上一层的所有神经元相连,而只和一小部分神经元相连。这样就减少了很多参数 (2)权值共享:一组连接可以共享同一个权重,而不是每个连接有一个不同的权重,这样又减少了很多参数。 (3)下采样:可以使用Pooling来减少每层的样本数
资源详情
资源评论
资源推荐
收起资源包目录
16、CNN学习.zip (4个子文件)
16、CNN学习
cnnsetup.m 2KB
cnntrain.m 6KB
CNNLearning.m 1KB
cnntest.m 2KB
共 4 条
- 1
mozun2020
- 粉丝: 1w+
- 资源: 131
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0