【UFLDL】Exercise: Convolutional Neural Network

这个exercise需要完成cnn中的forward pass,cost,error和gradient的计算。需要弄清楚每一层的以上四个步骤的原理,并且要充分利用matlab的矩阵运算。大概把过程总结了一下如下图所示:

STEP 1:Implement CNN Objective

STEP 1a: Forward Propagation

Forward Propagation主要是为了计算输入图片经过神经网络后的输出,这个网络有三层:convolution->pooling->softmax(dense connected),卷积层对于每个图像用所有的模板进行卷积;pooling层对卷积层输出的feature map采样;softmax层根据pooling层输出的feature预测图像的分类结果。其中convolution和pooling操作在之前就实现过了。具体的过程可以参见上图中Forward Pass中每层的具体操作。代码如下:

%%% YOUR CODE HERE %%%
%调用之前已经实现的函数
activations = cnnConvolve(filterDim, numFilters, images, Wc, bc);%sigmoid(wx+b)
activationsPooled = cnnPool(poolDim, activations);

% Reshape activations into 2-d matrix, hiddenSize x numImages,
% for Softmax layer
%将activationsPooled从outDim*outDim*numFilters*numImages拼接成hiddenSize*numImages的大矩阵
activationsPooled = reshape(activationsPooled,[],numImages);

%% Softmax Layer
%  Forward propagate the pooled activations calculated above into a
%  standard softmax layer. For your convenience we have reshaped
%  activationPooled into a hiddenSize x numImages matrix.  Store the
%  results in probs.

% numClasses x numImages for storing probability that each image belongs to
% each class.
probs = zeros(numClasses,numImages);

%%% YOUR CODE HERE %%%
h = exp(bsxfun(@plus,Wd * activationsPooled,bd));
probs = bsxfun(@rdivide,h,sum(h,1));

STEP 1b: Calculate Cost

计算梯度下降要优化的目标函数,主要分为两部分,一部分是由于分类器输出结果和真实结果的差异引起的误差函数,另一部分是对权重w的正则约束。第一部分可以参考softmax regression中对损失函数的计算,第二部分就是对Wc和Wd的所有项求平方和。类似下面的公式,不过第一项中的J是softmax的cross entropy损失函数。最后要对第一项除以图像的总数,这是十分重要的,一开始我没有除,最后得到的算法是发散的,原因可能是第一项数值过大,直接把正则项的影响给忽略了。

代码:

%%% YOUR CODE HERE %%%
logp = log(probs);
index = sub2ind(size(logp),labels‘,1:size(probs,2));
ceCost = -sum(logp(index));
wCost = lambda/2 * (sum(Wd(:).^2)+sum(Wc(:).^2));
cost = ceCost/numImages + wCost;

STEP 1c: Backpropagation

BP算法首先要计算各层的对最终误差的贡献delta。

softmax层:这一层的误差最容易计算,只要用ground truth减去神经网络的输出probs就可以了:

output = zeros(size(probs));
output(index) = 1;
DeltaSoftmax = probs - output;

pool层:这一层首先根据公式δ= Wδl+1 * f‘(zl)(pool层没有f‘(zl)这一项)计算该层的error,此时得到一个hiddenSize*numImages的矩阵,首先利用reshape函数把error还原成一个convDim*convDim*numFilters*numImages的矩阵,在pooling操作时,pooling层一个节点的输入是conv层2*2个节点的输出(假设poolDim=2)如下图所示:

所以pooling层的这个节点要将自己的error在这2*2个节点中平均分(因为使用的是mean pooling),UFLDL上面提示了可以用kron这个函数来实现,这样如上图所示,就可以通过pooling层一个2*2的filter对应的error计算得到convolution层一个4*4的filter对应的error了。代码如下:

DeltaPool = reshape(Wd‘ * DeltaSoftmax,outputDim,outputDim,numFilters,numImages);
DeltaUnpool = zeros(convDim,convDim,numFilters,numImages);

for imNum = 1:numImages
    for FilterNum = 1:numFilters
        unpool = DeltaPool(:,:,FilterNum,imNum);
        DeltaUnpool(:,:,FilterNum,imNum) = kron(unpool,ones(poolDim))./(poolDim ^ 2);
    end
end

convolution层:还是根据公式δ= Wδl+1 * f‘(zl)来计算:

DeltaConv = DeltaUnpool .* activations .* (1 - activations);

