情感識(shí)別實(shí)戰(zhàn):CNN+RNN融合音頻與視頻的復(fù)現(xiàn)與避坑指南)
簡(jiǎn)介資源為東南大學(xué)發(fā)表于《Journal of Southeast University》的學(xué)術(shù)論文PDF系統(tǒng)探討基于深度神經(jīng)網(wǎng)絡(luò)的多模態(tài)情感識(shí)別方法面向從事情感計(jì)算、人機(jī)交互及深度學(xué)習(xí)應(yīng)用的研究者與高年級(jí)學(xué)生。文中重點(diǎn)分析了CNN用于音頻與視頻低級(jí)特征提取、RNN用于時(shí)序動(dòng)態(tài)信息建模并提出了混合CNN與RNN的識(shí)別框架通過(guò)頻譜特征、能量函數(shù)、面部表情與動(dòng)作特征等多模態(tài)融合在CCPR 2016中文視聽(tīng)情感數(shù)據(jù)庫(kù)上取得了41.15%的平均識(shí)別精度比基線提升16.62%。包內(nèi)文件為1個(gè)PDF文檔壓縮包大小約714KB內(nèi)容包含完整摘要、方法與實(shí)驗(yàn)細(xì)節(jié)適合直接閱讀學(xué)習(xí)。目前已有233人學(xué)習(xí)下載對(duì)剛?cè)腴T多模態(tài)情感識(shí)別或希望了解CNN/RNN組合建模的讀者具有一定的參考價(jià)值。1. 多模態(tài)情感識(shí)別這篇 2017 年的論文憑什么漲了 16.62%把聲音和表情同時(shí)交給深度神經(jīng)網(wǎng)絡(luò)讓機(jī)器判斷說(shuō)話的人現(xiàn)在是開(kāi)心、憤怒還是焦慮——這是多模態(tài)情感識(shí)別最樸素的目標(biāo)。這篇 2017 年發(fā)表于《東南大學(xué)學(xué)報(bào)英文版》第 4 期的論文只有 4 頁(yè)作者來(lái)自東南大學(xué)生物科學(xué)與醫(yī)學(xué)工程學(xué)院卻用一套“1D CNN 雙向 RNN”處理音頻、“2D CNN RNN”處理視頻的完整方案在 CCPR 2016 多模態(tài)情感識(shí)別挑戰(zhàn)賽的 CHEAVD 中文自然音視頻情感數(shù)據(jù)庫(kù)上把多模態(tài)平均精度做到了 41.15%比組委會(huì)給出的基線高出 16.62 個(gè)百分點(diǎn)。對(duì)正在做復(fù)雜場(chǎng)景下多模態(tài)情感預(yù)測(cè)建模、或者想找一個(gè) CNN RNN 端到端融合模板的人來(lái)說(shuō)這篇論文最大的價(jià)值不是數(shù)學(xué)上多驚艷而是結(jié)構(gòu)完整、公開(kāi)參數(shù)充足、踩坑點(diǎn)明確非常適合照著復(fù)現(xiàn)再改造。2. 音頻分支openSMILE 特征 1D CNN B-RNN 怎么串起來(lái)2.1 為什么音頻分支要設(shè)計(jì)成 1D CNN RNN 的組合音頻情感識(shí)別最經(jīng)典的做法是手工提一大堆統(tǒng)計(jì)特征然后塞進(jìn) SVM 或隨機(jī)森林。這套路子的瓶頸很明顯特征工程決定上限換個(gè)數(shù)據(jù)集就得重新調(diào)特征。論文的做法是把音頻當(dāng)成一維時(shí)序信號(hào)先用卷積網(wǎng)絡(luò)做局部特征抽象再用循環(huán)網(wǎng)絡(luò)捕捉音調(diào)隨時(shí)間變化的動(dòng)態(tài)本質(zhì)上就是語(yǔ)音識(shí)別里“CNN 提特征 RNN 管時(shí)序”的遷移。為什么不是純 CNN 或純 RNN純 CNN 對(duì)局部模式敏感但音頻里的情感表達(dá)往往依賴前后語(yǔ)段的音調(diào)起伏卷積核的感受野有限純 RNN 能建模時(shí)序依賴但對(duì)原始頻譜這種高維輸入直接建模收斂速度和特征抽象能力都不如 CNN。把兩者串起來(lái)等于讓 CNN 先干粗活、把原始頻譜壓成緊湊的高層特征RNN 再干細(xì)活、專門看這些特征在時(shí)間軸上怎么變化。這個(gè)分工在情感識(shí)別里被反復(fù)驗(yàn)證過(guò)是低成本高收益的結(jié)構(gòu)選擇。2.2 openSMILE 特征提取論文里沒(méi)說(shuō)全的細(xì)節(jié)這一步是整條鏈路里最容易出偏差的地方。論文說(shuō)得很簡(jiǎn)單用 openSMILE 按 INTERSPEECH 2010 Paralinguistic Challenge 的配置提取 MFCC 等頻帶與能量特征。但實(shí)際跑起來(lái)你會(huì)發(fā)現(xiàn)openSMILE 的配置文件和版本會(huì)直接影響輸出維度哪怕同一個(gè)配置名不同版本解析出來(lái)的特征列表也可能不一樣。openSMILE 的命令行工具是 SMILExtract常用方式如下SMILExtract -C IS10_paraling_compat.conf \ -I audio.wav \ -O audio_features.csv這里-C指定配置文件-I是輸入音頻-O是輸出特征文件。IS10_paraling_compat.conf 是 INTERSPEECH 2010 挑戰(zhàn)賽的兼容配置提取的是幀級(jí) MFCC 加上能量、過(guò)零率等低級(jí)描述符。論文里對(duì)音頻信號(hào)的預(yù)處理是“固定幀長(zhǎng)、相鄰幀共享固定采樣點(diǎn)”這個(gè)在 openSMILE 里對(duì)應(yīng) frameSize 和 frameStep 兩個(gè)參數(shù)常見(jiàn)做法是 25ms 幀長(zhǎng)、10ms 幀移相鄰幀有 15ms 重疊保證局部和全局信息都不丟。2.3 音頻網(wǎng)絡(luò)骨架PyTorch 實(shí)現(xiàn)思路與 attention 對(duì)齊層論文的音頻網(wǎng)絡(luò)是四層 1D CNN 加池化再接雙向 RNN最后加了一個(gè) alignment 層——也就是注意力機(jī)制給每個(gè)時(shí)間步的隱藏狀態(tài)分配權(quán)重。下面是我按論文結(jié)構(gòu)搭的示意骨架不是原文代碼但結(jié)構(gòu)和超參對(duì)齊了論文 Tab.1 的卷積核數(shù)量 32→32→64→64import torch import torch.nn as nn class TemporalAttention(nn.Module): 對(duì)齊層給 RNN 每個(gè)時(shí)間步的隱藏狀態(tài)加權(quán)求和 def __init__(self, hidden_dim): super().__init__() self.score nn.Linear(hidden_dim, 1) def forward(self, h): # h: (batch, seq_len, hidden_dim) w torch.softmax(self.score(h), dim1) # 每個(gè)時(shí)間步的權(quán)重 return torch.sum(w * h, dim1) # 加權(quán)后的全局表示 class AudioBranch(nn.Module): def __init__(self, feat_dim158, rnn_hidden128, num_emotions8): super().__init__() # 1D CNN 局部特征抽象通道數(shù)按論文 32-32-64-64 self.conv1 nn.Conv1d(feat_dim, 32, kernel_size3, padding1) self.pool1 nn.MaxPool1d(2) self.conv2 nn.Conv1d(32, 32, kernel_size3, padding1) self.pool2 nn.MaxPool1d(2) self.conv3 nn.Conv1d(32, 64, kernel_size3, padding1) self.pool3 nn.MaxPool1d(2) self.conv4 nn.Conv1d(64, 64, kernel_size3, padding1) self.pool4 nn.MaxPool1d(2) self.rnn nn.GRU(64, rnn_hidden, bidirectionalTrue, batch_firstTrue) self.attn TemporalAttention(rnn_hidden * 2) self.fc nn.Linear(rnn_hidden * 2, num_emotions) def forward(self, x): # x: (batch, seq_len, feat_dim) x x.permute(0, 2, 1) # 轉(zhuǎn)成 (batch, feat_dim, seq_len) x self.pool1(torch.relu(self.conv1(x))) x self.pool2(torch.relu(self.conv2(x))) x self.pool3(torch.relu(self.conv3(x))) x self.pool4(torch.relu(self.conv4(x))) x x.permute(0, 2, 1) # 轉(zhuǎn)回 (batch, time, channels) out, _ self.rnn(x) out self.attn(out) return self.fc(out)這段代碼有兩個(gè)地方需要特別注意。第一feat_dim158是從論文 Tab.1 的輸入維度推測(cè)的實(shí)際要以你 openSMILE 輸出的特征列為準(zhǔn)配置不同這個(gè)數(shù)字就可能變成 130 多或者 180 多網(wǎng)絡(luò)第一層輸入必須跟著改。第二四層池化窗口都是 2如果輸入序列長(zhǎng)度本來(lái)就是 50四次池化后時(shí)間維只剩下 3RNN 基本學(xué)不到時(shí)序依賴。論文里的做法是讓部分卷積層步長(zhǎng)為 1池化并不總在時(shí)間維上壓縮所以你復(fù)現(xiàn)時(shí)一定要根據(jù)自己的序列長(zhǎng)度調(diào)整池化次數(shù)這是音頻分支最容易翻車的地方。2.4 論文沒(méi)有明說(shuō)的幾個(gè)參數(shù)位置論文對(duì)音頻網(wǎng)絡(luò)結(jié)構(gòu)的描述濃縮在一張表里關(guān)鍵信息是四層卷積的卷積核數(shù)量依次為 32、32、64、64卷積核大小為 3池化窗口為 2但步長(zhǎng)是 1 還是 2 原文沒(méi)寫(xiě)清楚。這里我建議按自己的輸入序列長(zhǎng)度反推目標(biāo)是讓進(jìn)入 RNN 之前的時(shí)間維不低于 10否則雙向 RNN 能看到的上下文太短。另一個(gè)值得注意的點(diǎn)是 RNN 用的是 BRNN也就是雙向結(jié)構(gòu)代碼里用bidirectionalTrue實(shí)現(xiàn)hidden 維度要記得乘 2。alignment 層對(duì)應(yīng)論文里的公式 4 和 5作用是給每個(gè)隱藏狀態(tài)一個(gè)可學(xué)習(xí)的權(quán)重然后加權(quán)求和作為全局表示。這一步在代碼里就是 TemporalAttention 做的事它讓網(wǎng)絡(luò)不再只依賴最后一個(gè)時(shí)間步的輸出而是綜合整段音頻的貢獻(xiàn)。實(shí)踐里的收益主要體現(xiàn)在憤怒、焦慮這類情緒轉(zhuǎn)折較多的樣本上因?yàn)檫@些情緒往往在中段爆發(fā)最后一步未必包含全部信息。3. 視頻分支Faster-RCNN 人臉裁剪與 VGG-Face16 微調(diào)的取舍3.1 Faster-RCNN 人臉裁剪自動(dòng)檢測(cè) 人工糾錯(cuò)的平衡視頻分支的第一步不是直接抽幀而是先把人臉區(qū)域裁出來(lái)。論文用的是 Faster-RCNN 檢測(cè)器把每一幀的人臉框檢測(cè)出來(lái)后裁剪并 resize 到統(tǒng)一尺寸。這一步看似預(yù)處理實(shí)際對(duì)最終結(jié)果影響非常大如果人臉框偏了VGG-Face16 提取的特征里混入大量背景后面的時(shí)序模型學(xué)到的全是噪聲。比較容易被忽略的是論文里的這句話裁剪結(jié)果需要逐張人工檢查把檢測(cè)錯(cuò)誤的框手動(dòng)修正。在 CHEAVD 這種自然場(chǎng)景數(shù)據(jù)集里人臉遮擋、側(cè)臉、出境是常態(tài)Faster-RCNN 再?gòu)?qiáng)也扛不住所有情況。對(duì)小規(guī)模數(shù)據(jù)集來(lái)說(shuō)人工修正幾百?gòu)垐D的時(shí)間成本是值得的因?yàn)榕K特征會(huì)順著整條網(wǎng)絡(luò)傳播到最后的融合層到時(shí)候再回頭排查就晚了。3.2 VGG-Face16 微調(diào)凍結(jié)卷積層只動(dòng)最后三個(gè) FCVGG-Face16 是 16 層的 VGG 人臉識(shí)別預(yù)訓(xùn)練模型結(jié)構(gòu)是五段卷積網(wǎng)絡(luò)加三個(gè)全連接層加 softmax。論文做了一個(gè)很克制的選擇只取最后一個(gè)全連接層的輸出作為空間特征微調(diào)時(shí)凍結(jié)前面的卷積層只把最后三個(gè)全連接層隨機(jī)初始化并更新。為什么不全量微調(diào)情感識(shí)別數(shù)據(jù)集通常只有幾千到幾萬(wàn)張人臉圖而 VGG-Face16 是在百萬(wàn)級(jí)人臉數(shù)據(jù)上預(yù)訓(xùn)練的。全量微調(diào)意味著把已經(jīng)學(xué)好的通用人臉表征推翻重來(lái)在小數(shù)據(jù)上極易過(guò)擬合表情細(xì)節(jié)還沒(méi)學(xué)到loss 就下不去了。只微調(diào) FC 層的邏輯是淺層卷積已經(jīng)能提取邊緣、紋理、五官結(jié)構(gòu)這些通用特征真正需要重新學(xué)的是“什么樣的面部組合對(duì)應(yīng)什么情緒”這個(gè)映射關(guān)系而這正是 FC 層的職責(zé)。3.3 幀特征重排按相鄰幀差異挑關(guān)鍵幀的代碼思路視頻長(zhǎng)度不固定沒(méi)法直接拼特征。論文的解決思路很工程化計(jì)算相鄰兩幀特征的差異差異太小說(shuō)明表情幾乎沒(méi)變直接丟掉差異大說(shuō)明情緒在變化保留這一幀。選完后再按時(shí)間順序排列如果幀數(shù)不夠固定長(zhǎng)度就把第一幀復(fù)制幾份補(bǔ)在開(kāi)頭。這個(gè)邏輯用 NumPy 實(shí)現(xiàn)非常直觀import numpy as np def select_key_frames(feats, min_diff0.05, max_len50): feats: (T, D) 每幀經(jīng)過(guò) VGG-Face 提取的特征T 是幀數(shù) min_diff: 相鄰幀特征差異閾值小于該值視為無(wú)變化 max_len: BRNN 輸入序列的固定長(zhǎng)度 keep [0] for t in range(1, len(feats)): delta np.linalg.norm(feats[t] - feats[t - 1]) if delta min_diff: keep.append(t) # 少于固定長(zhǎng)度時(shí)復(fù)制首幀插入開(kāi)頭保持時(shí)間順序 if len(keep) max_len: keep [0] * (max_len - len(keep)) keep return np.array(keep[:max_len])min_diff是控制篩選強(qiáng)度的關(guān)鍵超參數(shù)論文沒(méi)有給出具體數(shù)值經(jīng)驗(yàn)是從 0.01 開(kāi)始按十倍粒度掃。閾值設(shè)太小幾乎每幀都保留序列長(zhǎng)度依然很長(zhǎng)閾值設(shè)太大關(guān)鍵表情轉(zhuǎn)折幀可能被丟掉。補(bǔ)齊時(shí)把第一幀插到開(kāi)頭而不是結(jié)尾是因?yàn)榍榫w表達(dá)的鋪墊信息通常在視頻前段直接復(fù)制首幀放在序列開(kāi)頭能保留這種時(shí)間關(guān)系插在結(jié)尾會(huì)破壞語(yǔ)義順序。如果你復(fù)現(xiàn)時(shí)發(fā)現(xiàn)多模態(tài)結(jié)果比單模態(tài)還差先回來(lái)看這一步的篩選邏輯。3.4 視頻數(shù)據(jù)增強(qiáng)旋轉(zhuǎn)、鏡像和 multi-PIE 補(bǔ)樣本CHEAVD 的八類情緒樣本數(shù)量并不均衡論文采取了兩個(gè)策略一是對(duì)選中的視頻序列做旋轉(zhuǎn)和鏡像旋轉(zhuǎn)角度取 ±7° 和 ±15°二是從 multi-PIE 人臉庫(kù)補(bǔ)充樣本當(dāng) multi-PIE 只有 5 類情緒時(shí)就把原本不夠的 3 類用 CHEAVD 里對(duì)應(yīng)類別的樣本按序號(hào)復(fù)制保證八類數(shù)量級(jí)一致。這個(gè)操作給數(shù)據(jù)增強(qiáng)提了個(gè)醒旋轉(zhuǎn)和鏡像對(duì)視頻時(shí)序模型是安全的因?yàn)槿四樤谝曨l里本來(lái)就會(huì)有輕微平面內(nèi)旋轉(zhuǎn)但像縮放、裁剪這類改變?nèi)四樋臻g結(jié)構(gòu)的增強(qiáng)要慎用VGG-Face16 對(duì)對(duì)齊后的人臉很敏感。multi-PIE 補(bǔ)數(shù)據(jù)的大方向沒(méi)問(wèn)題跨數(shù)據(jù)集補(bǔ)樣本時(shí)需要注意域差異——multi-PIE 是實(shí)驗(yàn)室人臉采集環(huán)境CHEAVD 是影視劇素材兩者的光照和分辨率差異可能導(dǎo)致模型學(xué)到數(shù)據(jù)集特征而非情緒特征。4. 融合與訓(xùn)練參數(shù)softmax 加權(quán)里的 α、β 和數(shù)據(jù)增強(qiáng)細(xì)節(jié)4.1 softmax 加權(quán)融合公式與 α、β 的調(diào)試順序多模態(tài)融合是這篇論文的核心賣點(diǎn)。音頻網(wǎng)絡(luò)和視頻網(wǎng)絡(luò)各自輸出一個(gè) softmax 分?jǐn)?shù)向量然后按類別加權(quán)求和取最大值對(duì)應(yīng)的類別作為最終預(yù)測(cè)。對(duì)應(yīng)論文公式 6C argmax_c ( α · s_audio(c) β · s_video(c) )其中 s_audio(c) 和 s_video(c) 分別是音頻網(wǎng)絡(luò)、視頻網(wǎng)絡(luò)對(duì)第 c 個(gè)類別的 softmax 分?jǐn)?shù)α 和 β 是兩路模態(tài)的權(quán)重C 是最終預(yù)測(cè)標(biāo)簽。這個(gè)公式看起來(lái)簡(jiǎn)單調(diào)起來(lái)卻有點(diǎn)玄學(xué)。我的做法是分三步走第一步先跑音頻單模態(tài)和視頻單模態(tài)記錄各自在驗(yàn)證集上的平均精度第二步固定較優(yōu)模態(tài)的權(quán)重為 1在 0.1 到 1.0 范圍內(nèi)搜索另一路權(quán)重第三步把 α 和 β 歸一化后微調(diào)。論文沒(méi)有明確說(shuō) α β 等于 1但實(shí)際使用時(shí)歸一化更方便解釋。一個(gè)值得注意的現(xiàn)象是如果某一模態(tài)單模態(tài)精度特別低它在融合里的貢獻(xiàn)往往不是正向的這時(shí)把它的權(quán)重壓到 0.3 以下反而能整體提升。4.2 訓(xùn)練超參總表三套參數(shù)分別對(duì)應(yīng)哪一路網(wǎng)絡(luò)論文的實(shí)驗(yàn)部分給出了三套完全不同的訓(xùn)練參數(shù)分別對(duì)應(yīng)音頻子網(wǎng)絡(luò)、視頻微調(diào)、BRNN 時(shí)序網(wǎng)絡(luò)。復(fù)現(xiàn)時(shí)最容易犯的錯(cuò)是把三套參數(shù)混用看到 batch size 有 40、32、256 就以為隨便選一個(gè)都行實(shí)際上每一套都是按各自網(wǎng)絡(luò)規(guī)模和數(shù)據(jù)量調(diào)過(guò)的。網(wǎng)絡(luò)模塊batch sizelearning ratemomentumweight decay其他關(guān)鍵項(xiàng)音頻子網(wǎng)絡(luò)400.010.90.01epoch 600lr decay 0.1視頻微調(diào)階段320.0050.90.0015dropout 0.5BRNN 時(shí)序網(wǎng)絡(luò)2560.0050.90.0005序列長(zhǎng)度 50音頻子網(wǎng)絡(luò)用 600 個(gè) epoch 是因?yàn)?1D CNN 參數(shù)量不大而且 openSMILE 特征維度有限需要長(zhǎng)訓(xùn)練才能充分收斂。視頻微調(diào)階段加了 0.5 的 dropout這在全連接層上是常規(guī)操作防止 FC 層在情感數(shù)據(jù)上過(guò)擬合。BRNN 的 weight decay 只有 0.0005比視頻微調(diào)階段小了 3 倍說(shuō)明時(shí)序網(wǎng)絡(luò)的參數(shù)更依賴正則約束調(diào)大反而會(huì)讓時(shí)序依賴學(xué)不到位。4.3 音頻與視頻的數(shù)據(jù)增強(qiáng)策略對(duì)比兩條分支的數(shù)據(jù)增強(qiáng)思路完全不同。音頻側(cè)論文把產(chǎn)生噪聲的語(yǔ)音信號(hào)開(kāi)頭或結(jié)尾的 4000 到 8000 個(gè)采樣點(diǎn)直接切掉相當(dāng)于手動(dòng)去噪加樣本擴(kuò)充這樣能獲得大量增強(qiáng)后的語(yǔ)音樣本再?gòu)拿款愔须S機(jī)抽 800 個(gè)讓各類數(shù)量大致相等。視頻側(cè)則是通過(guò)旋轉(zhuǎn)、鏡像和跨數(shù)據(jù)集補(bǔ)樣本讓八類情緒序列數(shù)量分別達(dá)到 798、801、585、614、723、768、737 和 744。這兩套策略的共同點(diǎn)是都在解決類別不平衡但手段差異很大。音頻增強(qiáng)是基于波形層面的切掉噪聲段不會(huì)改變說(shuō)話人的情感表達(dá)視頻增強(qiáng)的風(fēng)險(xiǎn)在于旋轉(zhuǎn)角度太大會(huì)讓面部比例失真論文選的 ±7° 和 ±15° 是經(jīng)驗(yàn)和實(shí)驗(yàn)折中的結(jié)果。另外注意音頻樣本數(shù)量是“每類 800”視頻是“每類 600 到 800 不等”兩者并不嚴(yán)格相等這說(shuō)明多模態(tài)融合并不要求兩路樣本數(shù)完全一致只要類別分布不偏就行。5. 避坑指南復(fù)現(xiàn) CNNRNN 情感識(shí)別時(shí)最容易翻車的五個(gè)位置5.1 坑一openSMILE 版本配置不一致特征維度悄悄變了現(xiàn)象訓(xùn)練時(shí)模型報(bào)維度錯(cuò)誤或者特征維度在沒(méi)改代碼的情況下前后兩次運(yùn)行不一致。原因openSMILE 的配置文件在不同版本之間并不完全兼容IS10_paraling_compat.conf 在不同版本里解析出的特征列表可能多個(gè)或少個(gè)幾列特征維度對(duì)不上卷積網(wǎng)絡(luò)的輸入層。解決跑通代碼前先固定一個(gè) openSMILE 版本把配置文件解析出的特征列名導(dǎo)出來(lái)存成文件每次實(shí)驗(yàn)前核對(duì)維度。5.2 坑二視頻幀數(shù)不夠 50 時(shí)補(bǔ)齊位置放錯(cuò)了現(xiàn)象多模態(tài)融合結(jié)果比視頻單模態(tài)還低逐層排查發(fā)現(xiàn)時(shí)序特征混亂。原因序列補(bǔ)幀時(shí)把首幀復(fù)制放在了序列末尾破壞了情感鋪墊在時(shí)間軸上的順序BRNN 讀到的“時(shí)間順序”是假的。解決嚴(yán)格按論文做法復(fù)制首幀插到序列開(kāi)頭而且要在代碼里寫(xiě)明注釋防止后人“好心”幫你改成末尾補(bǔ)齊。5.3 坑三直接拿原始分布訓(xùn)練neutral 把結(jié)果帶偏現(xiàn)象訓(xùn)練 loss 能降但驗(yàn)證集上 happy 和 surprise 的召回率極低整體平均精度慘淡。原因CHEAVD 原始數(shù)據(jù)里 neutral 類占比偏高你不做均衡網(wǎng)絡(luò)會(huì)把多數(shù)類當(dāng)成更容易賺錢的方向?qū)W少數(shù)類被徹底犧牲。解決按論文思路先做音頻每類 800 采樣、視頻用增強(qiáng)手段補(bǔ)數(shù)量。補(bǔ)樣本時(shí)注意不要無(wú)腦復(fù)制復(fù)制樣本加輕微旋轉(zhuǎn)鏡像不算作弊因?yàn)閹卣鹘?jīng)過(guò) VGG-Face16 之后本來(lái)就對(duì)小幅幾何擾動(dòng)不敏感。5.4 坑四VGG-Face16 全量微調(diào)小數(shù)據(jù)集直接過(guò)擬合現(xiàn)象驗(yàn)證集精度先升后降訓(xùn)練集精度接近 100%典型過(guò)擬合曲線。原因VGG-Face16 是在百萬(wàn)級(jí)人臉數(shù)據(jù)上預(yù)訓(xùn)練的全量微調(diào)讓所有卷積核都往小數(shù)據(jù)集上適配情感變化沒(méi)學(xué)到數(shù)據(jù)集特有噪聲倒是學(xué)得很透徹。解決凍結(jié)卷積層只微調(diào)最后三個(gè) FC 層。如果效果還不夠再加一層 dropout 0.5或者把 FC 中間層的輸出維度從 4096 降到 512用信息瓶頸逼模型學(xué)更抽象的表征。5.5 坑五融合權(quán)重一拍腦袋不如先看單模態(tài)成績(jī)現(xiàn)象α 和 β 隨手設(shè)成 0.5/0.5融合結(jié)果比兩個(gè)單模態(tài)都差。原因softmax 輸出的分?jǐn)?shù)分布在不同網(wǎng)絡(luò)之間沒(méi)有可比性音頻網(wǎng)絡(luò)可能偏愛(ài)輸出高置信度視頻網(wǎng)絡(luò)輸出偏保守直接等權(quán)平均等于把兩路錯(cuò)誤也平均了。解決先分別跑通音頻和視頻單模態(tài)把各自最好的模型存下來(lái)再做權(quán)重搜索。我在實(shí)際復(fù)現(xiàn)時(shí)習(xí)慣用驗(yàn)證集網(wǎng)格掃描 α 從 0.1 到 0.9、β 從 0.1 到 0.9找到最高平均精度的組合后再上測(cè)試集。6. 進(jìn)階做法用三個(gè)里程碑驗(yàn)證你的復(fù)現(xiàn)是否對(duì)齊 41.15%6.1 復(fù)現(xiàn)驗(yàn)證的三個(gè)里程碑復(fù)現(xiàn)這篇論文不要一上來(lái)就沖多模態(tài)融合建議按單模態(tài)到多模態(tài)的順序分三個(gè)里程碑驗(yàn)證。論文給出的結(jié)果表是現(xiàn)成的校驗(yàn)標(biāo)尺模態(tài)分類準(zhǔn)確率平均精度音頻31.53%37.06%視頻31.85%37.63%多模態(tài)融合34.55%41.15%第一個(gè)里程碑是復(fù)現(xiàn)音頻分支目標(biāo)平均精度 37.06%。如果差得遠(yuǎn)優(yōu)先檢查 openSMILE 特征維度和序列長(zhǎng)度對(duì)不對(duì)。第二個(gè)里程碑是視頻分支目標(biāo)平均精度 37.63%這里重點(diǎn)排查 VGG-Face16 的 FC 層輸出和幀篩選閾值。第三個(gè)里程碑才是融合目標(biāo)平均精度 41.15%這時(shí)再調(diào) α、β。這樣做的好處是每個(gè)階段只面對(duì)一個(gè)變量翻車時(shí)能快速定位問(wèn)題出在特征、網(wǎng)絡(luò)還是融合權(quán)重。6.2 從這篇論文能帶走的兩件東西如果你是沖著 2026 華為杯 E 題那種復(fù)雜場(chǎng)景下多模態(tài)情感預(yù)測(cè)建模來(lái)的這篇論文給你的不是直接能跑的代碼而是兩個(gè)可以遷移的工程習(xí)慣。第一個(gè)是“單模態(tài)先跑通再談融合”它把多模態(tài)問(wèn)題拆成了三個(gè)可控子問(wèn)題降低排錯(cuò)成本。第二個(gè)是幀特征重排的思路它用相鄰幀特征差異做關(guān)鍵幀篩選比均勻抽幀更能保留情緒轉(zhuǎn)折點(diǎn)這個(gè)技巧在視頻片段不標(biāo)準(zhǔn)的任務(wù)里都能復(fù)用。論文的結(jié)構(gòu)雖然簡(jiǎn)單但每一步都是圍繞“數(shù)據(jù)不干凈、長(zhǎng)度不統(tǒng)一、類別不平衡”這些真實(shí)問(wèn)題設(shè)計(jì)的。從那以后我復(fù)現(xiàn)情緒相關(guān)的多模態(tài)論文時(shí)都強(qiáng)制先跑通單模態(tài)、再碰融合權(quán)重這個(gè)順序幫我省下了很多次半夜返工。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取