开发 | 在玩图像分类和图像分割?来挑战基于 TensorFlow 的图像注解生成!

AI科技评论按:本文刊载于 Oreilly,AI科技评论编译。

玩过图像分类的开发者不少,许多人或许对图像分割(image segmentation)也不陌生,但图像注解(image caption)的难度,无疑比前两者更进一步。

原因无他:利用神经网络来生成贴合实际的图像注释,需要结合最新的计算机视觉和机器翻译技术,缺一不可。对于为输入图像生成文字注解,训练神经图像注解模型能使其成功几率最大化,并能生成新奇的图像描述。举个例子,下图便是在 MS COCO 数据集上训练的神经图像注解生成器,所输出的潜在注解。

左图注解:一个灰衣男子挥舞棒子,黑衣男子旁观;右图注解:一辆大巴车“坐”在一个人旁边

本文是一篇中级教程,旨在教给大家如何在 Flickr30k 数据集上训练图像注解生成模型,使用的是谷歌 Show and Tell 模型的变体。我们使用 TensorFlow 框架来创建、训练、测试模型,因为 TensorFlow 相对容易使用,并且有不断增长的庞大用户社群。

图像注解技术的价值

近来深度学习在 CV(计算机视觉)和 NLP(自然语言处理)领域的成功,激发了 AI 研究人员在这两者的交叉领域探索新的应用。而作为结果的注解生成模型,需要平衡对视觉线索和自然语言的理解。

这两门传统上泾渭分明、并不相关的领域之间所产生的交集,有潜力在业内产生广泛的影响。该技术有一些直接应用场景,比如为 YouTube 视频生成简介,又比如为无标签图像做注解,但其价值远不止于此。类似于传统的 CV 技术试图让现实世界变得让计算机更容易接触更容易理解,该技术有潜力让现实世界变得对于我们来说更容易理解。它可以作为我们的导游、日常生活的视觉辅助,比如意大利 AI 公司 Eyra 的为视觉障碍患者开发的可穿戴设备 Horus (古埃及神话中的荷鲁斯之眼)。

准备工作

首先,你需要安装 TensorFlow。

其次,你需要 pandas, opencv2 以及 Jupyter 来跑相关代码。但是,为了简化安装过程,我们强烈推荐你在我们的 GitHub 资源库里跟随 Docker 的安装指南。

你还需要下载 Flickr30k 数据集的图像注解和 image embeddings。下载链接也在 GitHub 资源库里。

现在教程开始。

图像注解生成模型

在高层级,这就是我们将要训练的模型。每一幅图像将会用深度 CNN 编码成 4,096 维的矢量表示。一个语言生成 RNN 会随后对其按次序解码,成为自然语言描述。

注解生成——作为图像分类的延伸

作为一个历史悠久的 CV 任务,图像分类背后有许多强大模型。图像分类能把图像中相关联的形状、物体的视觉信息拼凑到一起,把图像放入物体类别中。针对其他 CV 任务的机器学习模型,建立在图像分类的基础之上,比如物体识别和图像分割。它们不仅能对提供的信息进行识别,还能学习如何解读 2D 空间,调和两种理解,并决定图像中物体信息的位置分布。

对于注释生成,这引发了两个问题:

  1. 我们如何充分利用图像分类模型的成功,从图像提取重要信息?
  2. 我们的模型,该如何调和对语言和图像的理解?

利用迁移学习

我们可以利用已有的模型,推动图像注解。迁移学习使得——在不同任务上训练神经网络而学习到的数据变形,能用于我们的数据。在我们的例子中,VGG-16 图像分类模型导入 224x224 分辨率的图像,生成对分类图像非常有用的 4,096 维特征矢量。

我们可以把 VGG-16 模型的表示(即 image embedding)用于训练其他模型上面。受篇幅限制,本文对 VGG-16 的架构不欲详述,并预先计算好了 4,096 维特征,来加速训练。

载入 VGG 图像特征和图像注解比较直接:

def get_data(annotation_path, feature_path): annotations = pd.read_table(annotation_path, sep='\t', header=None, names=['image', 'caption']) return np.load(feature_path,'r'), annotations['caption'].values

理解注解

有了图像表示,我们需要模型来学习把它解码为可理解的注解。由于文本的序列本质,我们需利用 RNN/LSTM 中的循环。对于序列中的给定词语,这些网络被训练,用以预测下一个词语以及图像表示。

LSTM 单元允许模型在注解词语序列中,更好地选择使用哪条信息、记忆什么、又要忘记什么。TensorFlow 提供了一个 wrapper 函数,来对给定输入、输出维度生成 LSTM 层。

为了把词语转换成适合 LSTM 输入的固定长度表示,我们使用了一个 embedding 层,它能学习把词语映射到 256 维的特征(或 word-embedding)。Word-embedding 帮助我们把词语表示为矢量,相近的词语矢量在语义上也是近似的。

在 VGG-16 图像分类器里,卷积层提取了 4,096 维表示,传入最终的 softmax 层进行分类。由于 LSTM 单元需要 256 维文本特征作为输入,我们需要把图像表示转译为针对目标注解的表示。为实现这一点,我们使用了另一个 embedding 层,学习把 4,096 维图像特征映射到 256 维文本特征的空间。

创建和训练模型