STEP 1d: Gradient Calculation

整个cnn一共有三层:convolution->pooling->softmax(dense connected),只有convolution和softmax层有权重,分别为Wc,bc,Wd,bd。那么就要计算目标函数J对他们的倒数以便在梯度下降中更新W和b。

Wd和bd的梯度计算:

根据下面两个公式:

          

其中al-1对应pooling层的激励(输出)activitonsPooled,δl就是这一层的误差DeltaSoftmax,代码如下:

Wd_grad = (1./numImages) .* DeltaSoftmax*activationsPooled‘+lambda*Wd;
bd_grad = (1./numImages) .* sum(DeltaSoftmax,2);

Wc和bc的梯度计算:

还是根据上面两个计算梯度的公式,不过麻烦就麻烦在l-1层其实是输入的图像,所以al-1对应的是输入的图像,那么就得用for循环逐个便利图像并利用UFLDL上提供的公式计算对应梯度:

这里为了方便,先对所有DeltaConv进行旋转,然后再用for循环依次求出梯度:

%%% YOUR CODE HERE %%%
Wd_grad = (1./numImages) .* DeltaSoftmax*activationsPooled‘+lambda*Wd;
bd_grad = (1./numImages) .* sum(DeltaSoftmax,2);

bc_grad = zeros(size(bc));
Wc_grad = zeros(filterDim,filterDim,numFilters);

for filterNum = 1:numFilters
    error = DeltaConv(:,:,filterNum,:);
    bc_grad(filterNum) = (1./numImages) .* sum(error(:));
end

%旋转所有DealtaConv
for filterNum = 1:numFilters
    for imNum = 1:numImages
        error = DeltaConv(:,:,filterNum,imNum);
        DeltaConv(:,:,filterNum,imNum) = rot90(error,2);
    end
end

for filterNum = 1:numFilters
    for imNum = 1:numImages
        Wc_grad(:,:,filterNum) = Wc_grad(:,:,filterNum) + conv2(images(:,:,imNum),DeltaConv(:,:,filterNum,imNum),‘valid‘);
    end
end
Wc_grad = (1./numImages) .* Wc_grad + lambda*Wc;

Step 2: Gradient Check

当时明明我的梯度下降没法收敛,这一步居然通过了=。=

Step 3: Learn Parameters

这步比较简单,根据UFLDL对随机梯度下降的解释,在minFuncSGD中加上冲量的影响就可以了:

%%% YOUR CODE HERE %%%
        velocity = mom*velocity+alpha*grad;
        theta = theta - velocity;

Step 4: Test

运行cnnTrain,最后准确率可以达到97%+

以上就可UFLDL上cnn的实现,最重要的是弄清楚每一层在每一个过程中需要进行的操作,我都总结在文章开头的表格里面了~matlab给我一个很大的感受就是矩阵的demension match,有时候知道公式是什么样的,但是实现起来要考虑矩阵的维度,两个维度match的矩阵才能相乘或者相加,不过好处就是再不知道怎么写代码的时候可以结果维度match来写代码。而且cnn debug起来真的好困难,完全不知道是哪里出了问题=。=

完整的代码在我的github上。

参考:

【1】http://ufldl.stanford.edu/tutorial/supervised/ExerciseConvolutionalNeuralNetwork/

【2】http://blog.csdn.net/lingerlanlan/article/details/41390443

时间: 2024-08-02 23:12:01

【UFLDL】Exercise: Convolutional Neural Network的相关文章

论文阅读(Weilin Huang——【TIP2016】Text-Attentional Convolutional Neural Network for Scene Text Detection)

Weilin Huang--[TIP2015]Text-Attentional Convolutional Neural Network for Scene Text Detection) 目录 作者和相关链接 方法概括 创新点和贡献 方法细节 实验结果 问题讨论 作者和相关链接 总结与收获点 作者补充信息 参考文献 作者和相关链接 论文下载 作者: tong he, 黄伟林,乔宇,姚剑 方法概括 使用改进版的MSER(CE-MSERs,contrast-enhancement)提取候选字符区域

【论文阅读】A mixed-scale dense convolutional neural network for image analysis

A mixed-scale dense convolutional neural network for image analysis  Published in PNAS on December 26, 2017 Available at PNAS Online: https://doi.org/10.1073/pnas.1715832114 Danie ?l M. Pelt and James A. Sethian 写在前面:本文方法无法使用TensorFlow或Caffe等现有框架实现.

