深度興趣網(wǎng)絡解析-DIN

一、源數(shù)據(jù)

1.1、訓練數(shù)據(jù)

每行為一個樣本,元素分別為用戶id,用戶訪問的item id歷史列表,用戶本次訪問的item(正樣本為真實數(shù)據(jù),負樣本為隨機生成數(shù)據(jù)),正負樣本標識

1.2、測試數(shù)據(jù)

每行為一個樣本,元素分別為用戶id,用戶訪問的item id歷史列表,(用戶本次訪問正樣本item,系統(tǒng)隨機生成的負樣本item)

1.3、類別

每個元素為對應item的類別

1.4、其他參數(shù)

用戶數(shù)目:192403

item數(shù)目:63001

cate數(shù)目:801

二、模型

2.1、模型結(jié)構(gòu)



2.2、模型詳解

2.2.1、輸入?yún)?shù)

u:int,用戶id列表,長度為batch_size

i:int,被推送的item

id列表,元素為曝光給每個用戶的item的id,長度為batch_size

y:float,正負樣本標識,0 or 1,長度為batch_size

hist_i:int,用戶點擊歷史數(shù)據(jù),元素為點擊的歷史item id,shape為batch_size*最大點擊歷史長度

sl:int,用戶實際點擊歷史長度,長度為batch_size

lr:訓練超參數(shù)

cate_iist:int,item類別轉(zhuǎn)換表,元素為item的cate id,長度為item總數(shù)

2.2.2、訓練參數(shù)

item_emb_w:item的embedding,shape為item數(shù)*64

item_b:item的bias,shape為item數(shù)

cate_emb_w:item類型的embedding,shape為cate數(shù)*64

2.2.3、整體流程

2.2.3.1、輸入數(shù)據(jù)轉(zhuǎn)換為嵌入向量形式

根據(jù)輸入數(shù)據(jù)的id(item id,cate id),從相應的訓練參數(shù)(嵌入表示查詢表)獲取匹配的嵌入表示。

c = tf.gather(cate_list, self.i)? #被推送的item的類型列表

i_emb = tf.concat(values = [

? ? ? ? tf.nn.embedding_lookup(item_emb_w, self.i),

? ? ? ? tf.nn.embedding_lookup(cate_emb_w, ic),

? ? ? ? ],axis=1)

i_b = tf.gather(item_b, self.i)


hc = tf.gather(cate_list, self.hist_i)

h_emb = tf.concat([

? ? ? ? tf.nn.embedding_lookup(item_emb_w, self.hist_i),

? ? ? ? tf.nn.embedding_lookup(cate_emb_w, hc),

? ? ? ? ], axis=2)


2.2.3.2、由i_emb,h_emb和sl根據(jù)注意力機制生成用戶的嵌入表示

用戶的嵌入表示的格式如下:


2.2.3.3、將u_emb與i_emb進行拼接,并作為MLP的輸入,最后輸出user對item的pctr,并與真實的點擊情況聯(lián)合生成損失函數(shù),用于優(yōu)化

din_i = tf.concat([u_emb, i_emb], axis=-1)

din_i = tf.layers.batch_normalization(inputs=din_i, name='b1')

d_layer_1_i = tf.layers.dense(din_i, 80, activation=None, name='f1')

d_layer_1_i = dice(d_layer_1_i, name='dice_1')

d_layer_2_i = tf.layers.dense(d_layer_1_i, 40, ctivation=None, name='f2')

d_layer_2_i = dice(d_layer_2_i, name='dice_2')

d_layer_3_i = tf.layers.dense(d_layer_2_i, 1, activation=None, name='f3')

self.logits = i_b + d_layer_3_i

self.loss = tf.reduce_mean(

? ? tf.nn.sigmoid_cross_entropy_with_logits(

? ? ? ? logits=self.logits,

? ? ? ? labels=self.y)

)

2.2.4、基于注意力機制的用戶嵌入表示

'''

? Bbatch的大小,T指用戶歷史行為的最大長度,Hembedding的長度

? queries:? ? [B, H]

? keys:? ? ? ? [B, T, H]

? keys_length: [B]

'''

queries_hidden_units = queries.get_shape().as_list()[-1]? #最后一維大小queries = tf.tile(queries, [1, tf.shape(keys)[1]])

