絡(luò):候選商品引導(dǎo)的注意力機(jī)制與推薦系統(tǒng)CTR模型實(shí)戰(zhàn)解析)
做推薦系統(tǒng)的同行應(yīng)該都有這種感覺(jué)用戶的歷史行為越長(zhǎng)數(shù)據(jù)越豐富模型反而越難做。明明一個(gè)用戶點(diǎn)了不少裙子、看了不少口紅給他推下一件商品的時(shí)候這些歷史行為到底哪些有用、哪些是噪聲就成了一個(gè)很難回答的問(wèn)題。早年大家習(xí)慣把用戶的歷史行為向量全部池化成一個(gè)固定向量然后拼上候選商品特征一起過(guò)MLP。這個(gè)方法很穩(wěn)定但它有一個(gè)先天缺陷——不管候選商品是什么池化出的用戶興趣向量都是同一份。仔細(xì)想想這是不合理的用戶在看一個(gè)籃球的時(shí)候他歷史里的口紅行為真的應(yīng)該和看一支口紅時(shí)貢獻(xiàn)相同的權(quán)重嗎DIN模型全稱Deep Interest Network就是沖著這個(gè)問(wèn)題來(lái)的。它的核心思路特別直白用戶的歷史行為不應(yīng)該被一成不變地壓縮成固定向量而應(yīng)該根據(jù)當(dāng)前候選商品去“喚醒”歷史行為中和這個(gè)候選商品最相關(guān)的部分。這個(gè)喚醒過(guò)程就是注意力機(jī)制只不過(guò)它在推薦系統(tǒng)里換了名字叫“局部激活單元”。這篇文章我會(huì)把這個(gè)模型的動(dòng)機(jī)、網(wǎng)絡(luò)結(jié)構(gòu)、訓(xùn)練細(xì)節(jié)、復(fù)現(xiàn)要點(diǎn)和工程落地中的坑全部講透尤其會(huì)解釋很多論文里一筆帶過(guò)、但實(shí)踐中非常關(guān)鍵的地方。1. 為什么需要DIN從固定池化到局部激活1.1 固定向量池化的根本問(wèn)題在DIN出來(lái)之前業(yè)內(nèi)主流的深度學(xué)習(xí)CTR模型基本長(zhǎng)這樣把用戶的歷史點(diǎn)擊商品ID序列做Embedding得到一個(gè)向量序列然后做sum pooling或者mean pooling把序列壓成一個(gè)向量再把這個(gè)向量和候選商品Embedding、用戶畫(huà)像特征拼在一起送進(jìn)MLP最后過(guò)一個(gè)sigmoid輸出點(diǎn)擊概率。這個(gè)結(jié)構(gòu)本身沒(méi)有問(wèn)題問(wèn)題出在pooling這個(gè)環(huán)節(jié)。sum pooling的本質(zhì)是把所有行為向量的信息全部“揉”進(jìn)一個(gè)等維度的向量里。假設(shè)用戶的興趣維度是128他點(diǎn)了100個(gè)商品這100個(gè)商品的Embedding加起來(lái)除以100得到的平均向量已經(jīng)把每個(gè)商品自身的細(xì)節(jié)抹掉了一大半。更關(guān)鍵的是這個(gè)池化后的向量無(wú)論如何都不會(huì)變——候選商品是籃球還是口紅用戶歷史行為的權(quán)重分配都是那同一套。你可以把它理解成一位導(dǎo)購(gòu)員不管顧客進(jìn)來(lái)是想買運(yùn)動(dòng)鞋還是想買護(hù)膚品她都用同一套說(shuō)辭推薦。這套說(shuō)辭可能在某種場(chǎng)景下有效但面對(duì)興趣跨度極大的真實(shí)用戶它必然顧此失彼。用戶的興趣天生就是多樣的一個(gè)年輕用戶可能同時(shí)喜歡數(shù)碼產(chǎn)品和潮牌服飾這兩個(gè)興趣在池化時(shí)會(huì)互相干擾。結(jié)果就是模型為了平衡學(xué)出來(lái)的用戶表示變得“平平無(wú)奇”哪個(gè)興趣方向都表達(dá)得不夠充分。1.2 為什么要用候選商品來(lái)“指揮”注意力DIN的論文給了我一個(gè)非常關(guān)鍵的思想轉(zhuǎn)變用戶興趣表示不應(yīng)該是獨(dú)立計(jì)算出來(lái)的它應(yīng)該和候選商品有關(guān)。所謂局部激活就是當(dāng)候選商品是籃球鞋的時(shí)候模型應(yīng)該去用戶的歷史行為序列里重點(diǎn)提取和籃球鞋相關(guān)的行為當(dāng)候選商品是美白精華的時(shí)候模型應(yīng)該把注意力放到美妝類的歷史行為上。這個(gè)“重點(diǎn)提取”的過(guò)程就是讓每個(gè)歷史行為Embedding和候選商品Embedding做一個(gè)交互計(jì)算得出一個(gè)權(quán)重然后對(duì)所有歷史行為向量做加權(quán)和。這樣做的好處立竿見(jiàn)影。第一模型的有效表達(dá)能力變強(qiáng)了因?yàn)橛脩襞d趣表示不是固定的而是針對(duì)每個(gè)候選商品“定制”的。第二噪聲干擾減少了歷史行為中與當(dāng)前候選商品無(wú)關(guān)的部分會(huì)被自動(dòng)壓權(quán)不會(huì)拖累預(yù)測(cè)。第三這個(gè)機(jī)制是端到端學(xué)出來(lái)的不需要人工去定義“籃球鞋和哪些歷史行為有關(guān)”這樣的規(guī)則完全靠數(shù)據(jù)自己擬合。我當(dāng)時(shí)讀完論文的第一反應(yīng)是這個(gè)思路太自然了為什么之前沒(méi)人這么做其實(shí)是有人這么想的但把注意力機(jī)制穩(wěn)定地用在億級(jí)稀疏特征的CTR場(chǎng)景里并且把訓(xùn)練技巧、激活函數(shù)、正則方法都補(bǔ)齊到工程可用DIN是做得最完整的一個(gè)。2. DIN模型結(jié)構(gòu)逐層拆解2.1 候選商品、用戶行為與上下文特征的輸入設(shè)計(jì)DIN的輸入分為三大塊。第一塊是候選商品相關(guān)的特征這一塊直接決定預(yù)測(cè)目標(biāo)通常包括商品ID、類目ID、店鋪ID等全部經(jīng)過(guò)Embedding后拼接成一個(gè)候選向量。第二塊是用戶歷史行為序列重點(diǎn)就是用戶在過(guò)去一段時(shí)間內(nèi)點(diǎn)擊過(guò)的商品ID序列每個(gè)商品ID同樣要做Embedding形成一個(gè)向量序列。第三塊是用戶畫(huà)像特征和上下文特征比如用戶的年齡、性別、城市等級(jí)、當(dāng)前時(shí)間等。在特征工程層面有一個(gè)值得注意的設(shè)計(jì)候選商品和用戶歷史行為里的商品在Embedding層是共享參數(shù)的。候選商品ID是ID行為序列里的商品ID也是ID如果分開(kāi)建兩套Embedding模型就學(xué)不到“候選商品和歷史點(diǎn)擊商品的關(guān)系”注意力權(quán)重也就失去了基礎(chǔ)。這一點(diǎn)在復(fù)現(xiàn)時(shí)特別容易漏掉一旦漏掉AUC會(huì)明顯下降。輸入長(zhǎng)度方面歷史行為序列不能無(wú)限長(zhǎng)。常見(jiàn)做法是固定截?cái)嚅L(zhǎng)度比如取最近點(diǎn)擊的50個(gè)或者100個(gè)商品。如果不足長(zhǎng)度就做padding如果超過(guò)就按時(shí)間倒序截?cái)唷?shí)際場(chǎng)景中很多用戶的歷史行為可能只有十幾個(gè)固定長(zhǎng)度會(huì)帶來(lái)大量padding需要在Embedding層把padding對(duì)應(yīng)的向量置為零防止它參與有效性計(jì)算。2.2 局部激活單元的計(jì)算邏輯局部激活單元是整個(gè)DIN的核心它的輸入是歷史行為序列里某一個(gè)商品對(duì)應(yīng)的Embedding向量以及候選商品對(duì)應(yīng)的Embedding向量。DIN的局部激活單元結(jié)構(gòu)與傳統(tǒng)的直接拼接做點(diǎn)乘不同它設(shè)計(jì)了一個(gè)小型的MLP來(lái)學(xué)習(xí)這兩個(gè)向量之間的交互關(guān)系。具體的計(jì)算方式是把兩個(gè)向量本身拼接在一起再讓它們做逐元素的外積得到一組交叉項(xiàng)然后把這三部分拼接起來(lái)送進(jìn)一個(gè)兩層的全連接網(wǎng)絡(luò)最后輸出一個(gè)標(biāo)量權(quán)重。這個(gè)權(quán)重再經(jīng)過(guò)指數(shù)映射就是那個(gè)歷史行為對(duì)候選商品的重要程度。很多初學(xué)者會(huì)問(wèn)一個(gè)問(wèn)題為什么不直接用softmax歸一化DIN有意沒(méi)有對(duì)全部行為序列做softmax因?yàn)橛脩襞d趣的絕對(duì)強(qiáng)度本身是有意義的。如果一個(gè)用戶對(duì)某個(gè)歷史行為極其感興趣他對(duì)候選商品的外顯權(quán)重就應(yīng)該整體偏高如果做全序列的softmax就相當(dāng)于把所有行為權(quán)重強(qiáng)制拉成相對(duì)比例這會(huì)丟失興趣強(qiáng)度的絕對(duì)值信息反而影響預(yù)測(cè)精度。計(jì)算出每個(gè)行為向量的權(quán)重之后對(duì)所有行為向量做加權(quán)求和得到最終的向量再與候選商品向量、用戶畫(huà)像向量拼接送入MLP。MLP部分就是標(biāo)準(zhǔn)的全連接網(wǎng)絡(luò)最后接sigmoid輸出點(diǎn)擊率。2.3 為什么不是先建模行為順序很多人會(huì)覺(jué)得歷史行為是序列數(shù)據(jù)應(yīng)該先用GRU、LSTM這些建模時(shí)序然后再接注意力。這個(gè)想法在邏輯上沒(méi)錯(cuò)但在DIN提出的那個(gè)階段用序列模型把所有用戶歷史行為建模完整計(jì)算量非常大效果增益卻未必匹配。DIN的定位是盡量簡(jiǎn)潔地解決“興趣表達(dá)與候選商品無(wú)關(guān)”的問(wèn)題它沒(méi)有刻意去建模行為之間的先后依賴也沒(méi)有做長(zhǎng)短期興趣的拆分就是一個(gè)注意力加權(quán)求和。論文后續(xù)確實(shí)有人在這條路上繼續(xù)延伸比如把行為序列換成Transformer結(jié)構(gòu)做建模但作為基石DIN把最有價(jià)值的一步先走通了——讓每個(gè)候選商品都能看到用戶歷史行為的“不同切面”。這一步走通之后后面的一切優(yōu)化都有了更牢固的地基。3. 訓(xùn)練中的兩個(gè)關(guān)鍵細(xì)節(jié)Dice激活與Mini-batch Aware正則3.1 Dice激活函數(shù)做了什么DIN論文里第一次看的時(shí)候大部分人都會(huì)被Dice激活函數(shù)這個(gè)小節(jié)卡住。它看起來(lái)只比PReLU多了一個(gè)自適應(yīng)開(kāi)關(guān)但理解它的動(dòng)機(jī)很重要。PReLU是帶可學(xué)習(xí)參數(shù)的ReLU變體公式很好理解當(dāng)輸入大于零時(shí)保持原值當(dāng)輸入小于等于零時(shí)乘以一個(gè)可學(xué)習(xí)的系數(shù)。這個(gè)系數(shù)是全局固定的一組標(biāo)量在所有輸入樣本上共享。問(wèn)題來(lái)了推薦系統(tǒng)里的特征輸入分布極其不穩(wěn)定有的特征均值可能在零附近有的特征整體是負(fù)數(shù)有的特征方差爆炸。用一個(gè)固定負(fù)斜率去處理所有分布特征很容易壓不住數(shù)據(jù)分布的變化。Dice的做法是對(duì)輸入做標(biāo)準(zhǔn)化用當(dāng)前batch數(shù)據(jù)的均值和方差把輸入調(diào)整到零均值單位方差附近再用sigmoid函數(shù)動(dòng)態(tài)控制這個(gè)激活門。當(dāng)輸入分布不穩(wěn)定時(shí)這個(gè)sigmoid門會(huì)自適應(yīng)地調(diào)節(jié)激活點(diǎn)的位置相當(dāng)于一個(gè)可以隨著數(shù)據(jù)分布流動(dòng)的“軟開(kāi)關(guān)”。復(fù)現(xiàn)的時(shí)候可以直接用PyTorch的batch normalization思路類比但要清楚Dice的標(biāo)準(zhǔn)化是不做仿射變換的重建的它只做標(biāo)準(zhǔn)化和門控。3.2 Mini-batch Aware正則的動(dòng)機(jī)與簡(jiǎn)化這個(gè)部分論文里給了比較復(fù)雜的形式很多復(fù)現(xiàn)教程會(huì)直接略過(guò)但工程上它非常重要。推薦系統(tǒng)的Embedding層參數(shù)動(dòng)輒上億模型的權(quán)重?cái)?shù)量遠(yuǎn)超樣本數(shù)過(guò)擬合風(fēng)險(xiǎn)極大。常用的L2正則理論上能壓制復(fù)雜度但它要求對(duì)全量參數(shù)更新時(shí)計(jì)算梯度這在工業(yè)級(jí)的Embedding規(guī)模下是不可行的——每個(gè)batch只碰到了極少一部分稀疏ID對(duì)全部Embedding做懲罰是巨大的浪費(fèi)。Mini-batch Aware正則的思路是在計(jì)算L2正則時(shí)只對(duì)當(dāng)前batch中出現(xiàn)過(guò)的稀疏特征對(duì)應(yīng)的Embedding做懲罰并且懲罰力度要依據(jù)該特征在當(dāng)前batch中的出現(xiàn)頻率進(jìn)行調(diào)整。更直白的解釋是如果一個(gè)參數(shù)在當(dāng)前batch中出現(xiàn)了兩次它獲得的懲罰是出現(xiàn)一次樣本的兩倍如果一個(gè)參數(shù)在當(dāng)前batch中一次都沒(méi)出現(xiàn)那就不懲罰它。論文里還做了一個(gè)頻次的p次方近似處理避免高頻特征被懲罰過(guò)重在實(shí)際復(fù)現(xiàn)時(shí)如果數(shù)據(jù)量不大不做p次方近似也不會(huì)差太多。我自己的復(fù)現(xiàn)經(jīng)驗(yàn)是Mini-batch Aware正則這個(gè)細(xì)節(jié)最容易被省略如果不加結(jié)果往往是離線AUC有小幅上升但波動(dòng)大線上反饋差距更明顯。做工程落地時(shí)這個(gè)正則一定要保留。4. 動(dòng)手復(fù)現(xiàn)DINPyTorch代碼核心要點(diǎn)4.1 稀疏特征與行為序列的預(yù)處理在開(kāi)始寫(xiě)模型之前先把數(shù)據(jù)流想清楚。輸入樣本通常長(zhǎng)這樣user_id、一個(gè)候選商品id、一個(gè)候選商品的類目id、一個(gè)歷史點(diǎn)擊商品id序列、一個(gè)歷史點(diǎn)擊商品類目序列、還有若干上下文特征。這里我建議把用戶歷史行為里的商品id和候選商品id放進(jìn)同一個(gè)詞表序列長(zhǎng)度固定為N。預(yù)處理階段把歷史行為序列倒序排列按時(shí)間最近優(yōu)先取前N個(gè)不足補(bǔ)零。class DINBase(nn.Module): def __init__(self, item_count, embedding_dim, sequence_length, hidden_units): super().__init__() self.item_embedding nn.Embedding(item_count, embedding_dim, padding_idx0) self.sequence_length sequence_length self.activation_unit ActivationUnit(embedding_dim, hidden_units) self.mlp nn.Sequential( nn.Linear(embedding_dim * 3 48, 200), Dice(200), nn.Linear(200, 80), Dice(80), nn.Linear(80, 1) )注意這里我拼接了用戶向量、候選商品向量、用戶畫(huà)像特征總計(jì)維度要算清楚。用戶向量就是注意力加權(quán)求和后的維度候選商品向量就是單個(gè)Embedding的維度。畫(huà)像特征通常是稠密數(shù)值特征加離散特征的Embedding拼接。4.2 局部激活單元的代碼實(shí)現(xiàn)局域激活單元的重點(diǎn)是計(jì)算交互特征。我給的實(shí)現(xiàn)是把候選商品向量復(fù)制成多個(gè)副本與每個(gè)歷史行為向量做外積再把三部分拼接送進(jìn)MLP。class ActivationUnit(nn.Module): def __init__(self, embedding_dim, hidden_units): super().__init__() self.linear nn.Linear(embedding_dim * 3, hidden_units) self.dice Dice(hidden_units) self.linear_out nn.Linear(hidden_units, 1) def forward(self, candidate_item, behavior_sequence): # candidate_item: [batch, dim] # behavior_sequence: [batch, seq_len, dim] batch_size, seq_len, dim behavior_sequence.shape c candidate_item.unsqueeze(1).expand(batch_size, seq_len, dim) interaction c * behavior_sequence concat torch.cat([behavior_sequence, c, interaction], dim-1) hidden self.dice(self.linear(concat)) weight self.linear_out(hidden).squeeze(-1) weight torch.exp(weight) mask (behavior_sequence.sum(dim-1) ! 0).float() weight weight * mask weight weight / (weight.sum(dim-1, keepdimTrue) 1e-8) return weight大多數(shù)人第一次實(shí)現(xiàn)都會(huì)糾結(jié)要不要對(duì)權(quán)重做歸一化。剛才分析過(guò)論文思想是不強(qiáng)制做softmax但實(shí)際工程里如果序列長(zhǎng)度差異很大不做歸一化長(zhǎng)序列用戶注意力分?jǐn)?shù)天然會(huì)大跨樣本比較就混亂了。我習(xí)慣在加權(quán)求和前對(duì)有效權(quán)重做一次求和歸一化保留興趣強(qiáng)度的相對(duì)差異但避免樣本間的序列長(zhǎng)度偏差問(wèn)題。當(dāng)然如果有更貼近論文原始含義的復(fù)現(xiàn)需求也可以不做這里的歸一化而是直接加權(quán)求和。4.3 訓(xùn)練主流程與超參數(shù)配置DIN在訓(xùn)練時(shí)的超參數(shù)選擇直接影響最終效果。論文給我的經(jīng)驗(yàn)是使用Adam優(yōu)化器初始學(xué)習(xí)率從0.001開(kāi)始配合指數(shù)衰減大概每?jī)奢喌p10%。Batch size在稠密ID規(guī)模不夸張時(shí)設(shè)為256到512比較合適。負(fù)樣本采樣也是一個(gè)重要環(huán)節(jié)。曝光未點(diǎn)擊樣本與點(diǎn)擊樣本的比例通常在5:1到20:1之間調(diào)整。比例高了模型會(huì)傾向預(yù)測(cè)低點(diǎn)擊率需要配合閾值校準(zhǔn)比例低了正樣本噪聲會(huì)污染注意力權(quán)重的學(xué)習(xí)。訓(xùn)練過(guò)程中的Loss就是標(biāo)準(zhǔn)的二值交叉熵。我建議在訓(xùn)練日志里同時(shí)記錄訓(xùn)練集和驗(yàn)證集AUC并且按用戶分組計(jì)算GAUC這一點(diǎn)和DIN論文的實(shí)驗(yàn)設(shè)置保持一致因?yàn)槿諥UC會(huì)被少數(shù)高頻用戶主導(dǎo)掩蓋模型在長(zhǎng)尾用戶上的真實(shí)表現(xiàn)。5. 實(shí)驗(yàn)評(píng)估、工程落地與常見(jiàn)問(wèn)題排查5.1 評(píng)估指標(biāo)為什么全局AUC不夠用DIN論文在實(shí)驗(yàn)部分強(qiáng)調(diào)了評(píng)估指標(biāo)的選擇問(wèn)題。直接算全量樣本的AUC結(jié)果會(huì)被行為數(shù)量極大的頭部用戶“帶偏”這些用戶的興趣通常比較集中歷史行為很長(zhǎng)模型對(duì)它們的預(yù)測(cè)本來(lái)就比較容易真正難預(yù)測(cè)的是那些歷史行為稀疏的長(zhǎng)尾用戶他們的點(diǎn)擊行為跨領(lǐng)域跨度大候選商品的注意力計(jì)算會(huì)遇到更多挑戰(zhàn)。所以推薦的做法是先把測(cè)試樣本按用戶分組在每個(gè)用戶組內(nèi)計(jì)算AUC再按曝光數(shù)加權(quán)平均得到GAUC。我自己的復(fù)現(xiàn)對(duì)比中DIN的相對(duì)AUC提升大約在0.5到1個(gè)百分點(diǎn)但GAUC提升會(huì)更明顯說(shuō)明模型的增益確實(shí)集中在了原有模型搞不定的樣本上。評(píng)估時(shí)千萬(wàn)要兩個(gè)指標(biāo)一起看。5.2 線上推理時(shí)的性能瓶頸與優(yōu)化工業(yè)落地中局部激活單元帶來(lái)的計(jì)算開(kāi)銷不容忽視。在線推理時(shí)候選商品數(shù)量可能是幾千上萬(wàn)個(gè)用戶歷史行為序列長(zhǎng)度在50到100如果每個(gè)候選都和全部歷史行為做一次外積和MLP計(jì)算壓力不小。一種有效優(yōu)化是預(yù)先緩存用戶行為序列的Embedding結(jié)果因?yàn)橛脩舻膭?dòng)作頻率遠(yuǎn)低于候選商品的變化頻率。行為向量的個(gè)數(shù)不變只是權(quán)重計(jì)算時(shí)需要和每個(gè)候選商品重新交互這部分無(wú)法完全預(yù)計(jì)算但可以把行為Embedding向量的查詢開(kāi)銷省掉。如果延遲敏感還可以對(duì)行為序列做截?cái)嗷蛘咧槐A糇罡咦⒁饬?quán)重的前K個(gè)行為實(shí)測(cè)下來(lái)精度損失很小。模型參數(shù)存儲(chǔ)方面Embedding矩陣是最大的內(nèi)存消耗點(diǎn)。如果商品量級(jí)是千萬(wàn)級(jí)每個(gè)商品32維Embedding那么單是商品Embedding就有數(shù)億個(gè)參數(shù)必須利用參數(shù)服務(wù)器或者按分片方式存儲(chǔ)不要讓單機(jī)內(nèi)存成為瓶頸。5.3 復(fù)現(xiàn)與落地常見(jiàn)問(wèn)題速查問(wèn)題現(xiàn)象可能原因解決思路局部激活單元訓(xùn)練不收斂學(xué)習(xí)率過(guò)大、行為序列padding沒(méi)有遮罩調(diào)小初始學(xué)習(xí)率對(duì)padding位置強(qiáng)制置零權(quán)重AUC提升不明顯候選商品與歷史行為商品用了兩套Embedding檢查是否共享詞表與Embedding矩陣訓(xùn)練過(guò)程loss震蕩正負(fù)樣本比例失衡或batch size過(guò)小提高負(fù)樣本比例或增大batch size線上延遲超標(biāo)注意力計(jì)算量過(guò)大截?cái)嘈袨樾蛄?、只保留TopK高權(quán)重行為長(zhǎng)尾用戶預(yù)測(cè)偏平行為序列太短、候選信息不足引入跨會(huì)話行為或補(bǔ)充用戶長(zhǎng)期畫(huà)像特征還有一個(gè)隱蔽的坑值得單獨(dú)提注意力權(quán)重的飽和現(xiàn)象。當(dāng)候選商品非常好猜時(shí)比如用戶歷史行為里有大量同款商品注意力網(wǎng)絡(luò)可能會(huì)把幾乎全部權(quán)重集中到一個(gè)行為上導(dǎo)致加權(quán)向量退化成單純的某個(gè)行為Embedding。這種情況雖然不報(bào)錯(cuò)但會(huì)讓模型喪失泛化能力。我的經(jīng)驗(yàn)是可以在激活單元輸出層加少量dropout或者對(duì)注意力權(quán)重logits做輕微的正則防止過(guò)度集中。迭代到后面你會(huì)發(fā)現(xiàn)DIN的真正價(jià)值不在模型結(jié)構(gòu)有多復(fù)雜而在于它把“候選商品引導(dǎo)歷史行為表示”這個(gè)思路做成了推薦系統(tǒng)深度模型的標(biāo)配。后續(xù)很多模型比如用多頭注意力做多興趣抽取的MIND用膠囊網(wǎng)絡(luò)區(qū)分興趣的ComiRec本質(zhì)上都能看到DIN的影子。如果你想在推薦領(lǐng)域深入吃透DIN的每一處細(xì)節(jié)是最值得投入的一件事。最后分享一個(gè)我在實(shí)際復(fù)現(xiàn)中收獲最大的習(xí)慣不要只對(duì)著論文公式寫(xiě)代碼把注意力網(wǎng)絡(luò)輸出的權(quán)重可視化出來(lái)。隨機(jī)挑幾個(gè)樣本看模型到底把注意力給了哪些歷史行為你會(huì)發(fā)現(xiàn)一個(gè)訓(xùn)練充分的DIN它的注意力分布和人的直覺(jué)高度吻合——這個(gè)觀察過(guò)程能幫你快速定位特征問(wèn)題和模型問(wèn)題比單純盯AUC數(shù)字有效得多。