您的位置:首页 > 理论基础 > 计算机网络

卷积神经网络CNN解析-针对斯坦福的深度学习教程

2016-10-30 17:22 288 查看
附上针对的实验:http://ufldl.stanford.edu/tutorial/supervised/ExerciseConvolutionalNeuralNetwork/

这里就不陈述卷积网络的意义了,就直接陈述怎么做,怎么写前向传播和反向传播,求各个参数的倒数。

阅读前建议读者对于全连接网络有着透彻的理解。。没有的话,强烈建议看看上述实验前面的全连接部分的练习。

建议读者配合着实验的英文论述再看这篇。。会好的多。

实验构造的是单个卷积-池化层------全连接网络--------输出的结构,就是一层CNN连接一层NN的结构。

以实验中的debug部分作为解析吧,实际运行时就改卷积核个数numFilters,和卷积尺度filterDim还有poolDim就可以了。

debug部分采用两个卷积核,对应两个池化层,然后池化层全连接输出单元。

来一个结构图解:嗯对的图很重要!这个乱七八糟的图是我自己画的,之后的图截取自实验教程。



从底层开始讲吧,最底层是输入层,在实验中对应那个28*28的原始输入图像。

卷积操作:卷积核使用9*9的尺寸,于是在卷积1,2中的图形是20*20的尺寸。

卷积层的输出定义为 activations=cnnConvolve(filterDim, numFilters, images, Wc, bc)



这里用图片举个例子,卷积特征的4来自于卷积核(橙色的方块)参数乘以对应的覆盖于然后求和出的结果,然后将卷积核在图像中逐个像素移动,得到对应的卷积后的特征图。然后对于卷积后的图像的每一个元素执行sigmoid函数,将每一个元素转化为[0,1]区间内的特征。
Tip: matlab中有一个很方便的函数用来做卷积叫做conv2。
池化操作:其实这就是一个取平均的操作,针对之前20*20的卷积特征图,池化层过滤器尺寸为5*5,则池化层输出为4*4的图像。还有别的池化操作,比如最大值等。。
池化层的输出定义为activationsPooled=cnnPool(poolDim, activations)



如图所示,池化层的1是卷积层的所有红色覆盖元素值的平均值。
最后对于池化层,全连接输出层。
全连接层的输出定义为probs。
以上结构中有需要学习参数的部分,只有卷积核参数W1,W2,还有全连接参数Theta。
反向传播:
计算误差:
这里是我认为的难点,一方面是确实难,另一方面实验教程的变量意义还注释的确实很不明白。。。。。
输出层误差:delta_output=probs-label_vec,就是预测值减去实际标签值,这里的预测值和标签值都是向量化的,比如10,表示为(0,0,0,0,0,0,0,0,0,1)。
池化层误差:delta_pool=Theta'*delta_output,等于Theta的转置乘以delta_output。
卷积层误差:delta_filter=zeros(convDim,convDim,numFilters,numImages);计算每一张图像对于每一个卷积层的误差,所以是一个四维数组。
for j=1:numFilters

    for i=1:numImages

        delta_filter(:,:,j,i)=(1/poolDim^2)*kron(delta_pool(:,:,j,i), ones(poolDim)).*activations(:,:,j,i) .*(1 - activations(:,:,j,i));

    end

end
这里有一个kron函数,它的意义是将一个矩阵等值扩张,将1,2,3,4矩阵扩张成左边那个矩阵的样子。这么做的是因为之前池化操作是对于卷积层的均值化嘛。
还有就是矩阵的.*意思是每一个元素相乘。



计算导数:
1,对于全连接层Theta:
它的数学公式长这样,嗯很抽象。。。。。



翻译成代码就是:Theta_grad = delta_output*activationsPooled'/numImages;
Theta_b_grad = sum(delta_o
8dec
utput,2)/numImages;
2,对于卷积层的倒数Wc_grad和bd_grad:
英文论述:。。。。



对于英文不是很给力的我简直。。。看着这想死。。。意思就是用卷积层误差,去卷积操作原始图像,得到的结果再对于图片数量取平均。
还是翻译成代码吧。。。。
for j=1:numFilters

    for i=1:numImages

        pic=images(:,:,i);

        delta=rot90(delta_filter(:,:,j,i),2);

        bc_grad(j)=bc_grad(j)+sum(delta(:));

        Wc_grad(:,:,j) = Wc_grad(:,:,j)+conv2(pic,delta,'valid');            

    end

end

Wc_grad=Wc_grad/numImages;

bc_grad=bc_grad/numImages;
到这里应该接下来就很简单了,获得了每个参数的导数之后,揉成单维向量,传进梯度下降函数中,调整每个参数的数值,嗯一个简易的卷积神经网络就完成喽。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