天池视频问答第16名,使用Keras,videoqa

视频问答,video qa using keras。天池江之杯视频问答大赛


问题描述

根据给定的短视频进行内容识别和分析,并回答每一个视频对应的问题。即给定一个视频,与任意的问题,模型根据视频对问题进行回答。
比赛地址:https://tianchi.aliyun.com/competition/introduction.htm?spm=5176.11165320.5678.1.538b325ckj6OVi&raceId=231676

项目地址(包含所有代码,可复现)

https://github.com/SummerRaining/videoqa_keras

成绩

复赛第16名


result.jpg

模型思路:

  • 总体思路:
    • a.句子通过lstm编码成1024维的向量;
    • b.视频均匀截取30帧后通过resnet152提取2048维的特征,通过句子向量对30个视频帧做attention。
    • c. 将attention后的视频向量与句子向量做融合(点乘),接上两个全连接到1000维。
    • d. 损失使用sigmoid,避免类间竞争,logloss。
    • e. 由于大部分答案都是重复的,故可以考虑成分类问题,选频率最高的1000个答案作为所有类别,对于不在1000个类别中的答案舍弃。每个问题有三个答案,故这是一个多标签问题。
  • 对于问题句子,最大的句子长度为19,固定所有的句子长度维19(由于不是很长)。使用embedding成19*300的矩阵,通过隐藏层为512的双层lstm,得到的结果为512维向量,即为句子向量。
  • 对于视频,均匀地截取30帧(第一名大佬好像是截取的关键帧),通过resnet152提取到2048维的特征。得到30*2048维的特征,使用句子向量对30个视频帧向量做attention。
    1. 将q全连接到[batch,h_dim],将v全连接到[batch,30,h_dim]
    2. q,v点乘。加上dropout,再使用一个全连接到1。[batch,30,1]
    3. L2标准化,softmax
1.jpg
  1. 融合:将句子向量全连接到1024维,视频向量也全连接到1024维,对其进行点乘,tanh做为激活函数。再添加两个全连接,输出结果为1000为的向量对应答案的概率。
  2. 损失:由于这是多标签问题,使用sigmoid激活函数而不是softmax,避免标签类竞争(softmax相加等于1)。loss = -y*log(y\_pred) - (1-y)*log(1-y\_pred)

模型改进residual block

原有的模型使用attention的方法是在多张图片中挑选一张最符合答案的图片,但是依然是使用一张图片回答问题,无法获得视频的动作特征。
我在这里尝试添加新的模型结构,以获取动作信息。

  1. 对代表30张图片的30×2048的特征矩阵,在30这个方向做一维的卷积,filter size = 3。这样就相当与大小为3的窗口在30个特征上滑动,每次滑动都产生一个特征。由于结合了相邻的三张图片的信息,得到的特征可以反应动作信息。

  2. 对特征做两次3*2048一维的卷积,由于这样可能打乱原有的静态特征。于是我们添加residual block,两次卷积之后加上原有的输入。
    <div align=center><img src="./1_pUyst_ciesOz_LUg0HocYg.png"/></div>

    1_pUyst_ciesOz_LUg0HocYg.png

  3. 这样视频特征就能代表静态和动态的信息,接下来使用attention,模型其他部分不变。

  4. 结果大概提升0.5-1%。改进并不明显,可能是帧率不固定或者结构比较简单无法很好的学习到动作信息。

其他尝试

添加c3d网络用于获得动作信息,将c3d与resblock进行融合。并没有得到明显提高,可能c3d并不能很好的获取动作信息


训练细节,tricks

  1. 训练时使用了lr reduce,当loss不在较小的时候,学习率下降10倍。
  2. early stop,一定次数后loss不下降,就停止训练。
  3. unfreeze,先不对词向量层训练。训练30个epoch后,再对解冻词向量层进行训练,能提高1-2个百分点。
  4. 模型融合,训练30个模型,分别对测试集预测。并将得到的概率求平均,上升2-3个百分点。

