function just_one_CNN()
load mnist_uint8;
train_x=double(reshape(train_x‘,28,28,60000))/255;
test_x=double(reshape(test_x‘,28,28,10000))/255;
train_y=double(train_y‘)/255;
test_y=double(test_y‘)/255;
cnn.layers={struct(‘type‘,‘i‘);
struct(‘type‘,‘c‘,‘outputmaps‘,6,‘kernelsize‘,5);
struct(‘type‘,‘s‘,‘scale‘,2);
struct(‘type‘,‘c‘,‘outputmaps‘,16,‘kernelsize‘,5);
struct(‘type‘,‘s‘,‘scale‘,2);};
cnn=cnnsetup(cnn,train_x,train_y);
opts.alpha=1;
opts.batchsizes=2;
opts.numepoches=2;
cnn=cnntrain(cnn,train_x,train_y,opts);
preimage=predict();
cnntest(cnn,preimage);
end
function net=cnnsetup(net,x,y)
inputmaps=1;
mapsize=size(x(:,:,1));
for l=1:numel(net.layers)
if strcmp(net.layers{l}.type,‘s‘)
mapsize=mapsize/net.layers{l}.scale;
for j=1:inputmaps
net.layers{l}.b{j}=0;
end
end
if strcmp(net.layers{l}.type,‘c‘)
mapsize=mapsize-net.layers{l}.kernelsize+1;
fan_out=net.layers{l}.outputmaps*net.layers{l}.kernelsize^2;
for j=1:net.layers{l}.outputmaps
fan_in=inputmaps*net.layers{l}.kernelsize^2;
for i=1:inputmaps
net.layers{l}.k{i}{j}=(rand(net.layers{l}.kernelsize)- 0.5) * 2 * sqrt(6 / (fan_in + fan_out));
end
net.layers{l}.b{j}=0;
end
inputmaps=net.layers{l}.outputmaps;
end
end
fvnum=prod(mapsize)*inputmaps;
onum=size(y,1);
net.ffb=zeros(onum,1);
net.ffW=(rand(onum, fvnum) - 0.5) * 2 * sqrt(6 / (onum + fvnum));
end
function net=cnntrain(net,x,y,opts)
m=size(x,3);
numbatchs=m/opts.batchsizes;
if rem(numbatchs, 1) ~= 0
error(‘numbatches not integer‘);
end
net.rL=[];
for i=1:opts.numepoches
tic;
kk=randperm(m);
for l=1:numbatchs
batch_x=x(:,:,kk((l-1)*opts.batchsizes+1:l*opts.batchsizes));
batch_y=y(:,kk((l-1)*opts.batchsizes+1:l*opts.batchsizes));
net=cnnff(net,batch_x);
net=cnnbp(net,batch_y);
net = cnnapplygrads(net, opts);
if isempty(net.rL)
net.rL(1) = net.L;
end
net.rL(end + 1) = 0.99 * net.rL(end) + 0.01 * net.L;
end
toc
end
end
function net=cnnff(net,x)
n=numel(net.layers);
net.layers{1}.a{1}=x;
inputmaps=1;
for l=2:n
if strcmp(net.layers{l}.type,‘c‘)
for j=1:net.layers{l}.outputmaps
z=zeros(size(net.layers{l-1}.a{1})-[net.layers{l}.kernelsize-1 net.layers{l}.kernelsize-1 0]);
for i=1:inputmaps
z=z+convn(net.layers{l-1}.a{i},net.layers{l}.k{i}{j},‘valid‘);
end
net.layers{l}.a{j}=sigm(z+net.layers{l}.b{j});
end
inputmaps=net.layers{l}.outputmaps;
elseif strcmp(net.layers{l}.type,‘s‘)
for j=1:inputmaps
z=convn(net.layers{l-1}.a{j},ones(net.layers{l}.scale)/(net.layers{l}.scale^2),‘valid‘);
net.layers{l}.a{j} = z(1 : net.layers{l}.scale : end, 1 : net.layers{l}.scale : end, :);
end
end
end
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
net.o = sigm(net.ffW * net.fv + repmat(net.ffb, 1, size(net.fv, 2)));
end
function [out]=sigm(in)
out=1./(1+exp(-in));
end
function net=cnnbp(net,y)
n=numel(net.layers);
net.e=net.o-y;
net.L=1/2*sum(net.e(:).^2)/size(net.e,2);
net.od=net.e.*(net.o.*(1-net.o));
net.fvd=(net.ffW‘*net.od);
if strcmp(net.layers{n}.type,‘c‘)
net.fvd=net.fv.*(netfv.*(1-net.fv));
end
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
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 = flipdim(flipdim(X, 1), 2);
end
function net = cnnapplygrads(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
end
net.layers{l}.b{j} = net.layers{l}.b{j} - opts.alpha * net.layers{l}.db{j};
end
end
net.ffW = net.ffW - opts.alpha * net.dffW;
net.ffb = net.ffb - opts.alpha * net.dffb;
end
function cnntest(net, x)
net = cnnff(net, x);
[~, h] = max(net.o);
disp(‘the image data is‘);
disp(h-1);
end
function [guige]=predict()
ff=imread(‘seven.png‘);
tgray=rgb2gray(ff);
tgray(1:7,:)=[];
tgray(end-3:end,:)=[];
tgray(:,1)=[];
gg=imread(‘eight.png‘);
eg=rgb2gray(gg);
eg(1:5,:)=[];
eg(end-4:end,:)=[];
eg(:,1)=[];
eg(:,end)=[];
guige=[tgray;eg];
guige=double(reshape(guige‘,28,28,2))/255;
end
function B = expand(A, S)
if nargin < 2
error(‘Size vector must be provided. See help.‘);
end
SA = size(A);
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);
H(1 : S(ii) : SA(ii) * S(ii)) = 1;
T{ii} = cumsum(H);
end
B = A(T{:});
end
function X=flipall(X)
for i=1:ndims(X)
X = flipdim(X,i);
end
end
上面代码只需要放在一个just_one_CNN函数里面就能运行。
可以任意拓展网络的层数,只需更新相应的参数就可以
对下面两张rgb图片能够正确识别,但是要进行处理,要将图片转为灰度图,分割成大小为28x28的图片,在展开成两行向量

原文:http://www.cnblogs.com/semen/p/7103829.html