(vl::Context& context,
67 | float* derData,
68 | float const* derSubsampled,
69 | size_t height, size_t width, size_t depth,
70 | size_t strideY, size_t strideX,
71 | size_t padTop, size_t padBottom, size_t padLeft, size_t padRight) ;
72 | #endif
73 |
74 | } }
75 |
76 | #endif /* defined(VL_NNSUBSAMPLE_H) */
77 |
--------------------------------------------------------------------------------
/doc/site/docs/index.md:
--------------------------------------------------------------------------------
1 | # MatConvNet: CNNs for MATLAB
2 |
3 | **MatConvNet** is a MATLAB toolbox implementing *Convolutional Neural
4 | Networks* (CNNs) for computer vision applications. It is simple,
5 | efficient, and can run and learn state-of-the-art CNNs. Several
6 | example CNNs are included to classify and encode images.
7 |
8 | **Citing.** If you use MatConvNet in your work, please cite:
9 | "MatConvNet - Convolutional Neural Networks for MATLAB", A. Vedaldi
10 | and K. Lenc, *Proc. of the ACM Int. Conf. on Multimedia*, 2015. [BibTex]
13 |
14 |
15 | @inproceedings{vedaldi15matconvnet,
16 | author = {A. Vedaldi and K. Lenc},
17 | title = {MatConvNet -- Convolutional Neural Networks for MATLAB},
18 | book = {Proceeding of the {ACM} Int. Conf. on Multimedia}
19 | year = {2015},
20 | }
21 |
22 |
23 | > **New:** 1.0-beta16 adds VGG-Face as a [pretrained model](pretrained.md).
24 | >
25 | > **New:** Fully-Convolutional Networks (FCN) training and evaluation
26 | > code is available
27 | > [here](https://github.com/vlfeat/matconvnet-fcn).
28 | >
29 | > **New:** 1.0-beta15 adds a few new layers to DagNN to support the
30 | > **Fully-Convolutonal Networks** (FCN) for image
31 | > segmentation. Pretrained models are
32 | > [also available here](pretrained.md). Batch normalization
33 | > ([`vl_nnbnorm`](mfiles/vl_nnbnorm.md)) has also been improved adding
34 | > features that will make it easier to remove the layer after training
35 | > a model.
36 | >
37 | > **New:** 1.0-beta14 adds a new object-oriented
38 | > [network wrapper `DagNN`](wrappers.md) supporting arbitrary network
39 | > topologies. This release also adds GoogLeNet as a pre-trained model,
40 | > new building blocks such as [`vl_nnconcat`](mfiles/vl_nnconcat.md),
41 | > a rewritten loss function block [`vl_nnloss`](mfiles/vl_nnloss.md),
42 | > better documentation, and bugfixes. A new **realtime demo** (see
43 | > `examples/cnn_imagenet_camdemo.m`) using GoogLeNet, VGG-VD, or any
44 | > other similar network.
45 | >
46 | > **New:** MatConvNet used in planetary science research by the
47 | > University of Arizona (see the
48 | > [NVIDIA blog post](http://devblogs.nvidia.com/parallelforall/deep-learning-image-understanding-planetary-science/)).
49 |
50 | * **Obtaining MatConvNet**
51 | - Tarball for [version 1.0-beta16](download/matconvnet-1.0-beta16.tar.gz)
52 | - [GIT repository](http://www.github.com/vlfeat/matconvnet.git)
53 |
54 | * **Documentation**
55 | - [PDF manual](matconvnet-manual.pdf)
56 | - [MATLAB functions](functions.md)
57 | - [FAQ](faq.md)
58 |
59 | * **Getting started**
60 | - [Quick start guide](quick.md)
61 | - [Installation instructions](install.md)
62 | - [Using pre-trained models](pretrained.md): VGG-VD, GoogLeNet, FCN, ...
63 | - [Training your own models](training.md)
64 | - [CNN wrappers: linear chains or DAGs](wrappers.md)
65 | - [Working with GPU accelerated code](gpu.md)
66 | - [Tutorial](http://www.robots.ox.ac.uk/~vgg/practicals/cnn/index.html),
67 | [slides](http://www.robots.ox.ac.uk/~vedaldi/assets/teach/2015/vedaldi15aims-bigdata-lecture-4-deep-learning-handout.pdf)
68 |
69 | * **Other information**
70 | - [Changes](about/#changes)
71 | - [Developing the library](developers.md)
72 |
73 |
--------------------------------------------------------------------------------
/matlab/xtest/suite/nnconvt.m:
--------------------------------------------------------------------------------
1 | classdef nnconvt < nntest
2 | properties (TestParameter)
3 | depth = {1 2 3}
4 | numImages = {1 2 3 4}
5 | numFilters = {1 2 3}
6 | upx = {1 2 3}
7 | upy = {1 2 3}
8 | padx1 = {1 2 3}
9 | padx2 = {1 2 3}
10 | pady1 = {1 2 3}
11 | pady2 = {1 2 3}
12 | up = {1 2}
13 | fsx = {1 2}
14 | crop = {1 2 3 4 5 6 7 8}
15 | numGroups = {1 2 3}
16 | end
17 |
18 | methods (Test)
19 | function basic(test, depth, numImages, numFilters)
20 | m = depth ;
21 | n = numImages ;
22 | k = numFilters;
23 | x = test.randn(10,12,m,n,'single') ;
24 | f = test.randn(3,4,k,m,'single') ;
25 | b = test.randn(1,k,'single') ;
26 | y = vl_nnconvt(x,f,b) ;
27 | dzdy = test.randn(size(y),'single') ;
28 | [dzdx,dzdf,dzdb] = vl_nnconvt(x,f,b,dzdy) ;
29 | test.der(@(x) vl_nnconvt(x,f,b), x, dzdy, dzdx, test.range * 1e-2) ;
30 | test.der(@(f) vl_nnconvt(x,f,b), f, dzdy, dzdf, test.range * 1e-2) ;
31 | test.der(@(b) vl_nnconvt(x,f,b), b, dzdy, dzdb, test.range) ;
32 | end
33 |
34 | function upsample_crop(test,upx,upy,padx1,pady1,padx2,pady2)
35 | m = 3 ; n = 2 ; k = 3;
36 | opts = {'upsample',[upy upx],'crop',[pady1 pady2 padx1 padx2]} ;
37 | x = test.randn(5,6,m,n,'single') ;
38 | f = test.randn(3,4,k,m,'single') ;
39 | b = test.randn(1,k,'single') ;
40 | y = vl_nnconvt(x,f,b,opts{:}) ;
41 | dzdy = test.randn(size(y),'single') ;
42 | [dzdx,dzdf,dzdb] = vl_nnconvt(x,f,b,dzdy,opts{:}) ;
43 | test.der(@(x) vl_nnconvt(x,f,b,opts{:}), x, dzdy, dzdx, test.range * 1e-2) ;
44 | test.der(@(f) vl_nnconvt(x,f,b,opts{:}), f, dzdy, dzdf, test.range * 1e-2) ;
45 | test.der(@(b) vl_nnconvt(x,f,b,opts{:}), b, dzdy, dzdb, test.range) ;
46 | end
47 |
48 | function grouped_filters(test, numGroups, depth, numFilters)
49 | ng = numGroups ;
50 | m = depth ;
51 | k = numFilters ;
52 | n = 3 ;
53 | opts = {'numgroups',ng} ;
54 | x = test.randn(10,12,m*ng,n,'single') ;
55 | f = test.randn(3,4,k,m*ng,'single') ;
56 | b = test.randn(1,k*ng,'single') ;
57 | y = vl_nnconvt(x,f,b,opts{:}) ;
58 | dzdy = test.randn(size(y),'single') ;
59 | [dzdx,dzdf,dzdb] = vl_nnconvt(x,f,b,dzdy,opts{:}) ;
60 | test.der(@(x) vl_nnconvt(x,f,b,opts{:}), x, dzdy, dzdx, test.range * 1e-2) ;
61 | test.der(@(f) vl_nnconvt(x,f,b,opts{:}), f, dzdy, dzdf, test.range * 1e-2) ;
62 | test.der(@(b) vl_nnconvt(x,f,b,opts{:}), b, dzdy, dzdb, test.range) ;
63 | end
64 |
65 | function one_one_image(test,up,fsx,crop)
66 | fsx = fsx*up ;
67 | if crop > fsx-1, return ; end
68 | m = 3 ;
69 | n = 4 ;
70 | k = 3 ;
71 | fsy = fsx * 3 ;
72 | x = test.randn(1,1,m,n,'single') ;
73 | f = test.randn(fsy,fsx,k,m,'single') ;
74 | b = test.randn(1,k,'single') ;
75 | croph = floor(crop/2) ;
76 | opts = {'crop', [croph, crop-croph, croph, crop-croph], 'upsample', [up up]} ;
77 | y = vl_nnconvt(x,f,b,opts{:}) ;
78 | dzdy = test.randn(size(y),'single') ;
79 | [dzdx,dzdf,dzdb] = vl_nnconvt(x,f,b,dzdy,opts{:}) ;
80 | test.der(@(x) vl_nnconvt(x,f,b,opts{:}), x, dzdy, dzdx, test.range * 1e-2) ;
81 | test.der(@(f) vl_nnconvt(x,f,b,opts{:}), f, dzdy, dzdf, test.range * 1e-2) ;
82 | test.der(@(b) vl_nnconvt(x,f,b,opts{:}), b, dzdy, dzdb, test.range * 1e-1) ;
83 | end
84 | end
85 | end
86 |
--------------------------------------------------------------------------------
/matlab/+dagnn/@DagNN/rebuild.m:
--------------------------------------------------------------------------------
1 | function rebuild(obj)
2 | %REBUILD Rebuild the internal data structures of a DagNN object
3 | % REBUILD(obj) rebuilds the internal data structures
4 | % of the DagNN obj. It is an helper function used internally
5 | % to update the network when layers are added or removed.
6 |
7 | varFanIn = zeros(1, numel(obj.vars)) ;
8 | varFanOut = zeros(1, numel(obj.vars)) ;
9 | parFanOut = zeros(1, numel(obj.params)) ;
10 |
11 | for l = 1:numel(obj.layers)
12 | ii = obj.getVarIndex(obj.layers(l).inputs) ;
13 | oi = obj.getVarIndex(obj.layers(l).outputs) ;
14 | pi = obj.getParamIndex(obj.layers(l).params) ;
15 | obj.layers(l).inputIndexes = ii ;
16 | obj.layers(l).outputIndexes = oi ;
17 | obj.layers(l).paramIndexes = pi ;
18 | varFanOut(ii) = varFanOut(ii) + 1 ;
19 | varFanIn(oi) = varFanIn(oi) + 1 ;
20 | parFanOut(pi) = parFanOut(pi) + 1 ;
21 | end
22 |
23 | [obj.vars.fanin] = tolist(num2cell(varFanIn)) ;
24 | [obj.vars.fanout] = tolist(num2cell(varFanOut)) ;
25 | if ~isempty(parFanOut),
26 | [obj.params.fanout] = tolist(num2cell(parFanOut)) ;
27 | end
28 |
29 | % dump unused variables
30 | keep = (varFanIn + varFanOut) > 0 ;
31 | obj.vars = obj.vars(keep) ;
32 | varRemap = cumsum(keep) ;
33 |
34 | % dump unused parameters
35 | keep = parFanOut > 0 ;
36 | obj.params = obj.params(keep) ;
37 | parRemap = cumsum(keep) ;
38 |
39 | % update the indexes to account for removed layers, variables and parameters
40 | for l = 1:numel(obj.layers)
41 | obj.layers(l).inputIndexes = varRemap(obj.layers(l).inputIndexes) ;
42 | obj.layers(l).outputIndexes = varRemap(obj.layers(l).outputIndexes) ;
43 | obj.layers(l).paramIndexes = parRemap(obj.layers(l).paramIndexes) ;
44 | obj.layers(l).block.layerIndex = l ;
45 | end
46 |
47 | % update the variable and parameter names hash maps
48 | obj.varNames = cell2struct(num2cell(1:numel(obj.vars)), {obj.vars.name}, 2) ;
49 | obj.paramNames = cell2struct(num2cell(1:numel(obj.params)), {obj.params.name}, 2) ;
50 | obj.layerNames = cell2struct(num2cell(1:numel(obj.layers)), {obj.layers.name}, 2) ;
51 |
52 | % determine the execution order again (and check for consistency)
53 | obj.executionOrder = getOrder(obj) ;
54 |
55 | % --------------------------------------------------------------------
56 | function order = getOrder(obj)
57 | % --------------------------------------------------------------------
58 | hops = cell(1, numel(obj.vars)) ;
59 | for l = 1:numel(obj.layers)
60 | for v = obj.layers(l).inputIndexes
61 | hops{v}(end+1) = l ;
62 | end
63 | end
64 | order = zeros(1, numel(obj.layers)) ;
65 | for l = 1:numel(obj.layers)
66 | if order(l) == 0
67 | order = dagSort(obj, hops, order, l) ;
68 | end
69 | end
70 | if any(order == -1)
71 | warning('The network grpah contains a cycle') ;
72 | end
73 | [~,order] = sort(order, 'descend') ;
74 |
75 | % --------------------------------------------------------------------
76 | function order = dagSort(obj, hops, order, layer)
77 | % --------------------------------------------------------------------
78 | if order(layer) > 0, return ; end
79 | order(layer) = -1 ; % mark as open
80 | n = 0 ;
81 | for o = obj.layers(layer).outputIndexes ;
82 | for child = hops{o}
83 | if order(child) == -1
84 | return ;
85 | end
86 | if order(child) == 0
87 | order = dagSort(obj, hops, order, child) ;
88 | end
89 | n = max(n, order(child)) ;
90 | end
91 | end
92 | order(layer) = n + 1 ;
93 |
94 | function varargout = tolist(x)
95 | [varargout{1:numel(x)}] = x{:} ;
96 |
--------------------------------------------------------------------------------
/matlab/vl_nnconv.m:
--------------------------------------------------------------------------------
1 | %VL_NNCONV CNN convolution.
2 | % Y = VL_NNCONV(X, F, B) computes the convolution of the image stack X
3 | % with the filter bank F and biases B. If B is the empty matrix,
4 | % then no biases are added. If F is the empty matrix, then
5 | % the function does not filter the image, but still adds the
6 | % biases as well as performing downsampling and padding as explained
7 | % below.
8 | %
9 | % X is a SINGLE array of dimension H x W x D x N where (H,W) are
10 | % the height and width of the image stack, D is the image depth
11 | % (number of feature channels) and N the number of images in the
12 | % stack.
13 | %
14 | % F is a SINGLE array of dimension FW x FH x FD x K where (FH,FW)
15 | % are the filter height and width and K the number o filters in the
16 | % bank. D is the depth of each filter and must match the depth D of
17 | % X. Alternatively, FD can *divide* the depth D; in this case,
18 | % filters are assumed to form G=D/FD *groups* of equal size (where
19 | % G must divide K). Each group of filters works on a consecutive
20 | % subset of feature channels of the input array X.
21 | %
22 | % [DZDX, DZDF, DZDB] = VL_NNCONV(X, F, B, DZDY) computes the
23 | % derivatives of the block projected onto DZDY. DZDX, DZDF, and
24 | % DZDB, and DZDY have the same dimensions as X, F, B, and Y
25 | % repsectively. In particular, if B is the empty matrix, then DZDB
26 | % is also empty.
27 | %
28 | % VL_NNCONV() implements a special `fully-connected' mode: when the
29 | % support of the filters matches exactly the support of the input
30 | % image, the code uses an optimized path for faster computation.
31 | %
32 | % VL_NNCONV(..., 'option', value, ...) takes the following options:
33 | %
34 | % `Stride`:: 1
35 | % The output stride or downsampling factor. If the value is a
36 | % scalar, then the same stride is applied to both vertical and
37 | % horizontal directions; otherwise, passing [STRIDEY STRIDEX]
38 | % allows specifying different downsampling factors for each
39 | % direction.
40 | %
41 | % `Pad`:: 0
42 | % The amount of input padding. Input images are padded with zeros
43 | % by this number of pixels before the convolution is
44 | % computed. Passing [TOP BOTTOM LEFT RIGHT] allows specifying
45 | % different padding amounts for the top, bottom, left, and right
46 | % sides respectively. Passing a single scalar applies the same
47 | % padding to all borders.
48 | %
49 | % The filter size must be not larger than the padded image, i.e.
50 | %
51 | % 1 <= FH <= H + 2*(PADTOP+PADBOTTOM),
52 | % 1 <= FW <= W + 2*(PADLEFT+PADRIGHT).
53 | %
54 | % The output a is a SINGLE array of dimension YH x YW x K x N of
55 | % N images with K challens and size:
56 | %
57 | % YH = floor((H + (PADTOP+PADBOTTOM) - FH)/STRIDEY) + 1,
58 | % YW = floor((W + (PADLEFT+PADRIGHT) - FW)/STRIDEX) + 1.
59 | %
60 | % ## CUDNN SUPPORT
61 | %
62 | % If compiled in, the function will use cuDNN convolution routines
63 | % (with the exception of asymmetric left-right or top-bottom
64 | % padding and a few corner cases such as 1x1 filters in Linux that
65 | % trigger current bugs in cuDNN). You can use the 'NoCuDNN' option
66 | % to disable cuDNN or 'cuDNN' to activate it back again (the choice
67 | % sticks until MATLAB purges the MEX files for any reason).
68 |
69 | % Copyright (C) 2014 Andrea Vedaldi and Max Jaderberg.
70 | % Copyright (C) 2015 Andrea Vedaldi.
71 | % All rights reserved.
72 | %
73 | % This file is part of the VLFeat library and is made available under
74 | % the terms of the BSD license (see the COPYING file).
75 |
--------------------------------------------------------------------------------
/matlab/src/bits/nnbias.cu:
--------------------------------------------------------------------------------
1 | // @file nnbias.cu
2 | // @brief Bias block
3 | // @author Andrea Vedaldi
4 |
5 | /*
6 | Copyright (C) 2015 Andrea Vedaldi.
7 | All rights reserved.
8 |
9 | This file is part of the VLFeat library and is made available under
10 | the terms of the BSD license (see the COPYING file).
11 | */
12 |
13 | #include "nnbias.hpp"
14 | #include "impl/nnbias_blas.hpp"
15 | #if ENABLE_CUDNN
16 | #include "impl/nnbias_cudnn.hpp"
17 | #endif
18 | #include
19 |
20 | using namespace vl ;
21 |
22 | /* ---------------------------------------------------------------- */
23 | /* Dispatchers */
24 | /* ---------------------------------------------------------------- */
25 |
26 | vl::Error
27 | vl::nnbias_forward(vl::Context& context,
28 | vl::Tensor output, double outputMult,
29 | vl::Tensor data, double dataMult,
30 | vl::Tensor biases, double biasesMult)
31 | {
32 | vl::Error status = vlSuccess ;
33 | switch (output.getMemoryType()) {
34 | default:
35 | assert(false) ;
36 | status = vl::vlErrorUnknown ;
37 | break ;
38 |
39 | case vl::CPU:
40 | status = vl::impl::nnbias_forward_blas
41 | (context, output, outputMult, data, dataMult, biases, biasesMult) ;
42 | break ;
43 |
44 | #if ENABLE_GPU
45 | case vl::GPU:
46 | #if ENABLE_CUDNN
47 | if (context.getCudaHelper().getCudnnEnabled()) {
48 | status = vl::impl::nnbias_forward_cudnn
49 | (context, output, outputMult, data, dataMult, biases, biasesMult) ;
50 | if (status == vl::vlSuccess) { return status ; }
51 | if (status != vl::vlErrorUnsupported) { goto done ; }
52 | /* this case was not supported by CUDNN -- fallback */
53 | }
54 | #endif
55 | status = vl::impl::nnbias_forward_blas
56 | (context, output, outputMult, data, dataMult, biases, biasesMult) ;
57 | break ;
58 | #endif
59 | }
60 | #if ENABLE_CUDNN
61 | done:
62 | #endif
63 | return context.passError(status, "nnbias_forward: ") ;
64 | }
65 |
66 | vl::Error
67 | vl::nnbias_backward(vl::Context& context,
68 | vl::Tensor derData, double derDataMult,
69 | vl::Tensor derBiases, double derBiasesMult,
70 | vl::Tensor derOutput, double derOutputMult)
71 | {
72 | vl::Error status = vlSuccess ;
73 | switch (derOutput.getMemoryType()) {
74 | default:
75 | assert(false) ;
76 | status = vl::vlErrorUnknown ;
77 | break ;
78 |
79 | case vl::CPU:
80 | status = vl::impl::nnbias_backward_blas
81 | (context, derData, derDataMult, derBiases, derBiasesMult, derOutput, derOutputMult) ;
82 | break ;
83 |
84 | #if ENABLE_GPU
85 | case vl::GPU:
86 | #if ENABLE_CUDNN
87 | if (context.getCudaHelper().getCudnnEnabled()) {
88 | status = vl::impl::nnbias_backward_cudnn
89 | (context, derData, derDataMult, derBiases, derBiasesMult, derOutput, derOutputMult) ;
90 | if (status == vl::vlSuccess) { return status ; }
91 | if (status != vl::vlErrorUnsupported) { goto done ; }
92 | /* this case was not supported by CUDNN -- fallback */
93 | }
94 | #endif
95 | status = vl::impl::nnbias_backward_blas
96 | (context, derData, derDataMult, derBiases, derBiasesMult, derOutput, derOutputMult) ;
97 | break ;
98 | #endif
99 | }
100 | #if ENABLE_CUDNN
101 | done:
102 | #endif
103 | return context.passError(status, "nnbias_backward: ") ;
104 | }
105 |
106 |
--------------------------------------------------------------------------------