对于人类来说,描述一张图片的内容是非常重要的。但因这个过程并没有标准答案,因此对于计算机来说这并不是一个简单地过程。我们希望通过本次实验能够设计一个模型完成让计算机给图片设定 caption 的目标。更进一步,如果在图片中检测到人脸,我们希望能识别出人的情绪表情。最终呈现出如图 3.1 的效果:
图 3.1 实现目标
Jupyter Notebook:
。Tensorflow
。Keras
Flickr8k Dataset:该数据集已经成为研究基于句子的图片描述的基准,该数据集包括了 8052 张图片,每张图片包括了 5 句相关的描述性句子,示例如下:
图 1 数据集的示例
Jupyter Notebook:
。Tensorflow
。Keras
大写转换为小写,删除标点符号,去除单复数等,实现效果如图 4.1 所示:
图 4.1 原数据表示
图 4.2 处理后的数据表示
将所有在描述语言中出现过的单词组成一个 vocabulary,统计在 vocabulary 中出现过的单词。起初计算出约 40000 个语句中总共出现 8763 个单词,但由于许多单词只出现两三次,对于预测性的模型来说,无实质性的帮助,因此接下来我们只考虑在所有语句中出现次数大于十的单词,计算出此时的 vocabulary 中就变为 1651 个单词。更进一步,我们还要多增加一个 0 padding,因此总单词数为 1652。可参考图 4.3 的流程:
图 4.3 Unique words 统计
运用 InceptionV3 模型将图片转换为一个固定长度(length=2018)的向量,使其可以作为输入到神经网路。
InceptionV3 原来是给图片分类的模型,由于我们的目标只是提取图片的特征向量,我们就移去了最后的 softmax 层,从倒数第二层中提取特征向量,如图 4.4 所示:
图 4.4 特征向量的提取
将每个 vocabulary 中的词编码为一个固定大小的向量,并创建两个 Pyhon 的 Dictionary,分别为 wordtoix[‘abc’]:返回’abc’的索引;ixtoword[k]:返回索引为“k“的单词,每个单词的索引为 1-1652 的其中一个整数。
计算 caption 的最大长度:34
(在此举一个例子以更好地阐释)
eg. 以两张训练图片一张测试图片组成,如图 4.5 所示:
图 4.5 实例
Caption_1 -> “startseq the black cat sat on grass endseq”
Caption_2 -> “startseq the white cat is walking on road endseq”
vocab = {black, cat, endseq, grass, is, on, road, sat, startseq, the, walking, white}
black -1, cat -2, endseq -3, grass -4, is -5, on -6, road -7, sat -8, startseq -9, the -10, walking -11, white -12
图 4.6 单词依次预测以组成 caption
将每个单词以索引来表示,效果如 4.7 所示:
图 4.7 将 partial caption 用索引表示
将 caption 补全为同一长度,统一的长度即为之前计算出的 caption 最大数 34,补全的元素为 0,即所谓的 0 padding,效果如 4.8 所示:
图 4.8 zero padding
图 5.1 模型的流程思路
如图 5.1 所示,我们希望以 partial caption 和图片的特征向量为输入,因此起初会有两个 tensor。首先 partial caption 经过预处理得到长度为 34 的向量后经过一个 embedding 层,把每个单词都映射到一个长度为 200 的向量,经过一层 Dropout 防止过拟合,之后经过一层 LSTM(选择 LSTM 的原因:LSTM 在自然语言的处理中能发挥不错的作用,并且相比普通的 RNN,LSTM 在更长的序列中有更好的表现)得到一个(batch_size,256)的输出。
同时,图片的特征向量经过一层 Dropout 防止过拟合,之后再经过一层全连接层同样得到一个(batch_size,256)的输出。
我们把两个格式相同的 tensor 合为一个,以便更好的训练得出最终结果,之后再经过一个全连接层后,经最后一层 softmax 层,产生涵盖 1652 个在 vocabulary 出现的单词的概率分布,基于 greedy search,概率分布最大的单词即我们要选择的输出单词。具体实例如图 5.2 所示
图 5.2 迭代的具体实现实例
迭代循环的终止条件有两个:
以“endseq“结尾,模型认为 caption 已经完成
句长大于 34,为了避免一直迭代下去,强制终止
我们训练这个模型设定了 epoch 为 30,前 20 个 epoch 的学习率设为 0.001,batch size 设为 3。当完成了 20 次迭代后,将学习率降为 0.0001 并且将 batch size 设为 6。用这些超参数的原因是因为当训练到达后半程时,模型逐渐趋向平缓,我们必须减小学习率才能在最低点边缩小步长,以趋近最低点。并且,适当的增加 batch size 使梯度的更新更加有效。
本模型的预测结果使用 BLEU 进行预测。
BLEU 能作为机器翻译的一个评估指。它采用了 N-gram 的匹配规则,能够算出比较译文和参考译文之间 n 组词的相似的一个占比。随着 n-gram 的增大,总体的精度得分是呈指数下降的,所以一般 N-gram 最多取到 4-gram。
一般情况 1-gram 可以代表原文有多少词被单独翻译出来,可以反映译文的充分性,2-gram 以上可以反映译文的流畅性,它的值越高说明可读性越好。这两个指标是能够跟人工评价对标的。
图 5.3.1 1-gram 准确度(该例为 5/6)
图 5.3.2 2-gram 准确度(该例为 3/5)
图 5.3.3 3-gram 准确度(该例为 1/4)
N-gram 的一个弊端是其译文准确度的匹配关系不能很好地体现译文长度不准确的问题。因此,针对翻译译文长度比参考译文要短的情况,就需要一个惩罚的机制去控制。在此便引入了惩罚因子的概念。惩罚因子的计算公式如下:
图 5.4 惩罚因子 BP 的计算
C 是测试译文的词数,r 是参考译文的词数
BLEU 算法就是在这两个概念的基础上整合得到,其计算公式如图 5.5 所示,BLEU 值越大表示测试译文与参考译文越接近,反之则差别越大。
图 5.5 BLEU 算法的计算公式
经过分析,我们发现 BLEU 尽管在一定程度上可以作为测试出的 caption 和原 caption 的评估指标,也比较方便和快捷,但它无法考虑语法上的准确性,测评的精度也会收到常用词的干扰。同时 BLEU 无法考虑同义词或相似表达的情况,因此作为该实验的评估指标还是存在一定的缺陷。
图 6.1 比较理想的测试结果
图6.2 不太理想的测试结果
针对实验结果,我们发现测试样例中有匹配度高的 caption,也有结果不太理想的测试结果,分析后我们认为:部分测试对图片中的数目、颜色或人物性别的检测出现差错,可能是特征提取的弊端造成的,因此未来优化时可以采取更好的特征提取模型(如 vgg 等);此外由于该数据集不够大,对模型的训练并不能达到很理想的效果,因此我们需要更大的数据集去训练它(实际操作中,我们有尝试用更大的数据集,但因为 CPU 的限制,最终没有跑出来);针对优化,我们还提出了可以调整超参数优化模型训练、用交叉验证集避免过拟合、并寻找比 BLEU 更好的检测结果的方法等。
– Human Images Source-CK+: http://www.consortium.ri.cmu.edu/ckagree/
– Human Images Source-Kaggle Dataset: https://www.kaggle.com/jonathanoheix/face-expression-recognition-dataset
– Human Images Source-Jaffebase Dataset: http://www.kasrl.org/jaffe.html
– Animated Images Source-FERG_DB: https://grail.cs.washington.edu/projects/deepexpr/ferg-db.htmlhttps://grail.cs.washington.edu/projects/deepexpr/ferg-db.html)
最左边的每个文件夹对应一个人;
中间的每个文件夹对应一个人的一组表情序列图片;
最右边的一组图片记录的是从面无表情到表情饱满的过程:见下图