【ufldl tutorial】Convolution and Pooling
卷积的实现:
对于每幅图像,每个filter,首先从W中取出对应的filter:
filter = squeeze(W(:,:,filterNum));
接下来startercode里面将filter旋转90度并且取出image:
% Flip the feature matrix because of the definition of convolution, as explained later filter = rot90(squeeze(filter),2); % Obtain the image im = squeeze(images(:, :, imageNum));
然后进行卷积,注意这里要用conv2的valid模式,因为这里的卷积不对图像边界之外的像素进行操作:
%%% YOUR CODE HERE %%% convolvedImage = conv2(im,filter,'valid');
最后加上偏置b并且作用一个sigmoid函数,最终得到的featuremap放到convolvedFeatures里面:
%%% YOUR CODE HERE %%% convolvedImage = bsxfun(@plus,convolvedImage,b(filterNum)); convolvedImage = 1 ./ (1+exp(-convolvedImage)); convolvedFeatures(:, :, filterNum, imageNum) = convolvedImage;
完整的实现参见我的github
Pooling的实现:
对于每幅图像的每一个卷积操作得到的featuremap,首先从convolvedFeatures中取出对应的featuremap:
featuremap = squeeze(convolvedFeatures(:,:,featureNum,imageNum));
这里的pooling是通过卷积实现的,如下图所示:
上图第一个正方形表示4*4的featuremap,假设poolDim的大小是2*2,用一个(poolDim*poolDim)的filter对图像进行卷积操作,得到第二个正方形;最后进行步长为poolDim的采样,就得到最后pooling之后的featuremap——第三个正方形。注意这样使用mean pooling,所以filter设置成一个(poolDim*poolDim),值为1/(poolDim*poolDim)的正方形矩阵就可以达到这个目的了,代码如下:
%%% YOUR CODE HERE %%% for imageNum = 1:numImages for featureNum = 1:numFilters featuremap = squeeze(convolvedFeatures(:,:,featureNum,imageNum)); pooledFeaturemap = conv2(featuremap,ones(poolDim)/(poolDim^2),'valid'); pooledFeatures(:,:,featureNum,imageNum) = pooledFeaturemap(1:poolDim:end,1:poolDim:end); end end
两个for中第一行代码得到featuremap,第二行进行卷积求平均值,第三行进行采样并把结果放到pooledFeatures中。
完整代码参见我的github。