这里我们用Keras来实现这么一个VQA的模型
你可以自由选择keras的backend,或者是theano或者是tensorflow
这个project涉及到大量图片,建议使用GPU。
本教程使用的是python2
训练VQA,首先得需要一套用来训练的材料。
这里:http://www.visualqa.org/
给出了所有所需的素材,数据,等等。
所有的数据都是原始数据,所以我们需要做一点初始化,来把数据变成标准的结构,便于我们日后拿出来处理。
这个方法就是用来一步到位预处理所有数据的:(相关原理和方法,在NLP基础课上讲过,这里不赘述)
通过这个方法,我们把所有问题/回答/对应图片给联系起来,用他们各自的“ID”代码来表示。
这样,我们只需要三个txt文档,就可以存下这么一个对应关系了。
我这里直接在data文件夹下给大家提供了。
根据课上讲解的内容,
我们把“看到一个图就能回答所有问题”这么一个看起来玄幻的目标,
简化成“从1000个最有可能的回答中,找到最符合图片的答案”这个样式。
也就是把一个开放AI问题,转化成了multi-class的分类问题。
好,我们来选取最popular的1000个问答:
接下来,我们把所有的1000个答案给编号。
这样我们选取某个答案的时候,就不用使用“全称”,可以使用他们的label。
我们简单用到sklearn的preprocessing功能来赋值label。
当然,我们之后一直需要使用这个一一对应的label,所以我们存下来。
这个labelencoder怎么用?
我们写一个method,可以把所有的answers转化成数字化的label
这里,我们使用工业/学术上都很耀眼的VGG CNN来提取图片的特征。
这部分内容(关于怎么训练一个CNN),不太了解的同学,可以关注其他相关的Deep Learning课程。
我们这里,直接运用已经成熟训练好的VGG CNN模型,直接下载,并导入,
因为我们用的是标准MSCOCO图片库,所以对应的标准VGG已经训练完备。
详见:http://mscoco.org/
http://cs.stanford.edu/people/karpathy/deepimagesent
用这个方法,我们把input图片的features一步到位地取出来。
这时候,我们再写一个method,
是用来取得任何一个input图片的“数字化表达形式”的,也就是一个matrix
这个matrix是由vgg扫过/处理图片以后,再加一层flatten得到的4096维的数组,我们称之为CNN Features
接下来,是文字部分。
我们用SpaCy自带的英文模型。
把问句中的所有英文转化为vector,
并平均化整个句子。
这个本质上就是我们NLP基础课上讲过的word2vec
我们来建立我们最简单版本的MLP模型
也就是普通的神经网络模型
注意:我这里就跑了1个epoch,只是为了Demo,真实场景中,这显然是不够的, 大家可以试试100次。
好接下来,我们做一个保存的动作。
训练大规模网络的时候,这是一种比较保险的举措,即可以让我们回测数据,也可以在紧急情况下及时返回保存过了的模型
In [12]:
在训练之前,我们还需要一个chunk list的方法,来把我们原始的数据分成一组一组的形式
为了我们之后的batch training做准备
In [ ]:
可以开始训练了!
代码非常直观:
In [13]:
这里注意,我们一共存了两种文件。
一种是json,是我们建立模型以后就存下来的东西,它代表了我们模型的龙骨(构架)
一种是hdf5, 全称Hierarchical Data Format,是非常高效的一种存储格式,把我们训练好的权重(weights)都记录下来。
那么,经过N轮的training之后,我们可以根据loss来监视效果。
那么,同学们如果想做一下Evaluation,或者模型升级,等等,都可以改改代码试试。
道理上讲,这里训练的部分,跟前面依旧没啥区别,
唯一的区别是,我们造语言部分的matrix的时候,使用timestep的方法,也就是我们刚刚上面改写的那个方法
In [17]:
依旧是只train了一个epoch。
但是可以看到,loss已然比刚刚MLP的时候低了。
大家可以多跑跑可以看看效果。
最后,我们来看看效果!
我们走网上找了一波测试图片
因为我们没有自己训练一个VGG CNN模型,而是直接借用的其他家训练好的模型,这个自己做测试部分,其实是比较tricky的。
所以这里,我们还需要借用他们的模型,来给我们的图片做第一步的“特征提取”。
上面给的网页里面,同时也给了这个VGG的模型参数和weights,下载下来:
模型参数 模型构架
In [29]:
玩玩还是很有趣的。
同学们有时间,可以多train一下模型,然后拿出来跑跑,看看效果如何。