dat*_*den 71 deep-learning caffe conv-neural-network deep-dream imagenet
我一直在玩,Deep Dream并Inceptionism使用Caffe框架来可视化层GoogLeNet,这是一个为Imagenet项目构建的架构,一个专为视觉对象识别而设计的大型可视化数据库.
Imagenet可以在这里找到:Imagenet 1000类.
为了探究架构并产生"梦想",我使用了三个笔记本:
https://github.com/kylemcdonald/deepdream/blob/master/dream.ipynb
https://github.com/auduno/deepdraw/blob/master/deepdraw.ipynb
这里的基本思想是从模型或"指南"图像中提取指定图层中每个通道的一些特征.
然后我们将我们希望修改的图像输入到模型中,并在指定的同一层中提取特征(对于每个八度音阶),增强最佳匹配特征,即两个特征向量的最大点积.
到目前为止,我已经设法使用以下方法修改输入图像和控制梦想:
- (a)将图层用作
'end'输入图像优化的目标.(见功能可视化)- (b)使用第二图像来指导输入图像上的de优化目标.
- (c)可视化
Googlenet由噪声产生的模型类.
但是,我想要实现的效果介于这些技术之间,我没有找到任何文档,论文或代码.
要使一个属于给定
'end'层的单个类或单元(a)引导优化目标(b)并使该类在输入图像上可视化(c):
一个例子,其中class = 'face'和input_image = 'clouds.jpg':
请注意:上面的图像是使用面部识别模型生成的,该模型未经过Imagenet数据集培训.仅用于演示目的.
方法(a)
from cStringIO import StringIO
import numpy as np
import scipy.ndimage as nd
import PIL.Image
from IPython.display import clear_output, Image, display
from google.protobuf import text_format
import matplotlib as plt
import caffe
model_name = 'GoogLeNet'
model_path = 'models/dream/bvlc_googlenet/' # substitute your path here
net_fn = model_path + 'deploy.prototxt'
param_fn = model_path + 'bvlc_googlenet.caffemodel'
model = caffe.io.caffe_pb2.NetParameter()
text_format.Merge(open(net_fn).read(), model)
model.force_backward = True
open('models/dream/bvlc_googlenet/tmp.prototxt', 'w').write(str(model))
net = caffe.Classifier('models/dream/bvlc_googlenet/tmp.prototxt', param_fn,
mean = np.float32([104.0, 116.0, 122.0]), # ImageNet mean, training set dependent
channel_swap = (2,1,0)) # the reference model has channels in BGR order instead of RGB
def showarray(a, fmt='jpeg'):
a = np.uint8(np.clip(a, 0, 255))
f = StringIO()
PIL.Image.fromarray(a).save(f, fmt)
display(Image(data=f.getvalue()))
# a couple of utility functions for converting to and from Caffe's input image layout
def preprocess(net, img):
return np.float32(np.rollaxis(img, 2)[::-1]) - net.transformer.mean['data']
def deprocess(net, img):
return np.dstack((img + net.transformer.mean['data'])[::-1])
def objective_L2(dst):
dst.diff[:] = dst.data
def make_step(net, step_size=1.5, end='inception_4c/output',
jitter=32, clip=True, objective=objective_L2):
'''Basic gradient ascent step.'''
src = net.blobs['data'] # input image is stored in Net's 'data' blob
dst = net.blobs[end]
ox, oy = np.random.randint(-jitter, jitter+1, 2)
src.data[0] = np.roll(np.roll(src.data[0], ox, -1), oy, -2) # apply jitter shift
net.forward(end=end)
objective(dst) # specify the optimization objective
net.backward(start=end)
g = src.diff[0]
# apply normalized ascent step to the input image
src.data[:] += step_size/np.abs(g).mean() * g
src.data[0] = np.roll(np.roll(src.data[0], -ox, -1), -oy, -2) # unshift image
if clip:
bias = net.transformer.mean['data']
src.data[:] = np.clip(src.data, -bias, 255-bias)
def deepdream(net, base_img, iter_n=20, octave_n=4, octave_scale=1.4,
end='inception_4c/output', clip=True, **step_params):
# prepare base images for all octaves
octaves = [preprocess(net, base_img)]
for i in xrange(octave_n-1):
octaves.append(nd.zoom(octaves[-1], (1, 1.0/octave_scale,1.0/octave_scale), order=1))
src = net.blobs['data']
detail = np.zeros_like(octaves[-1]) # allocate image for network-produced details
for octave, octave_base in enumerate(octaves[::-1]):
h, w = octave_base.shape[-2:]
if octave > 0:
# upscale details from the previous octave
h1, w1 = detail.shape[-2:]
detail = nd.zoom(detail, (1, 1.0*h/h1,1.0*w/w1), order=1)
src.reshape(1,3,h,w) # resize the network's input image size
src.data[0] = octave_base+detail
for i in xrange(iter_n):
make_step(net, end=end, clip=clip, **step_params)
# visualization
vis = deprocess(net, src.data[0])
if not clip: # adjust image contrast if clipping is disabled
vis = vis*(255.0/np.percentile(vis, 99.98))
showarray(vis)
print octave, i, end, vis.shape
clear_output(wait=True)
# extract details produced on the current octave
detail = src.data[0]-octave_base
# returning the resulting image
return deprocess(net, src.data[0])
Run Code Online (Sandbox Code Playgroud)
我运行上面的代码:
end = 'inception_4c/output'
img = np.float32(PIL.Image.open('clouds.jpg'))
_=deepdream(net, img)
Run Code Online (Sandbox Code Playgroud)
方法(b)
"""
Use one single image to guide
the optimization process.
This affects the style of generated images
without using a different training set.
"""
def dream_control_by_image(optimization_objective, end):
# this image will shape input img
guide = np.float32(PIL.Image.open(optimization_objective))
showarray(guide)
h, w = guide.shape[:2]
src, dst = net.blobs['data'], net.blobs[end]
src.reshape(1,3,h,w)
src.data[0] = preprocess(net, guide)
net.forward(end=end)
guide_features = dst.data[0].copy()
def objective_guide(dst):
x = dst.data[0].copy()
y = guide_features
ch = x.shape[0]
x = x.reshape(ch,-1)
y = y.reshape(ch,-1)
A = x.T.dot(y) # compute the matrix of dot-products with guide features
dst.diff[0].reshape(ch,-1)[:] = y[:,A.argmax(1)] # select ones that match best
_=deepdream(net, img, end=end, objective=objective_guide)
Run Code Online (Sandbox Code Playgroud)
我运行上面的代码:
end = 'inception_4c/output'
# image to be modified
img = np.float32(PIL.Image.open('img/clouds.jpg'))
guide_image = 'img/guide.jpg'
dream_control_by_image(guide_image, end)
Run Code Online (Sandbox Code Playgroud)
方法失败
这就是我试图访问单个类,热编码类矩阵并专注于一个(迄今为止无济于事)的方法:
def objective_class(dst, class=50):
# according to imagenet classes
#50: 'American alligator, Alligator mississipiensis',
one_hot = np.zeros_like(dst.data)
one_hot.flat[class] = 1.
dst.diff[:] = one_hot.flat[class]
Run Code Online (Sandbox Code Playgroud)
可以请有人在这里指导我正确的方向吗?这将不胜感激.
问题是如何#50: \'American alligator, Alligator mississipiensis\'从 ImageNet 获取所选类别的图像。
前往下载。
\n网站已更改,您无法再按以下步骤下载。现在看起来像这样:
\n\n\n\nImageNet 最常用的子集是ImageNet 大规模视觉识别挑战赛 (ILSVRC) 2012-2017 图像分类和定位数据集。该数据集涵盖 1000 个对象类别,包含 1,281,167 个训练图像、50,000 个验证图像和 100,000 个测试图像。该子集在Kaggle上可用。
\n要访问完整的 ImageNet 数据集和其他常用子集,请登录或请求访问。为此,您需要同意我们的访问条款。
\n
\n\n\n\n如何从浏览器下载同义词集的 URL?
\nRun Code Online (Sandbox Code Playgroud)\n1. Type a query in the Search box and click "Search" button\n
没有显示鳄鱼。ImageNet is under maintenance. Only ILSVRC synsets are included in the search results.没问题,我们对类似的动物“鳄鱼蜥蜴”没问题,因为此搜索是为了找到 WordNet 树形图的正确分支。我不知道即使没有维护,你是否能在这里得到直接的ImageNet图像。
\n\n\nRun Code Online (Sandbox Code Playgroud)\n2. Open a synset papge\n
向下滚动:
\n\n向下滚动:
\n\n寻找美洲短吻鳄,它恰好也是蜥蜴双孔类爬行动物,作为近邻:
\n\n\n\n\nRun Code Online (Sandbox Code Playgroud)\n3. You will find the "Download URLs" button under the left-bottom corner of the image browsing window.\n
您将获得所选类别的所有 URL。浏览器中会弹出一个文本文件:
\nhttp://image-net.org/api/text/imagenet.synset.geturls?wnid=n01698640
\n我们在这里看到,只需知道需要放在 URL 末尾的正确 WordNet id 即可。
\n文本文件如下所示:
\n\n例如,第一个 URL 链接到:
\n\n第二个是死链接:
\n\n第三个链接已失效,但第四个链接可用。
\n\n这些网址的图片是公开的,但许多链接已失效,而且图片分辨率较低。
\n再次来自 ImageNet 指南:
\n\n\n如何通过HTTP协议下载?要通过 HTTP 请求下载同义词集,您需要先获取同义词集的“WordNet ID”(wnid)。\n当您使用资源管理器浏览同义词集时,您可以在图像窗口下方找到 WordNet\nID。(点击这里搜索“Synset WordNet ID”\n可以找到“Dog,家养狗,Canisamilariis”synset的wnid)。\n要了解更多关于“WordNet ID”的信息,请参阅
\nRun Code Online (Sandbox Code Playgroud)\nMapping between ImageNet and WordNet\n给定同义词集的 wnid,可以在以下位置获取其图像的 URL:
\nRun Code Online (Sandbox Code Playgroud)\nhttp://www.image-net.org/api/text/imagenet.synset.geturls?wnid=[wnid]\n您还可以获取给定 wnid 的下位词同义词集,请参阅 API\n文档以了解更多信息。
\n
那么API 文档中有什么内容呢?
\n这里有获取所有 WordNet ID(所谓的“同义词集 ID”)及其所有同义词集的单词所需的一切,也就是说,它有任何类名称及其手头的 WordNet ID,都是免费的。
\n\n\n获取同义词集的单词
\n给定同义词集的 wnid,\n可以在以下位置获取该同义词集的单词:
\nRun Code Online (Sandbox Code Playgroud)\nhttp://www.image-net.org/api/text/wordnet.synset.getwords?wnid=[wnid]\n您还可以单击此处下载\n所有同义词集的 WordNet ID 和单词之间的映射,\n单击此处下载\n所有同义词集的 WordNet ID 和注释之间的映射。
\n
如果您知道所选的 WordNet id 及其类名称,则可以使用“nltk”(自然语言工具包)的 nltk.corpus.wordnet,请参阅WordNet 接口。
\n在我们的例子中,我们只需要 class 的图像#50: \'American alligator, Alligator mississipiensis\',我们已经知道我们需要什么,因此我们可以将 nltk.corpus.wordnet 放在一边(有关更多信息,请参阅教程或 Stack Exchange 问题)。我们可以通过循环仍然存在的 URL 来自动下载所有鳄鱼图像。当然,我们还可以通过循环遍历所有 WordNet ID 将其扩展到完整的 WordNet,尽管这对于整个树形图来说会花费太多时间 - 而且也不推荐,因为如果有 1000 个人下载,图像将不再存在。他们每天。
恐怕我不会花时间编写接受 ImageNet 类号“#50”作为参数的 Python 代码,尽管使用从 WordNet 到 ImageNet 的映射表也应该是可能的。类名和 WordNet ID 应该足够了。
\n对于单个 WordNet ID,代码可能如下:
\nimport urllib.request \nimport csv\n\nwnid = "n01698640"\nurl = "http://image-net.org/api/text/imagenet.synset.geturls?wnid=" + str(wnid)\n\n# From /sf/answers/3175118271/\nreq = urllib.request.Request(url, headers={\'User-Agent\': \'Mozilla/5.0\'})\nwith open(wnid + ".csv", "wb") as f:\n with urllib.request.urlopen(req) as r:\n f.write(r.read())\n\nwith open(wnid + ".csv", "r") as f:\n counter = 1\n for line in f.readlines(): \n print(line.strip("\\n"))\n failed = []\n try:\n with urllib.request.urlopen(line) as r2:\n with open(f\'\'\'{wnid}_{counter:05}.jpg\'\'\', "wb") as f2:\n f2.write(r2.read())\n except:\n failed.append(f\'\'\'{counter:05}, {line}\'\'\'.strip("\\n"))\n counter += 1\n if counter == 10:\n break\n\nwith open(wnid + "_failed.csv", "w", newline="") as f3:\n writer = csv.writer(f3)\n writer.writerow(failed)\nRun Code Online (Sandbox Code Playgroud)\n结果:
\n\nwnid=n01698640URL 末尾的 ,这是映射到 ImageNet 的 WordNet id。到达,得到:
\n\n或右键单击-另存为:
\n\n您可以使用 WordNet id 来获取原始图像。
\n\n如果您是商业用途,我建议您联系 ImageNet 团队。
\n采纳评论的想法:如果您不需要很多图像,而只想要尽可能多地代表该类的“一个单类图像”,请查看Visualizing GoogLeNet Classes并尝试将此方法与图像一起使用取而代之的是 ImageNet。它也使用 deepdream 代码。
\n\n\n可视化 GoogLeNet 类
\n\n
\n- 2015年7月
\n有没有想过深度神经网络认为达尔马提亚狗应该是什么样子?好吧,别再好奇了。
\n最近,Google发表了一篇文章,描述了他们如何设法使用深度神经网络生成类可视化并通过所谓的 xe2x80x9cinceptionismxe2x80x9d 方法修改图像。他们后来\n自己发布了通过 inceptionism 方法修改图像的代码,\n但是,他们\xe2\x80\x99 没有发布代码来生成他们在同一篇文章中\n显示的类可视化。
\n虽然我从来没有弄清楚 Google 是如何生成他们的类可视化的,但在砍掉了Deepdream 代码和Kyle McDonald 的ipython 笔记本之后,我成功地指导 GoogLeNet 绘制了这些:
\n\n... [还有许多其他示例图像]
\n