diff --git a/.travis.yml b/.travis.yml index 45ed2a2..569a873 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ before_script: - sudo apt-add-repository ppa:octave/stable --yes - sudo apt-get update -y - - sudo apt-get install octave -y + - sudo apt-get install octave --force-yes - sudo apt-get install liboctave-dev -y script: - sh -c "octave tests/runalltests.m" diff --git a/CNN/cnnbp.m b/CNN/cnnbp.m index 09028a2..c9cd86c 100644 --- a/CNN/cnnbp.m +++ b/CNN/cnnbp.m @@ -23,7 +23,9 @@ 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); + xscale = net.layers{l + 1}.xscale; + yscale = net.layers{l + 1}.yscale; + net.layers{l}.d{j} = net.layers{l}.a{j} .* (1 - net.layers{l}.a{j}) .* (expand(net.layers{l + 1}.d{j}, [xscale yscale 1]) / (xscale*yscale)); end elseif strcmp(net.layers{l}.type, 's') for i = 1 : numel(net.layers{l}.a) diff --git a/CNN/cnnff.m b/CNN/cnnff.m index b9b6bc5..1db260d 100644 --- a/CNN/cnnff.m +++ b/CNN/cnnff.m @@ -21,8 +21,8 @@ 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, :); + z = convn(net.layers{l - 1}.a{j}, net.layers{l}.meanFilter, 'valid'); + net.layers{l}.a{j} = z(1 : net.layers{l}.xscale : end, 1 : net.layers{l}.yscale : end, :); end end end diff --git a/CNN/cnnsetup.m b/CNN/cnnsetup.m index 6d6b002..2169653 100644 --- a/CNN/cnnsetup.m +++ b/CNN/cnnsetup.m @@ -1,14 +1,17 @@ function net = cnnsetup(net, x, y) inputmaps = 1; mapsize = size(squeeze(x(:, :, 1))); - - for l = 1 : numel(net.layers) % layer + + for l = 1 : numel(net.layers) % layer if strcmp(net.layers{l}.type, 's') - mapsize = mapsize / net.layers{l}.scale; + mapsize = [mapsize(1)/net.layers{l}.xscale, mapsize(2)/net.layers{l}.yscale]; assert(all(floor(mapsize)==mapsize), ['Layer ' num2str(l) ' size must be integer. Actual: ' num2str(mapsize)]); for j = 1 : inputmaps net.layers{l}.b{j} = 0; end + %these are the subsampling filters for each layer + net.layers{l}.meanFilter = ones(net.layers{l}.xscale, net.layers{l}.yscale) / (net.layers{l}.xscale*net.layers{l}.yscale); + end if strcmp(net.layers{l}.type, 'c') mapsize = mapsize - net.layers{l}.kernelsize + 1; diff --git a/tests/test_cnn_gradients_are_numerically_correct.m b/tests/test_cnn_gradients_are_numerically_correct.m index 2391ae1..4cb06f9 100644 --- a/tests/test_cnn_gradients_are_numerically_correct.m +++ b/tests/test_cnn_gradients_are_numerically_correct.m @@ -1,12 +1,29 @@ function test_cnn_gradients_are_numerically_correct +%squared average kernels batch_x = rand(28,28,5); batch_y = rand(10,5); cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 2, 'kernelsize', 5) %convolution layer - struct('type', 's', 'scale', 2) %sub sampling layer + struct('type', 's', 'xscale', 2, 'yscale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 2, 'kernelsize', 5) %convolution layer - struct('type', 's', 'scale', 2) %subsampling layer + struct('type', 's', 'xscale', 2, 'yscale', 2) %subsampling layer +}; +cnn = cnnsetup(cnn, batch_x, batch_y); + +cnn = cnnff(cnn, batch_x); +cnn = cnnbp(cnn, batch_y); +cnnnumgradcheck(cnn, batch_x, batch_y); + +%non squared average kernels +batch_x = rand(28,600,5); +batch_y = rand(10,5); +cnn.layers = { + struct('type', 'i') %input layer + struct('type', 'c', 'outputmaps', 2, 'kernelsize', 5) %convolution layer + struct('type', 's', 'xscale', 2, 'yscale', 2) %sub sampling layer + struct('type', 'c', 'outputmaps', 2, 'kernelsize', 5) %convolution layer + struct('type', 's', 'xscale', 2, 'yscale', 2) %subsampling layer }; cnn = cnnsetup(cnn, batch_x, batch_y); diff --git a/tests/test_example_CNN.m b/tests/test_example_CNN.m index dbc6b0c..8183ddd 100644 --- a/tests/test_example_CNN.m +++ b/tests/test_example_CNN.m @@ -15,12 +15,11 @@ cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer - struct('type', 's', 'scale', 2) %sub sampling layer + struct('type', 's', 'xscale', 2, 'yscale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer - struct('type', 's', 'scale', 2) %subsampling layer + struct('type', 's', 'xscale', 2, 'yscale', 2) %subsampling layer }; - opts.alpha = 1; opts.batchsize = 200; opts.numepochs = 7;