文件安排

  • 文件结构总结:
 |- master
    readme.md
    |- pretrain_model
        c3d                         #包含c3d的模型结构和模型参数,download from internet
        resnet152                   #包含resnet152的模型结构和模型参
        c3d.py                      #定义调用c3d的模型和预处理函数的方法
        resnet152.py                #定义调用resnet152的模型和预处理函数的方法
    |- utils
        preteatment.py          #生成单词到词向量的对应关系,answer到编号的对应关系。将问题和答案编码后划分验证集和训练集
        wordans_to_index.json   
        embed_matrix.h5
        train_encode.txt
        val_encode.txt
    |- data
        |- glove.6B             #glove词向量,网上下载的
        |- train
        |- test
        train.txt
        test.txt
    |- images
        |- image
        get_pic.py
        get_picc3d.py
    |- attmfl_res                   #每个模型文件夹,包含视频特征读取文件,视频名对应的序号
        get_feature.py              #提取对每个视频提取30个2048维的resnet特征,保存在feature/resnet 152中
         attention.py               #构造attention类
         model.py                   #构造模型结构
         my_dataset.py              #构造dataset类,产生迭代器,用于model.fit\_generator
        attmflres.py                #根据dataset和model,生成并训练模型,为了使用模型融合,我们这里生成了30个模型(60epoch)
        predict_prob.py             #根据生成的模型,预测test集上的概率。
        model                       #存放生成的模型
        prob_res                    #预测测试集上的概率
    ...
   |- cnn_res                      #与attmfl_res的文件结构相同,模型增加了residual block部分
   ...

demo

单个视频test:

不想训练模型,只是运行模型看看效果的话,可以运行test.py文件。

  • 将编码方式: wordans_to_index.json , embed_matrix.h5,模型,预训练模型下载放入对应文件。链接
  • 命令:python test.py main --model_path='attmfl_res/models/1' --video= 'test/1.mp4'
  • 需要把模型下载到attmfl_res/models/1目录下面。视频放在test文件,当然也可以通过上面的命令自己指定路径
  • 注:我在提交文件的时候,实际上使用了30个不同的模型分别预测,然后将预测的概率取平均的,结果大概高3个百分点(使用TTA可能效果更佳)。这里为了简便只使用一个模型。

运行结果:

example.png
  • 输入question: what is in the video
  • answer: television
  • 输入question: where is the person in the video
  • answer: indoor
  • question: what color clothes does the person wear in the video
  • answer: grey

train:

使用自己的视频和对应问题来训练模型:

  1. 将train.txt和test.txt,视频,下载的glove词向量放在data文件夹下。glove地址
  2. 运行image/get_pic.py,将每段视频截取30张图片,分成训练集和验证集放在images下。
  3. 运行utils/pretreament.py将数据划分成训练集和验证集,并将问题与答案编码。
  4. 运行attmfl_res/get_feature.py,将图片的resnet特征放到features/resnet152中。
  5. 运行attmfl_res/attmflres.py开始训练。默认训练30个模型,每个模型训练60个epoch,前30个冻结embedding层,后30个解冻。

使用江之杯的数据

  1. 我将截取的图片和编码好的数据已打包上传至链接,下载并解压到对应文件夹。
  2. 运行attmfl_res/get_feature.py提取特征,和attmfl_res/attmflres.py训练模型。

test:

usage:

  1. 运行attmfl_res/predict_prob.py,用训练的30个模型分别预测test概率
  2. 运行merge_prob.py,融合预测的概率。并生成预测文件。

文件预处理说明

  • 在所有answers中取出现频率最高的前1000个作为所有类别。
  • word_to_index决定了embed_matrix的每行向量与单词的对应关系;ans_to_index和word_to_index决定了encode_data单词和答案的对应编码。而后续所有训练的模型都与其有关,一旦修改,所有模型将无效。生成之后谨慎修改。
  • 下载的glove300词向量上包含40 0000个单词,而我们这个问题没有涉及那么多单词。所以调整词向量矩阵为只用出现过的单词。问题中出现部分错别单词不在词向量中,如:girl ->gril,我们使用enchant纠错。
  • 编码词汇处理方案:
    • 将所有的questions的词汇进行纠错。question中的每个词如果不在glove中就按enchant的建议转换。
    • 然后将所有纠错的问题,提取出词汇。与glove的所有词汇做交集,生成vocabulary。
    • 这样保证了vocabulary包含了:1. 所有在glove的问题词汇 、2. 不在glove中的词汇,纠错后在glove中的词汇
    • 而纠错之后还不在glove中的词汇,在编码过程中就舍弃它(由于数量和出现次数都极少,直接舍弃没有影响)

项目亮点

  1. 使用sigmoid + crossentropy来处理多标签问题,避免类间竞争。后续改进使用focal loss来针对训练困难样本。
  2. 对每个视频截取30个图像,由于并不是每张图片都能回答问题。所以引入注意力的机制:“让问题来挑选能够回答它的图片”。
  3. 对问题中的错误词汇,进行纠错。并合理构建词汇表而不是直接使用,错误的词汇构建词汇表。
  4. 改变模型结构,增强residual block,让模型获得一些动作信息。

项目地址(包含所有代码,可复现)

https://github.com/SummerRaining/videoqa_keras

  • 要是诸君觉得还阔以的话,star,点赞走一波呗。
  • 欢迎讨论,能力有限,欢迎大佬指正。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352