python|基于Python实现看图说话和微表情识别

1. 设计思想 对于人类来说,描述一张图片的内容是非常重要的。但因这个过程并没有标准答案,因此对于计算机来说这并不是一个简单地过程。我们希望通过本次实验能够设计一个模型完成让计算机给图片设定 caption 的目标。更进一步,如果在图片中检测到人脸,我们希望能识别出人的情绪表情。最终呈现出如图 3.1 的效果:
python|基于Python实现看图说话和微表情识别
文章图片

图 3.1 实现目标
2. 实验环境和工具 Jupyter Notebook:
。Tensorflow
。Keras
3. 实验过程 3.1 看图说话 3.1.1 数据集介绍
Flickr8k Dataset:该数据集已经成为研究基于句子的图片描述的基准,该数据集包括了 8052 张图片,每张图片包括了 5 句相关的描述性句子,示例如下:
python|基于Python实现看图说话和微表情识别
文章图片

图 1 数据集的示例
3.1.2 实验环境和工具
Jupyter Notebook:
。Tensorflow
。Keras
3.1.3 数据预处理
3.1.3.1 基本的数据清理 大写转换为小写,删除标点符号,去除单复数等,实现效果如图 4.1 所示:
python|基于Python实现看图说话和微表情识别
文章图片

图 4.1 原数据表示
python|基于Python实现看图说话和微表情识别
文章图片

图 4.2 处理后的数据表示
3.1.3.2 Unique words 的统计 将所有在描述语言中出现过的单词组成一个 vocabulary,统计在 vocabulary 中出现过的单词。起初计算出约 40000 个语句中总共出现 8763 个单词,但由于许多单词只出现两三次,对于预测性的模型来说,无实质性的帮助,因此接下来我们只考虑在所有语句中出现次数大于十的单词,计算出此时的 vocabulary 中就变为 1651 个单词。更进一步,我们还要多增加一个 0 padding,因此总单词数为 1652。可参考图 4.3 的流程:
python|基于Python实现看图说话和微表情识别
文章图片

图 4.3 Unique words 统计
3.1.3.3 特征向量的提取 运用 InceptionV3 模型将图片转换为一个固定长度(length=2018)的向量,使其可以作为输入到神经网路。
InceptionV3 原来是给图片分类的模型,由于我们的目标只是提取图片的特征向量,我们就移去了最后的 softmax 层,从倒数第二层中提取特征向量,如图 4.4 所示:
python|基于Python实现看图说话和微表情识别
文章图片

图 4.4 特征向量的提取
3.1.3.4 词编码 将每个 vocabulary 中的词编码为一个固定大小的向量,并创建两个 Pyhon 的 Dictionary,分别为 wordtoix[‘abc’]:返回’abc’的索引;ixtoword[k]:返回索引为“k“的单词,每个单词的索引为 1-1652 的其中一个整数。
3.1.3.5 计算长度 计算 caption 的最大长度:34
3.1.3.6 data matrix 的构建过程 (在此举一个例子以更好地阐释)
eg. 以两张训练图片一张测试图片组成,如图 4.5 所示:
python|基于Python实现看图说话和微表情识别
文章图片

python|基于Python实现看图说话和微表情识别
文章图片

python|基于Python实现看图说话和微表情识别
文章图片

图 4.5 实例

  • 将 image1、image2 转换为长度为 2048 地特征向量
  • 给清理过的 caption 加上头尾标志(startseq、endseq)
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}

  • 给 vocabulary 中的单词分配整数索引
black -1, cat -2, endseq -3, grass -4, is -5, on -6, road -7, sat -8, startseq -9, the -10, walking -11, white -12

  • 为了预测 caption 中的第 t+1 个单词,我们可以通过前 t 个单词组成的部分的 caption 和图片的特征向量来进行。预测 caption 从 startseq 开始直到 endseq 结束,如图 4.6 所示:
python|基于Python实现看图说话和微表情识别
文章图片

图 4.6 单词依次预测以组成 caption
将每个单词以索引来表示,效果如 4.7 所示:
python|基于Python实现看图说话和微表情识别
文章图片

图 4.7 将 partial caption 用索引表示
将 caption 补全为同一长度,统一的长度即为之前计算出的 caption 最大数 34,补全的元素为 0,即所谓的 0 padding,效果如 4.8 所示:
python|基于Python实现看图说话和微表情识别
文章图片

图 4.8 zero padding
3.1.4 模型搭建
python|基于Python实现看图说话和微表情识别
文章图片

图 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 所示
python|基于Python实现看图说话和微表情识别
文章图片

图 5.2 迭代的具体实现实例
迭代循环的终止条件有两个:
  • 以“endseq“结尾,模型认为 caption 已经完成
  • 句长大于 34,为了避免一直迭代下去,强制终止
