Deep Dream是一个非常有趣的算法,利用已经训练好的卷积网络模型,对输入图像进行反向修改,放大卷积网络中某部分的输出。
这里演示一个最简单的反向图像生成。和之前的演示一样,我们同样使用VGG的ImageNet模型。
https://github.com/google/deepdream
https://github.com/jrosebr1/bat-country
https://github.com/jcjohnson/cnn-vis
* 基于Torch的实现
https://github.com/eladhoffer/DeepDream.torch
https://github.com/Teaonly/easyStyle (鄙人的简单实现)
In [15]:
require('nn')
require('image')
require('loadcaffe')
require('cunn')
torch.setdefaulttensortype('torch.FloatTensor')
--装载原始模型
fullModel = loadcaffe.load('vgg19/VGG_ILSVRC_19_layers_deploy.prototxt', 'vgg19/VGG_ILSVRC_19_layers.caffemodel', 'nn')
fullModel:evaluate()
cnnModel = nn.Sequential()
for i = 1, 27 do
cnnModel:add( fullModel.modules[i] )
end
cnnModel:float()
cnnModel:evaluate()
collectgarbage()
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
In [2]:
require('image')
orignalImg = image.loadPNG('./input.png', 3)
itorch.image(orignalImg)
orignalImg = orignalImg:float() * 256
for j = 1, 3 do
orignalImg[{j, {}, {}}] = orignalImg[{j, {}, {}}] - 128
end
In [14]:
require("cunn")
local maxIterator = 20
local enhenceImageGPU = function (inputImage)
local targetImg = inputImage:clone()
targetImg = targetImg:cuda()
for i = 1, maxIterator do
local inputOuput = cnnModel:forward(targetImg)
-- 从神经网络的输出层,制造loss函数,输出 dloss
local amplifyDiff = inputOuput:clone()
amplifyDiff:mul(-1) -- 乘以-1,表示放大这个神经层
inputOuput = cnnModel:backward(targetImg, amplifyDiff)
local scale = 1.5 / torch.mean(torch.abs(inputOuput))
targetImg:add(inputOuput*(-1*scale))
collectgarbage()
end
targetImg = targetImg:float()
clipImage(targetImg)
for j = 1, 3 do
targetImg[{j, {}, {}}] = targetImg[{j, {}, {}}] + 128
end
targetImg = targetImg / 256
return targetImg
end
cnnModel:cuda()
local te = sys.clock()
local outImage = enhenceImageGPU(orignalImg)
print("==>总用时:" .. (sys.clock() - te) )
itorch.image(outImage)
Out[14]:
In [ ]: