上一篇文章,我的空间域最小二乘逆滤波的时间、空间复杂度都非常高。其中求逆矩阵是消耗巨大的一步,这里用迭代优化解法展示了如何不用求逆矩阵来求解最小二乘逆滤波。
首先卷积图像的生成表示为
AXravel+Nravel=Bravel
,我们将问题转化为一个简单的带正则化的优化问题
J(Xravel)=argmin12(AXravel−Bravel)2+λ2|Xravel|2
这是一个无约束问题,我们直接用最速下降法求解:
∂J∂X=(ATA+λI)Xravel−ATBravelXk+1ravel=Xk−μ[(ATA+λI)Xkravel−ATBravel]
其中X的初始值是一个随机矩阵。构建卷积矩阵A最耗时,而最速下降法就快多了。时间和空间复杂度都比直接最小二乘法要好的多。
下面是 μ=0.7,λ=0.01,epoch=200 的结果
Fig (a)原图 (b)5x5均值滤波图像 (c)优化求解逆滤波图像
更新:
然而直接展开卷积作为矩阵乘法,卷积矩阵非常稀疏,即使使用第三方稀疏矩阵库,依然很麻烦。让我们解决这个问题。
解决方案有两个:
- 加速卷积计算
- 将转置卷积矩阵乘法变为普通卷积运算
第一个问题,在opencv和scipy中卷积已经获得了非常快的解法。opencv中加速卷积计算的要点是利用了计算机原理中的局部性原理。对于一个3x3的卷积,我们可以使用3个指针,第i个指针指向卷积区域的第i行,这样就形成了一个线扫描区域,每个指针顺序滑动指向下一个邻近数据地址,这样可以极大地利用计算机缓存,加快速度。
第二个问题,可以从CNN卷积神经网络的反向传播中获取思想。神经网络的反向传播,本质上是求解梯度下降法。而卷积层的反向梯度,即对卷积的求导操作,依然是一个卷积操作,其公式是
J′=conv(σ,rot180(kernel))
也就是旋转了卷积模板,跟自相关计算类似。推导过程见:
Convolutional Neural Networks backpropagation类比本文第一个公式,
AX
其实就是对X用K卷积模板(A是K卷积的展开)做卷积,
ATΔX
则是对
AX
矩阵乘法的求导,也就是
X∗K
卷积操作的求导,因此可以还原为卷积操作。
综合上述,我们得到的最优化超快速解法为:
Xk+1ravel=Xk−μ{conv[conv(X,K)−B,rot180(K)]+λX}
以下第一幅图是模糊图像,第二幅图是
μ=1.0,λ=0.01,epoch=200
的逆滤波结果,第三幅图是原图
PS:这个算法相当于把一个随机图像变成卷积图像的逆滤波图像,与神经网络图像风格化neural style有共通之妙。