3.1.5 模型的训练
我们训练这个模型设定了 epoch 为 30,前 20 个 epoch 的学习率设为 0.001,batch size 设为 3。当完成了 20 次迭代后,将学习率降为 0.0001 并且将 batch size 设为 6。用这些超参数的原因是因为当训练到达后半程时,模型逐渐趋向平缓,我们必须减小学习率才能在最低点边缩小步长,以趋近最低点。并且,适当的增加 batch size 使梯度的更新更加有效。
3.1.6 模型评估
本模型的预测结果使用 BLEU 进行预测。
BLEU 能作为机器翻译的一个评估指。它采用了 N-gram 的匹配规则,能够算出比较译文和参考译文之间 n 组词的相似的一个占比。随着 n-gram 的增大,总体的精度得分是呈指数下降的,所以一般 N-gram 最多取到 4-gram。
一般情况 1-gram 可以代表原文有多少词被单独翻译出来,可以反映译文的充分性,2-gram 以上可以反映译文的流畅性,它的值越高说明可读性越好。这两个指标是能够跟人工评价对标的。
python|基于Python实现看图说话和微表情识别
文章图片

图 5.3.1 1-gram 准确度(该例为 5/6)
python|基于Python实现看图说话和微表情识别
文章图片

图 5.3.2 2-gram 准确度(该例为 3/5)
python|基于Python实现看图说话和微表情识别
文章图片

图 5.3.3 3-gram 准确度(该例为 1/4)
N-gram 的一个弊端是其译文准确度的匹配关系不能很好地体现译文长度不准确的问题。因此,针对翻译译文长度比参考译文要短的情况,就需要一个惩罚的机制去控制。在此便引入了惩罚因子的概念。惩罚因子的计算公式如下:
python|基于Python实现看图说话和微表情识别
文章图片

图 5.4 惩罚因子 BP 的计算
C 是测试译文的词数,r 是参考译文的词数
BLEU 算法就是在这两个概念的基础上整合得到,其计算公式如图 5.5 所示,BLEU 值越大表示测试译文与参考译文越接近,反之则差别越大。
python|基于Python实现看图说话和微表情识别
文章图片

图 5.5 BLEU 算法的计算公式
经过分析,我们发现 BLEU 尽管在一定程度上可以作为测试出的 caption 和原 caption 的评估指标,也比较方便和快捷,但它无法考虑语法上的准确性,测评的精度也会收到常用词的干扰。同时 BLEU 无法考虑同义词或相似表达的情况,因此作为该实验的评估指标还是存在一定的缺陷。
3.1.7 测试结果
3.1.7.1 较理想的测试结果: python|基于Python实现看图说话和微表情识别
文章图片

python|基于Python实现看图说话和微表情识别
文章图片

python|基于Python实现看图说话和微表情识别
文章图片

python|基于Python实现看图说话和微表情识别
文章图片

图 6.1 比较理想的测试结果
3.1.7.2 不太理想的测试结果 python|基于Python实现看图说话和微表情识别
文章图片

图6.2 不太理想的测试结果
3.1.7.3 结果分析: 针对实验结果,我们发现测试样例中有匹配度高的 caption,也有结果不太理想的测试结果,分析后我们认为:部分测试对图片中的数目、颜色或人物性别的检测出现差错,可能是特征提取的弊端造成的,因此未来优化时可以采取更好的特征提取模型(如 vgg 等);此外由于该数据集不够大,对模型的训练并不能达到很理想的效果,因此我们需要更大的数据集去训练它(实际操作中,我们有尝试用更大的数据集,但因为 CPU 的限制,最终没有跑出来);针对优化,我们还提出了可以调整超参数优化模型训练、用交叉验证集避免过拟合、并寻找比 BLEU 更好的检测结果的方法等。
3.2 微表情识别 3.2.1 数据集
3.2.1.1 来源 – 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)
3.2.1.2 特点展示
  • CK+ Dataset:
python|基于Python实现看图说话和微表情识别
文章图片

最左边的每个文件夹对应一个人;
中间的每个文件夹对应一个人的一组表情序列图片;
最右边的一组图片记录的是从面无表情到表情饱满的过程:见下图
python|基于Python实现看图说话和微表情识别
文章图片

  • Kaggle Dataset:已经划分好 train 和 validation 集合,见下图:
python|基于Python实现看图说话和微表情识别
文章图片

  • Jaffebase Dataset:文件夹中所有的图片都可以通过文件名字划分表情类别,见下图
python|基于Python实现看图说话和微表情识别
文章图片

  • FERG_DB Dataset:动漫表情,且图片已经按照表情类别分类,见下图:
【python|基于Python实现看图说话和微表情识别】python|基于Python实现看图说话和微表情识别
文章图片

    推荐阅读