整体上,这就是谷歌 Show and Tell 模型看起来的样子:

上图中, {s0, s1, ..., sN}代表了注解中我们想要预测的词语, {wes0, wes1, ..., wesN-1} 是每个词的 word embedding 矢量。LSTM 的输出 {p1, p2, ..., pN} 是模型生成的概率分布,针对句子中的下一个词。该模型被训练来最小化每个词语对数概率(log probabilities )的负数总和。

使用推理生成注解

训练之后,我们有了一个模型。给定图像和所有此前的词语,它能给出下一步某个词出现在注解中的概率。如何用它来生成新注解呢?

最简单的办法,是拿来一个输入图像,输出下一个可能性最高的词语,创建一个简单的图像注解。

这在许多情况下会奏,但“贪婪”地使用每一个概率最大的词语,未必能获得整体上概率最大的注解。

绕过这个难题的一个潜在方案,是采用一个名为"Beam Search"的方法。该算法会对长度 t 以内的 k 个最佳语句集反复考量,作为候选来生成 t + 1 大小的句子,只保留结果中的 k 个最佳选择。这允许开发者探索一个较大的优质注解空间,同时让推理在计算上可追踪。在下面的例子里,算法保持了一个 k = 2 的候选句子列表,即每个垂直时间步到每个加粗词语的路线。

局限性

对于学习把图像映射到人类级别的文字注解,该神经图像注解生成器提供了一个十分有用的框架。铜鼓偶在大量图像—注解成对数据上训练,该模型学会了通过视觉特征抓取相关语义信息。

但对于静态图片而言,嵌入我们的注解生成器,将会聚焦于图像中对分类有用的特征,而不是对注解生成有用的特征。为提升每个特征里涵盖的与任务相关的信息,我们可以训练图像嵌入模型(用来对特征进行编码的 VGG-16 网络)作为注解生成模型的一部分。这使得我们能为图像编码器调参,以更符合注解生成器的角色。

另外,如果我们仔细观察生成的注解,会发现它们基本是日常、常见的情形。下图便是例子:

几乎可以肯定,这图片是“长颈鹿站在一棵树旁边”。但是,如果我们看看其他图片,会立刻发现无论对于哪一张生成的注解都是“长颈鹿站在一棵树旁边”。这是因为训练集中的长颈鹿都出现在树旁边。

下一步

首先,如果你想要提升该模型,你需要看看谷歌的开源 Show and Tell 神经网络。它用 MS COCO 数据集和 Inception-v3 图像嵌入训练。

现有的前沿图像注解模型会包含一个视觉注意力机制(visual attention mechanism),使得模型能发现图像中感兴趣的部分,因而能在生成注解时选择性地聚焦。

另外,如果你对注解生成的前沿执行非常好奇,不妨看看这一篇论文:Show, Attend, and Tell: Neural Image Caption Generation with Visual Attention。

提醒:作者已将本文所有 Python 代码上传于 GitHub,地址:https://github.com/mlberkeley/oreilly-captions?utm_source=newsite&utm_medium=content&utm_campaign=lgen&utm_content=caption-this-with-tensorflow-top-cta。

原文发布于微信公众号 - AI科技评论(aitechtalk)

原文发表时间:2017-05-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PaddlePaddle

【AI核心技术】课程十六:突破障碍的LSTM

UAI与PaddlePaddle联合推出的【AI核心技术掌握】系列课程持续更新中!

862
来自专栏机器学习算法与Python学习

6分钟教你如何使用Python编写、可视化决策树算法(Iris数据集)

本集视频使用真实的数据来建一棵决策树,编写代码,将其可视化,并练习如何阅读决策树。这样您即可明白决策树是如何在幕后工作的。(PS:英文,无字幕) ?

3606
来自专栏生信小驿站

R 梯度提升算法①

它是一种传统而重要的Boost算法,在学习时为每一个样本赋上一个权重,初始时各样本权重一样。在每一步训练后,增加错误学习样本的权重,这使得某些样本的重要性凸显出...

733
来自专栏PaddlePaddle

【AI核心技术】课程十四:序列场景分析

UAI与PaddlePaddle联合推出的【AI核心技术掌握】系列课程持续更新中!

783
来自专栏懒人开发

(0)James Stewart Calculus 5th Edition:自己扯淡

自己也没有怎么看完过什么全英文的书籍 原来同事,感觉英文也一般,但是为了图形学的代码 看完整本书,并且做完了所有的题目

421
来自专栏SnailTyan

Very Deep Convolutional Networks for Large-Scale Image Recognition—VGG论文翻译—中文版

声明:作者翻译论文仅为学习,如有侵权请联系作者删除博文,谢谢! Very Deep Convolutional Networks for Large-Scale...

2310
来自专栏WOLFRAM

让函数的导数可视化

1024
来自专栏肖力涛的专栏

马里奥 AI 实现方式探索 :神经网络+增强学习(上)

如果能够在游戏自动化测试、智能 AI 中应用这些有趣的算法,想想还是有点小激动哒。

6904
来自专栏PaddlePaddle

【AI核心技术】课程十八:神经图灵机整理结构

UAI与PaddlePaddle联合推出的【AI核心技术掌握】系列课程持续更新中!

1135
来自专栏图像识别与深度学习

2018-04-22 project proposal

1325

扫描关注云+社区