queries = tf.reshape(queries, [-1, tf.shape(keys)[1], queries_hidden_units])

din_all = tf.concat([queries, keys, queries-keys, queries*keys], axis=-1) #用戶點擊歷史與推薦的item拼接生成MLP的輸入

d_layer_1_all = tf.layers.dense(din_all, 80, activation=tf.nn.sigmoid, name='f1_att', reuse=tf.AUTO_REUSE)

d_layer_2_all = tf.layers.dense(d_layer_1_all, 40, activation=tf.nn.sigmoid, name='f2_att', reuse=tf.AUTO_REUSE)

d_layer_3_all = tf.layers.dense(d_layer_2_all, 1, activation=None, name='f3_att', reuse=tf.AUTO_REUSE)

d_layer_3_all = tf.reshape(d_layer_3_all, [-1, 1, tf.shape(keys)[1]])

outputs = d_layer_3_all

由queries(i_emb)拼貼成keys(h_emb)的形狀,并與keys(h_emb)進行差、點乘運算后生成MLP的輸入(din_all),經(jīng)MLP計算生成與各點擊歷史相關(guān)的權(quán)重系數(shù)


# Mask

key_masks = tf.sequence_mask(keys_length, tf.shape(keys)[1])? # [B, T]

key_masks = tf.expand_dims(key_masks, 1) # [B, 1, T]

paddings = tf.ones_like(outputs) * (-2 ** 32 + 1)

outputs = tf.where(key_masks, outputs, paddings)? # [B, 1, T]

# Scale

outputs = outputs / (keys.get_shape().as_list()[-1] ** 0.5)

# Activation

outputs = tf.nn.softmax(outputs)? # [B, 1, T]

# Weighted sum

outputs = tf.matmul(outputs, keys)? # [B, 1, H]

hist_i =outpus hist_i = tf.layers.batch_normalization(inputs = hist_i)

hist_i = tf.reshape(hist_i, [-1, hidden_units], name='hist_bn')

hist_i = tf.layers.dense(hist_i, hidden_units, name='hist_fcn')

u_emb = hist_i

由于每個用戶的點擊歷史是不一樣長的,需要使用一個mask張量對無效的數(shù)據(jù)進行屏蔽。


在得到在推item與歷史點擊item的相關(guān)系數(shù)后,與點擊歷史的item_emb進行權(quán)重和后進行歸一化處理可以得到用戶的嵌入表示。



2.2.5、dice激活


def dice(_x,axis=-1,epsilon=0.0000001,name=''):

? ? alphas = tf.get_variable('alpha'+name,_x.get_shape()[-1],initializer = tf.constant_initializer(0.0), dtype=tf.float32)

? ? input_shape =list(_x.get_shape())? # [batch_size, hidden_unit_size]

? ? reduction_axes = list(range(len(input_shape)))? # [0, 1]

? ? del reduction_axes[axis] # [0]

? ? broadcast_shape = [1] * len(input_shape)? # [1, 1]

? ? broadcast_shape[axis] = input_shape[axis]? # [1, hidden_unit_size]

? ? # case: train mode (uses stats of the current batch)

? ? mean = tf.reduce_mean(_x, axis=reduction_axes)? # [1 * hidden_unit_size]

? ? brodcast_mean = tf.reshape(mean, broadcast_shape) # [1 * hidden_unit_size]

? ? std = tf.reduce_mean(tf.square(_x - brodcast_mean) + epsilon, axis=reduction_axes)? # [1 * hidden_unit_size]

? ? std = tf.sqrt(std)

? ? brodcast_std = tf.reshape(std, broadcast_shape) #[1 * hidden_unit_size]

? ? # x_normed = (_x - brodcast_mean) / (brodcast_std + epsilon)

? ? x_normed = tf.layers.batch_normalization(_x, center=False, scale=False, training=True)? # a simple way to use BN to calculate x_p

? ? x_p = tf.sigmoid(x_normed)

? ? return alphas * (1.0 - x_p) * _x + x_p * _x

不同alpha值得dice隨y值變化圖如下:


ReLU和Leaky ReLU的圖示如下:



三、參考文獻

1、Deep Interest Network for Click-Through Rate Prediction

2、github:https://github.com/zhougr1993/DeepInterestNetwork

3、http://www.itdecent.cn/p/73b6f5d00f46

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容