diff options
author | Clement Farabet <clement.farabet@gmail.com> | 2011-09-14 23:01:17 +0400 |
---|---|---|
committer | Clement Farabet <clement.farabet@gmail.com> | 2011-09-14 23:01:17 +0400 |
commit | f1b9c1123ec4e5633b0c5654930a8f3733f0e4ac (patch) | |
tree | 1298cbd78d378e5f8e836fb7671a9e81cf3a6068 | |
parent | 937f52bdd070f59db90720c5993b28abd44f6aac (diff) |
Got rid of SpatialMaxPooling
-rw-r--r-- | SpatialMaxPooling.lua | 89 | ||||
-rw-r--r-- | generic/SpatialMaxPooling.c | 161 | ||||
-rw-r--r-- | init.c | 2 | ||||
-rw-r--r-- | init.lua | 1 |
4 files changed, 0 insertions, 253 deletions
diff --git a/SpatialMaxPooling.lua b/SpatialMaxPooling.lua deleted file mode 100644 index d331a10..0000000 --- a/SpatialMaxPooling.lua +++ /dev/null @@ -1,89 +0,0 @@ -local SpatialMaxPooling, parent = torch.class('nn.SpatialMaxPooling', 'nn.OmpModule') - -local help_desc = -[[Applies a 2D sub-sampling over an input image composed of -several input planes. The input tensor in forward(input) is -expected to be a 3D tensor (nInputPlane x height x width). -The number of output planes will be the same as nInputPlane. - -Compared to the nn.SpatialSubSampling module, a max operator is -used to pool values in the kHxkW input neighborhood. - -Note that depending of the size of your kernel, several -(of the last) columns or rows of the input image might be lost. -It is up to the user to add proper padding in images. - -If the input image is a 3D tensor nInputPlane x height x width, -the output image size will be nInputPlane x oheight x owidth, where - -owidth = (width - kW) / dW + 1 -oheight = (height - kH) / dH + 1 . - -The parameters of the sub-sampling can be found in self.weight -(Tensor of size nInputPlane) and self.bias (Tensor of size nInputPlane). -The corresponding gradients can be found in self.gradWeight and self.gradBias. - -The output value of the layer can be precisely described as: - -output[i][j][k] = bias[k] - + weight[k] sum_{s=1}^kW sum_{t=1}^kH input[dW*(i-1)+s][dH*(j-1)+t][k] ]] - -function SpatialMaxPooling:__init(kW, kH, dW, dH) - parent.__init(self) - - -- usage - if not kW or not kH then - error(xlua.usage('nn.SpatialMaxPooling', help_desc, nil, - {type='number', help='kernel width', req=true}, - {type='number', help='kernel height', req=true}, - {type='number', help='stride width [default = kernel width]'}, - {type='number', help='stride height [default = kernel height]'})) - end - - dW = dW or kW - dH = dH or kH - - self.kW = kW - self.kH = kH - self.dW = dW - self.dH = dH - - self.indices = torch.Tensor() -end - -function SpatialMaxPooling:forward(input) - input.nn.SpatialMaxPooling_forward(self, input) - return self.output -end - -function SpatialMaxPooling:backward(input, gradOutput) - input.nn.SpatialMaxPooling_backward(self, input, gradOutput) - return self.gradInput -end - -function SpatialMaxPooling:empty() - self.gradInput:resize() - self.gradInput:storage():resize(0) - self.output:resize() - self.output:storage():resize(0) - self.indices:resize() - self.indices:storage():resize(0) -end - -function SpatialMaxPooling:write(file) - parent.write(self, file) - file:writeInt(self.kW) - file:writeInt(self.kH) - file:writeInt(self.dW) - file:writeInt(self.dH) - file:writeObject(self.indices) -end - -function SpatialMaxPooling:read(file) - parent.read(self, file) - self.kW = file:readInt() - self.kH = file:readInt() - self.dW = file:readInt() - self.dH = file:readInt() - self.indices = file:readObject() -end diff --git a/generic/SpatialMaxPooling.c b/generic/SpatialMaxPooling.c deleted file mode 100644 index 7a95bf1..0000000 --- a/generic/SpatialMaxPooling.c +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef TH_GENERIC_FILE -#define TH_GENERIC_FILE "generic/SpatialMaxPooling.c" -#else - -static int nn_(SpatialMaxPooling_forward)(lua_State *L) -{ - THTensor *input = luaT_checkudata(L, 2, torch_(Tensor_id)); - int kW = luaT_getfieldcheckint(L, 1, "kW"); - int kH = luaT_getfieldcheckint(L, 1, "kH"); - int dW = luaT_getfieldcheckint(L, 1, "dW"); - int dH = luaT_getfieldcheckint(L, 1, "dH"); - THTensor *indices = luaT_getfieldcheckudata(L, 1, "indices", torch_(Tensor_id)); - THTensor *output = luaT_getfieldcheckudata(L, 1, "output", torch_(Tensor_id)); - int nThread = luaT_getfieldcheckint(L, 1, "nThread"); - - luaL_argcheck(L, input->nDimension == 3, 2, "3D tensor expected"); - luaL_argcheck(L, input->size[2] >= kW && input->size[1] >= kH, 2, "input image smaller than kernel size"); - - // sizes - long nslices = input->size[0]; - long iheight = input->size[1]; - long iwidth = input->size[2]; - long oheight = (iheight - kH) / dH + 1; - long owidth = (iwidth - kW) / dW + 1; - - // get contiguous input - input = THTensor_(newContiguous)(input); - - // resize output - THTensor_(resize3d)(output, nslices, oheight, owidth); - - // indices will contain i,j locatyions for each output point - THTensor_(resize4d)(indices, 2, nslices, oheight, owidth); - - // get raw pointers - real *input_data = THTensor_(data)(input); - real *output_data = THTensor_(data)(output); - real *indices_data = THTensor_(data)(indices); - - // compute max pooling for each input slice - long k; - omp_set_num_threads(nThread); - #pragma omp parallel for private(k) - for (k = 0; k < nslices; k++) { - // pointers to slices - real *input_p = input_data + k*iwidth*iheight; - real *output_p = output_data + k*owidth*oheight; - real *indx_p = indices_data + k*owidth*oheight; - real *indy_p = indices_data + (k+nslices)*owidth*oheight; - - // loop over output - int i,j; - for(i = 0; i < oheight; i++) { - for(j = 0; j < owidth; j++) { - // local pointers - real *ip = input_p + i*iwidth*dH + j*dW; - real *op = output_p + i*owidth + j; - real *indxp = indx_p + i*owidth + j; - real *indyp = indy_p + i*owidth + j; - - // compute local max: - long maxindex = -1; - real maxval = -THInf; - long tcntr = 0; - int x,y; - for(y = 0; y < kH; y++) { - for(x = 0; x < kW; x++) { - real val = *(ip + y*iwidth + x); - if (val > maxval) { - maxval = val; - maxindex = tcntr; - } - tcntr++; - } - } - - // set output to local max - *op = maxval; - - // store location of max (x,y) - *indxp = (int)(maxindex / dW)+1; - *indyp = (maxindex % dW) +1; - } - } - } - - // cleanup - THTensor_(free)(input); - - return 1; -} - -static int nn_(SpatialMaxPooling_backward)(lua_State *L) -{ - THTensor *input = luaT_checkudata(L, 2, torch_(Tensor_id)); - THTensor *gradOutput = luaT_checkudata(L, 3, torch_(Tensor_id)); - int kW = luaT_getfieldcheckint(L, 1, "kW"); - int kH = luaT_getfieldcheckint(L, 1, "kH"); - int dW = luaT_getfieldcheckint(L, 1, "dW"); - int dH = luaT_getfieldcheckint(L, 1, "dH"); - - THTensor *indices = luaT_getfieldcheckudata(L, 1, "indices", torch_(Tensor_id)); - THTensor *gradInput = luaT_getfieldcheckudata(L, 1, "gradInput", torch_(Tensor_id)); - - THTensor *gradOutputPlane, *gradInputPlane, *unfoldedGradInputPlane, *gradLocalInput; - int k,i,j; - - THTensor_(resizeAs)(gradInput, input); - THTensor_(zero)(gradInput); - - gradInputPlane = THTensor_(new)(); - gradOutputPlane = THTensor_(new)(); - gradLocalInput = THTensor_(new)(); - unfoldedGradInputPlane = THTensor_(new)(); - - for (k = 0; k < input->size[0]; k++) - { - /* get input and output plane */ - THTensor_(select)(gradOutputPlane, gradOutput, 0, k); - THTensor_(select)(gradInputPlane, gradInput, 0, k); - - /* Unfold input to get each local window */ - THTensor_(unfold)(unfoldedGradInputPlane, gradInputPlane, 0, kH, dH); - THTensor_(unfold)(unfoldedGradInputPlane, NULL, 1, kW, dW); - - /* Calculate max points */ - for(i = 0; i < gradOutputPlane->size[0]; i++) { - for(j = 0; j < gradOutputPlane->size[1]; j++) { - THTensor_(select)(gradLocalInput, unfoldedGradInputPlane,0,i); - THTensor_(select)(gradLocalInput, NULL, 0,j); - long maxi = THTensor_(get4d)(indices,0,k,i,j)-1; - long maxj = THTensor_(get4d)(indices,1,k,i,j)-1; - double gi = THTensor_(get2d)(gradLocalInput,maxi,maxj)+THTensor_(get2d)(gradOutputPlane,i,j); - THTensor_(set2d)(gradLocalInput,maxi,maxj,gi); - } - } - } - - /* Cleanup */ - THTensor_(free)(gradInputPlane); - THTensor_(free)(gradOutputPlane); - THTensor_(free)(unfoldedGradInputPlane); - THTensor_(free)(gradLocalInput); - - return 1; -} - -static const struct luaL_Reg nn_(SpatialMaxPooling__) [] = { - {"SpatialMaxPooling_forward", nn_(SpatialMaxPooling_forward)}, - {"SpatialMaxPooling_backward", nn_(SpatialMaxPooling_backward)}, - {NULL, NULL} -}; - -static void nn_(SpatialMaxPooling_init)(lua_State *L) -{ - luaT_pushmetaclass(L, torch_(Tensor_id)); - luaT_registeratname(L, nn_(SpatialMaxPooling__), "nn"); - lua_pop(L,1); -} - -#endif @@ -57,7 +57,6 @@ DLL_EXPORT int luaopen_libnnx(lua_State *L) nn_FloatHardShrink_init(L); nn_FloatAbs_init(L); nn_FloatThreshold_init(L); - nn_FloatSpatialMaxPooling_init(L); nn_FloatSpatialUpSampling_init(L); nn_FloatSpatialReSampling_init(L); nn_FloatSparseCriterion_init(L); @@ -71,7 +70,6 @@ DLL_EXPORT int luaopen_libnnx(lua_State *L) nn_DoubleHardShrink_init(L); nn_DoubleAbs_init(L); nn_DoubleThreshold_init(L); - nn_DoubleSpatialMaxPooling_init(L); nn_DoubleSpatialUpSampling_init(L); nn_DoubleSpatialReSampling_init(L); nn_DoubleSparseCriterion_init(L); @@ -79,7 +79,6 @@ end -- spatial (images) operators: torch.include('nnx', 'SpatialLinear.lua') torch.include('nnx', 'SpatialClassifier.lua') -torch.include('nnx', 'SpatialMaxPooling.lua') torch.include('nnx', 'SpatialPadding.lua') torch.include('nnx', 'SpatialNormalization.lua') torch.include('nnx', 'SpatialUpSampling.lua') |