MatConvNet的CNN卷积网络目标函数定义,优化和反向传播及其Matlab代码实现
在CNN卷积网络中,从输入前向传播到误差反向传播,如下图所示:
其中,在反向传播过程中,还需要把网络的输出经过一个目标函数(Objective function),通常也称为损失函数(Loss function),把网络的输出映射为一个实数,反向传播就是去优化这个损失函数,具体如下图所示:
在上图中,f 表示网络的计算模块,y 为网络输出,g 表示损失函数,网络的输出 y 经 g 映射为一个实数 z 。反向传播需要将误差 z 反向传播,那么就需要计算 z 关于 x 和 w 的偏导和,但是根据链式求导法则需要先求得。
下面设 f 为卷积模块, p 用正态分布随机数填充,则前向传播与反向传播求导如下代码:
- <span style="font-size:14px;">% Read an example image
- x = im2single(imread(\'peppers.png\')) ;
- % Create a bank of linear filters and apply them to the image
- w = randn(5,5,3,10,\'single\') ;
- y = vl_nnconv(x, w, []) ;
- % Create the derivative dz/dy
- dzdy = randn(size(y), \'single\') ;
- % Back-propagation
- [dzdx, dzdw] = vl_nnconv(x, w, [], dzdy) ;
- </span>
通过上述代码,已经熟悉了CNN卷积网络的前向传导与反向传播求导的基本操作,下面自定义一个目标函数,对其求导,并反向传播。
目标函数定义如下:
在上式中,f(x;w,b) 为网络的输出,也即上文中的 y 。因此,在对 w 与 b 求导前需要对 f(x;w,b) 先求导。下面分析这个目标函数以便进行求导。由上式可得:
现将网络输出 f(x;w,b) 设为res.x3(这里定义了一个三层的网络,且为了与MatConvNet定义的网络输出保持一致),E(3,1)即为上式中的目标函数, 也表示输出 z ,P—>pos, N—>neg, Matlab代码实现如下:
- <span style="font-size:14px;">E(1,1) = ...
- mean(max(0, 1 - res.x3(pos))) + ...
- mean(max(0, res.x3(neg))) ;
- E(2,1) = 0.5 * shrinkRate * sum(w(:).^2) ;
- E(3,1) = E(1,1) + E(2,1) ;
- dzdx3 = ...
- - single(res.x3 < 1 & pos) / sum(pos(:)) + ...
- + single(res.x3 > 0 & neg) / sum(neg(:)) ;</span>
完整代码如下:
- <span style="font-size:14px;"> % Forward pass
- res = tinycnn(im, w, b) ;
- % Loss
- E(1,1) = ...
- mean(max(0, 1 - res.x3(pos))) + ...
- mean(max(0, res.x3(neg))) ;
- E(2,1) = 0.5 * shrinkRate * sum(w(:).^2) ;
- E(3,1) = E(1,1) + E(2,1) ;
- dzdx3 = ...
- - single(res.x3 < 1 & pos) / sum(pos(:)) + ...
- + single(res.x3 > 0 & neg) / sum(neg(:)) ;
- % Backward pass
- res = tinycnn(im, w, b, dzdx3) ;</span>
请发表评论