ufldl学习笔记与编程作业:Convolutional Neural Network(卷积神经网络)

ufldl出了新教程,感觉比之前的好,从基础讲起,系统清晰,又有编程实践. 在deep learning高质量群里面听一些前辈说,不必深究其他机器学习的算法,可以直接来学dl. 于是最近就开始搞这个了,教程加上matlab编程,就是完美啊. 新教程的地址是:http://ufldl.stanford.edu/tutorial/ 本节学习地址:http://ufldl.stanford.edu/tutorial/supervised/ConvolutionalNeuralNetwork/ 一直没更

【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

第一种做法(时间太感人): 这题我真的逗了,调了一下午,疯狂造数据,始终找不到错. 后来发现自己sb了,更新那里没有打id,直接套上u了.我.... 调了一下午啊!一下午的时光啊!本来说好中午A掉去学习第二种做法,噗 好吧,现在第一种做法是hld+seg+bst+二分,常数巨大,log^4级别,目前只会这种. 树剖后仍然用线段树维护dfs序区间,然后在每个区间建一颗平衡树,我用treap,(这题找最大啊,,,囧,并且要注意,这里的rank是比他大的数量,so,我们在二分时判断要判断一个范围,即要

人群计数:Single-Image Crowd Counting via Multi-Column Convolutional Neural Network(CVPR2016)

本博文主要是CVPR2016的<Single-Image Crowd Counting via Multi-Column Convolutional Neural Network>这篇文章的阅读笔记,以及对人群计数领域做一个简要介绍. Abstract 这篇论文开发了一种可以从一个单幅的图像中准确地估计任意人群密度和任意角度的人群数目.文章提出了一种简单有效的的多列卷积神经网络结构(MCNN)将图像映射到其人群密度图上.该方法允许输入任意尺寸或分辨率的图像,每列CNN学习得到的特征可以自适应由

Heterogeneous Multi-task Learning for Human Pose Estimation with Deep Convolutional Neural Network

论文题目Heterogeneous Multi-task Learning for Human Pose Estimation with Deep Convolutional Neural Network, 链接 该篇论文是IJCV 2014的, 文章的核心multi-tasks的joint traning. 直接看图说话, 该论文的核心思想/步骤可以分为两个components: 1对图像里面的person进行detection, 以便裁剪出图像里面的人. 这个显然是必要的, 尤其是图像大而p

Some Improvements on Deep Convolutional Neural Network Based Image Classif ication

本文的大概思想就是: (1)增加训练样本:(2)增加测试样本预测数量:(3)多个CNN模型的融合: 一.增加训练样本的数量 常用的增加样本的方法有:crop.flip及add randomly generated ligthing: 1.传统的crop方法是把图像resize到256*256,然后在进行crop,但是这样会损失掉一部分有用的信息例如下图: 因此本文采用的方法:先将图像的最小的一边放大到256,这样就形成了256*N或者N*256,然后在进行crop: 2.除了随机加入光照噪声以外

读paper:Deep Convolutional Neural Network using Triplets of Faces, Deep Ensemble, andScore-level Fusion for Face Recognition

今天给大家带来一篇来自CVPR 2017关于人脸识别的文章. 文章题目:Deep Convolutional Neural Network using Triplets of Faces, Deep Ensemble, and 摘要: 文章动机:人脸识别在一个没有约束的环境下,在计算机视觉中是一个非常有挑战性的问题.同一个身份的人脸当呈现不同的装饰,不同的姿势和不同的表情都可以使人脸看起来完全不同.这种相同身份的变化可以压倒不同身份的变化,这样给人脸识别带来更大的挑战,特别是在没有约束的环境下.

卷积神经网络(Convolutional Neural Network,CNN)

全连接神经网络(Fully connected neural network)处理图像最大的问题在于全连接层的参数太多.参数增多除了导致计算速度减慢,还很容易导致过拟合问题.所以需要一个更合理的神经网络结构来有效地减少神经网络中参数的数目.而卷积神经网络(Convolutional Neural Network,CNN)可以做到. 1. 卷积神经网络构成 图 1:卷积神经网络 输入层 整个网络的输入,一般代表了一张图片的像素矩阵.图 1中最左侧三维矩阵代表一张输入的图片,三维矩阵的长.宽代表了图