UPD:谷歌发布了他们如何实现它的更详细说明:https ://github.com/google/deepdream/blob/master/dream.ipynb
还有另一个项目:https ://317070.github.io/Dream/
如果您从链接中阅读1 ,[2],[3],[4] ,您会发现他们使用了 Caffe。这个框架已经包含了可以使用的训练有素的网络。您无需手动训练任何内容,只需使用models/
文件夹中的 .sh 脚本下载模型即可。
您想要“即插即用的过程”,这并不容易,因为除了框架之外,我们还需要他们使用的脚本的代码,并且可能还需要修补 Caffe。我试着用他们的描述做点什么。Caffe 有 Python 和 Matlab 接口,但它的内部还有更多。
下面的文字描述了我对如何实现它的想法。我不确定我的话,所以这更像是邀请与我一起研究,而不是“即插即用过程”。但是由于仍然没有人回答,所以让我把它放在这里。也许有人会修复我。
所以
据我了解,他们运行优化
[sum((net.forwardTo(X, n) - enchanced_layer).^2) + lambda * R(X)] -> min
即寻找这样的输入X
,以便网络的特定层将产生“增强”数据而不是“原始”数据。
有一个正则化约束R(X)
:X
应该看起来像“自然图像”(没有高频噪声)。
X
是我们的目标图像。初始点X0
是原始图像。
forwardTo(X, n)
是当我们用 X 提供输入时我们的网络在层中产生的n
结果。如果谈到 Caffe,您可以进行全前向传递 ( net.forward
) 并查看您感兴趣的 blob ( net.blob_vec(n).get_data()
)。
enchanced_layer
- 我们在其中获取原始层 blob 和“增强”信号。什么意思,我不知道。也许他们只是将值乘以系数,也许是别的。
因此sum((forwardTo(X, n) - enchanced_net).^2)
,当您的输入图像在图层中准确生成您想要的内容时,它将变为零n
。
lambda
是正则化参数,R(X)
看起来X
很自然。我没有实现它,我的结果看起来很嘈杂。至于它的公式,您可以在[2]中查找。
我使用了 Matlab 并fminlbfgs
进行了优化。
关键部分是找到上面公式的梯度,因为问题的维度太多,无法用数值计算梯度。
正如我所说,我没有设法找到R(X)
. 至于公式的主要部分,我设法以这种方式找到它:
- 将图层上的 diff blob 设置
n
为forwardTo(X, n) - enchanced_net
. (请参阅 caffe 文档中的set_diff
and set_data
,set_data
用于转发并等待数据,set_diff
用于反向传播并等待数据错误)。
- 执行从层到输入的部分反向传播。
n-1
- 输入差异 blob 将包含我们需要的梯度。
Python 和 Matlab 接口不包含部分反向传播,但 Caffe C++ 内部包含它。我在下面添加了一个补丁,使其在 Matlab 中可用。
增强第四层的结果:
我对结果不满意,但我认为这篇文章有一些共同点。