推薦系統遇上深度學習(六)--PNN模型理論和實踐

2021-02-08 Python愛好者社區

作者:石曉文   中國人民大學信息學院在讀研究生

個人公眾號:小小挖掘機(ID:wAIsjwj)


前文傳送門:

推薦系統遇上深度學習(一)--FM模型理論和實踐

推薦系統遇上深度學習(二)--FFM模型理論和實踐

推薦系統遇上深度學習(三)--DeepFM模型理論和實踐

推薦系統遇上深度學習(四)--多值離散特徵的embedding解決方案

推薦系統遇上深度學習(五)--Deep&Cross Network模型理論和實踐

1、原理

PNN,全稱為Product-based Neural Network,認為在embedding輸入到MLP之後學習的交叉特徵表達並不充分,提出了一種product layer的思想,既基於乘法的運算來體現體徵交叉的DNN網絡結構,如下圖:

按照論文的思路,我們也從上往下來看這個網絡結構:

輸出層

輸出層很簡單,將上一層的網絡輸出通過一個全連結層,經過sigmoid函數轉換後映射到(0,1)的區間中,得到我們的點擊率的預測值:

l2層

根據l1層的輸出,經一個全連結層 ,並使用relu進行激活,得到我們l2的輸出結果:

l1層

l1層的輸出由如下的公式計算:

重點馬上就要來了,我們可以看到在得到l1層輸出時,我們輸入了三部分,分別是lz,lp 和 b1,b1是我們的偏置項,這裡可以先不管。lz和lp的計算就是PNN的精華所在了。我們慢慢道來

Product Layer

product思想來源於,在ctr預估中,認為特徵之間的關係更多是一種and「且」的關係,而非add"加」的關係。例如,性別為男且喜歡遊戲的人群,比起性別男和喜歡遊戲的人群,前者的組合比後者更能體現特徵交叉的意義。

product layer可以分成兩個部分,一部分是線性部分lz,一部分是非線性部分lp。二者的形式如下:

在這裡,我們要使用到論文中所定義的一種運算方式,其實就是矩陣的點乘啦:

我們先繼續介紹網絡結構,有關Product Layer的更詳細的介紹,我們在下一章中介紹。

Embedding Layer

Embedding Layer跟DeepFM中相同,將每一個field的特徵轉換成同樣長度的向量,這裡用f來表示。

損失函數
使用和邏輯回歸同樣的損失函數,如下:

2、Product Layer詳細介紹

前面提到了,product layer可以分成兩個部分,一部分是線性部分lz,一部分是非線性部分lp。

看上面的公式,我們首先需要知道z和p,這都是由我們的embedding層得到的,其中z是線性信號向量,因此我們直接用embedding層得到:

論文中使用的等號加一個三角形,其實就是相等的意思,你可以認為z就是embedding層的複製。

對於p來說,這裡需要一個公式進行映射:

不同的g的選擇使得我們有了兩種PNN的計算方法,一種叫做Inner PNN,簡稱IPNN,一種叫做Outer PNN,簡稱OPNN。

接下來,我們分別來具體介紹這兩種形式的PNN模型,由於涉及到複雜度的分析,所以我們這裡先定義Embedding的大小為M,field的大小為N,而lz和lp的長度為D1。

2.1 IPNN

IPNN的示意圖如下:

IPNN中p的計算方式如下,即使用內積來代表pij:

所以,pij其實是一個數,得到一個pij的時間複雜度為M,p的大小為N*N,因此計算得到p的時間複雜度為N*N*M。而再由p得到lp的時間複雜度是N*N*D1。因此 對於IPNN來說,總的時間複雜度為N*N(D1+M)。文章對這一結構進行了優化,可以看到,我們的p是一個對稱矩陣,因此我們的權重也可以是一個對稱矩陣,對稱矩陣就可以進行如下的分解:

因此:

因此:

從而得到:

可以看到,我們的權重只需要D1 * N就可以了,時間複雜度也變為了D1*M*N。

2.2 OPNN

OPNN的示意圖如下:

OPNN中p的計算方式如下:

此時pij為M*M的矩陣,計算一個pij的時間複雜度為M*M,而p是N*N*M*M的矩陣,因此計算p的事件複雜度為N*N*M*M。從而計算lp的時間複雜度變為D1 * N*N*M*M。這個顯然代價很高的。為了減少負責度,論文使用了疊加的思想,它重新定義了p矩陣:

這裡計算p的時間複雜度變為了D1*M*(M+N)

3、代碼實戰

終於到了激動人心的代碼實戰環節了,一直想找一個實現比較好的代碼,找來找去tensorflow沒有什麼合適的,倒是pytorch有一個不錯的。沒辦法,只能自己來實現啦,因此本文的代碼嚴格根據論文得到,有不對的的地方或者改進之處還望大家多多指正。

本文的github地址為:
https://github.com/princewen/tensorflow_practice/tree/master/Basic-PNN-Demo.

本文的代碼根據之前DeepFM的代碼進行改進,我們只介紹模型的實現部分,其他數據處理的細節大家可以參考我的github上的代碼.

模型輸入

模型的輸入主要有下面幾個部分:

self.feat_index = tf.placeholder(tf.int32,
                                shape=[None,None],
                                name='feat_index')
self.feat_value = tf.placeholder(tf.float32,
                              shape=[None,None],
                              name='feat_value')

self.label = tf.placeholder(tf.float32,shape=[None,1],name='label')
self.dropout_keep_deep = tf.placeholder(tf.float32,shape=[None],name='dropout_deep_deep')

feat_index是特徵的一個序號,主要用於通過embedding_lookup選擇我們的embedding。feat_value是對應的特徵值,如果是離散特徵的話,就是1,如果不是離散特徵的話,就保留原來的特徵值。label是實際值。還定義了dropout來防止過擬合。

權重構建

權重由四部分構成,首先是embedding層的權重,然後是product層的權重,有線性信號權重,還有平方信號權重,根據IPNN和OPNN分別定義。最後是Deep Layer各層的權重以及輸出層的權重。

對線性信號權重來說,大小為D1 * N * M
對平方信號權重來說,IPNN 的大小為D1 * N,OPNN為D1 * M * M。

def _initialize_weights(self):
   weights = dict()

   #embeddings
   weights['feature_embeddings'] = tf.Variable(
       tf.random_normal([self.feature_size,self.embedding_size],0.0,0.01),
       name='feature_embeddings')
   weights['feature_bias'] = tf.Variable(tf.random_normal([self.feature_size,1],0.0,1.0),name='feature_bias')


   #Product Layers
   if self.use_inner:
       weights['product-quadratic-inner'] = tf.Variable(tf.random_normal([self.deep_init_size,self.field_size],0.0,0.01))
   else:
       weights['product-quadratic-outer'] = tf.Variable(
           tf.random_normal([self.deep_init_size, self.embedding_size,self.embedding_size], 0.0, 0.01))



   weights['product-linear'] = tf.Variable(tf.random_normal([self.deep_init_size,self.field_size,self.embedding_size],0.0,0.01))
   weights['product-bias'] = tf.Variable(tf.random_normal([self.deep_init_size,],0,0,1.0))
   #deep layers
   num_layer = len(self.deep_layers)
   input_size = self.deep_init_size
   glorot = np.sqrt(2.0/(input_size + self.deep_layers[0]))

   weights['layer_0'] = tf.Variable(
       np.random.normal(loc=0,scale=glorot,size=(input_size,self.deep_layers[0])),dtype=np.float32
   )
   weights['bias_0'] = tf.Variable(
       np.random.normal(loc=0,scale=glorot,size=(1,self.deep_layers[0])),dtype=np.float32
   )


   for i in range(1,num_layer):
       glorot = np.sqrt(2.0 / (self.deep_layers[i - 1] + self.deep_layers[i]))
       weights["layer_%d" % i] = tf.Variable(
           np.random.normal(loc=0, scale=glorot, size=(self.deep_layers[i - 1], self.deep_layers[i])),
           dtype=np.float32)  # layers[i-1] * layers[i]
       weights["bias_%d" % i] = tf.Variable(
           np.random.normal(loc=0, scale=glorot, size=(1, self.deep_layers[i])),
           dtype=np.float32)  # 1 * layer[i]


   glorot = np.sqrt(2.0/(input_size + 1))
   weights['output'] = tf.Variable(np.random.normal(loc=0,scale=glorot,size=(self.deep_layers[-1],1)),dtype=np.float32)
   weights['output_bias'] = tf.Variable(tf.constant(0.01),dtype=np.float32)


   return weights

Embedding Layer

這個部分很簡單啦,是根據feat_index選擇對應的weights['feature_embeddings']中的embedding值,然後再與對應的feat_value相乘就可以了:

# Embeddings
self.embeddings = tf.nn.embedding_lookup(self.weights['feature_embeddings'],self.feat_index) # N * F * K
feat_value = tf.reshape(self.feat_value,shape=[-1,self.field_size,1])
self.embeddings = tf.multiply(self.embeddings,feat_value) # N * F * K

Product Layer

根據之前的介紹,我們分別計算線性信號向量,二次信號向量,以及偏置項,三者相加同時經過relu激活得到深度網絡部分的輸入。

# Linear Singal
linear_output = []
for i in range(self.deep_init_size):
   linear_output.append(tf.reshape(
       tf.reduce_sum(tf.multiply(self.embeddings,self.weights['product-linear'][i]),axis=[1,2]),shape=(-1,1)))# N * 1

self.lz = tf.concat(linear_output,axis=1) # N * init_deep_size

# Quardatic Singal
quadratic_output = []
if self.use_inner:
   for i in range(self.deep_init_size):
       theta = tf.multiply(self.embeddings,tf.reshape(self.weights['product-quadratic-inner'][i],(1,-1,1))) # N * F * K
       quadratic_output.append(tf.reshape(tf.norm(tf.reduce_sum(theta,axis=1),axis=1),shape=(-1,1))) # N * 1

else:
   embedding_sum = tf.reduce_sum(self.embeddings,axis=1)
   p = tf.matmul(tf.expand_dims(embedding_sum,2),tf.expand_dims(embedding_sum,1)) # N * K * K
   for i in range(self.deep_init_size):
       theta = tf.multiply(p,tf.expand_dims(self.weights['product-quadratic-outer'][i],0)) # N * K * K
       quadratic_output.append(tf.reshape(tf.reduce_sum(theta,axis=[1,2]),shape=(-1,1))) # N * 1

self.lp = tf.concat(quadratic_output,axis=1) # N * init_deep_size

self.y_deep = tf.nn.relu(tf.add(tf.add(self.lz, self.lp), self.weights['product-bias']))
self.y_deep = tf.nn.dropout(self.y_deep, self.dropout_keep_deep[0])

Deep Part

論文中的Deep Part實際上只有一層,不過我們可以隨意設置,最後得到輸出:

# Deep component
for i in range(0,len(self.deep_layers)):
   self.y_deep = tf.add(tf.matmul(self.y_deep,self.weights["layer_%d" %i]), self.weights["bias_%d"%i])
   self.y_deep = self.deep_layers_activation(self.y_deep)
   self.y_deep = tf.nn.dropout(self.y_deep,self.dropout_keep_deep[i+1])
self.out = tf.add(tf.matmul(self.y_deep,self.weights['output']),self.weights['output_bias'])

剩下的代碼就不介紹啦!

好啦,本文只是提供一個引子,有關PNN的知識大家可以更多的進行學習呦。

參考文獻
1 、https://zhuanlan.zhihu.com/p/33177517
2、https://cloud.tencent.com/developer/article/1104673?fromSource=waitui
3、https://arxiv.org/abs/1611.00144

Python愛好者社區歷史文章大合集

Python愛好者社區歷史文章列表(每周append更新一次)

福利:文末掃碼立刻關注公眾號,「Python愛好者社區」,開始學習Python課程:

關注後在公眾號內回復課程即可獲取:

小編的Python入門免費視頻課程!!!

【最新免費微課】小編的Python快速上手matplotlib可視化庫!!!

崔老師爬蟲實戰案例免費學習視頻。

陳老師數據分析報告製作免費學習視頻。

玩轉大數據分析!Spark2.X+Python 精華實戰課程免費學習視頻。


相關焦點

  • 推薦系統遇上深度學習(八)--AFM模型理論和實踐
    推薦系統遇上深度學習系列:推薦系統遇上深度學習(一)--FM模型理論和實踐推薦系統遇上深度學習(二)--FFM
  • 推薦系統遇上深度學習(二)--FFM模型理論和實踐
    簡單來說,同一個categorical特徵經過One-Hot編碼生成的數值特徵都可以放到同一個field,包括用戶國籍,廣告類型,日期等等。在FFM中,每一維特徵 xi,針對其它特徵的每一種field fj,都會學習一個隱向量 v_i,fj。因此,隱向量不僅與特徵相關,也與field相關。
  • 推薦系統遇上深度學習(十二)--推薦系統中的EE問題及基本Bandit算法
    收錄於話題 #推薦系統遇上深度學習,只需要一行代碼就能在選擇合適的老虎機。
  • 推薦系統遇上深度學習(十七)--探秘阿里之MLR算法淺析及實現
    (learning_rate).minimize(cost)隨後,我們就可以進行試驗了。可以看到,lr的效果是最好的,隨著m的增加,模型的效果越來越差。當然,這並不能說明mlr效果不如lr好,只是我們的數據實在是太少了,哈哈。
  • 推薦系統遇上深度學習(三十三)--Neural Attentive Item Similarity Model
    模型的框架圖如下:好了,模型介紹就到這裡了,關於模型中的一些細節,大家可以閱讀原論文。3、NASI代碼實現作者給出了Python2版本的代碼:https://github.com/AaronHeee/Neural-Attentive-Item-Similarity-Model這個代碼在Python3中是無法運行的,主要是Python3中range函數得到的不是list,需要使用list()函數進行轉換,Python3版本的代碼地址:https://github.com
  • 推薦系統遇上深度學習(三)--DeepFM模型理論和實踐
    對於一個基於CTR預估的推薦系統,最重要的是學習到用戶點擊行為背後隱含的特徵組合。在不同的推薦場景中,低階組合特徵或者高階組合特徵可能都會對最終的CTR產生影響。之前介紹的因子分解機(Factorization Machines, FM)通過對於每一維特徵的隱變量內積來提取特徵組合。最終的結果也非常好。
  • Tensroflow練習,包括強化學習、推薦系統、nlp等
    4、推薦系統推薦系統遇上深度學習(一)--FM模型理論和實踐推薦系統遇上深度學習(二)--FFM模型理論和實踐推薦系統遇上深度學習(三)--DeepFM模型理論和實踐推薦系統遇上深度學習(四)--多值離散特徵的embedding解決方案推薦系統遇上深度學習(五)--Deep&Cross Network模型理論和實踐推薦系統遇上深度學習
  • 推薦系統遇上深度學習(一)--FM模型理論和實踐
    www.jianshu.com/u/c5df9e229a67)     天善社區:https://www.hellobi.com/u/58654/articles     騰訊云:https://cloud.tencent.com/developer/user/16221401、FM背景在計算廣告和推薦系統中
  • 推薦系統遇上深度學習(二十二)--DeepFM升級版XDeepFM模型強勢來襲!
    例如,在新聞推薦場景中,一個三階交叉特徵為AND(user_organization=msra,item_category=deeplearning,time=monday_morning),它表示當前用戶的工作單位為微軟亞洲研究院,當前文章的類別是與深度學習相關的,並且推送時間是周一上午。
  • 推薦系統遇上深度學習(二十)--貝葉斯個性化排序(BPR)算法原理及實戰
    它在學習和預測過程中都將排序列表作為一個樣本。排序的組結構被保持。而模型的最終目標是尋找合適的矩陣W和H,讓X-(公式打不出來,這裡代表的是X上面有一個橫線,即W和H矩陣相乘後的結果)和X(實際的評分矩陣)最相似。看到這裡,也許你會說,BPR和矩陣分解沒有什區別呀?
  • 【推薦實踐】深度學習在阿里B2B電商推薦系統中的實踐
    推薦導購場景在電商中是重要的滿足用戶"逛"和"買"的場景,本次分享我們聚焦深度學習在阿里B2B電商 ( 1688 ) 推薦系統中的應用,其中包括商品推薦中召回 ( 多興趣Deep Match ),排序 ( 自研DMR ) 的相關工作,以及在新興的互動內容場景 ( 直播、短視頻 ) 中通過異構網絡來解決異構信息的精準匹配問題。
  • 【推薦】基於MATLAB編程、機器學習、深度學習在圖像處理中的實踐技術應用
    >Matlab科研經驗分享與科研工具推薦深度學習在遙感地物分類、目標識別和圖像分割技巧總結尤其是在計算機視覺和圖像處理領域,各種顛覆性的成果應運而生。因此,為了幫助廣大科研人員更加系統地學習圖像處理、機器學習和深度學習的基礎理論知識及對應的代碼實現方法,Ai尚研修特舉辦「MATLAB圖像處理與機器學習技術應用培訓班」 培訓班,旨在幫助學員掌握圖像處理的基礎知識,以及經典機器學習算法和最新的深度神經網絡、遷移學習、對抗生成網絡等算法的基本原理及其MATLAB編程實現方法。
  • PNN神經網絡(Matlab)
    它具有如下優點:學習過程簡單、訓練速度快;分類更準確,容錯性好等。從本質上說,它屬於一種有監督的網絡分類器,基於貝葉斯最小風險準則。二、PNN結構該神經網絡與GRNN類似由輸入層、隱含層和輸出層組成。輸入層將變量傳遞給隱含層,但不進行計算,因此該層只起傳輸數據的作用。
  • 深度學習在推薦系統上的應用
    確實深度學習很火,近期深度學習的戰火燒到推薦系統,其強大的表徵能力和低準入門檻,已經成為各大高校和中國人改網絡發paper的紅利時代。可是我還沒能發上那麼幾篇,之前面試大廠的AI labs被總監虐,感覺工作之後被壓榨太多,快幹了。推薦系統為什麼引入深度學習?
  • 深度學習模型及應用詳解!50本包郵贈送福利
    書籍介紹本書內容定位本書側重在實際應用中讓讀者快速掌握基於深度學習模型的系統開發,內容覆蓋以下幾個部分。第1 部分(第1、2 章)講解深度學習的現狀、概念和實現工具。推薦語 本書深入淺出地介紹了深度學習中常用的多種算法和模型,並結合實際的搜索廣告系統,介紹了很多深度神經網絡在實際系統中的應用。本書兼顧了理論介紹和實際應用,尤其適合於想要將深度學習技術應用於工程實踐的讀者閱讀。
  • 新書推薦:TensorFlow深度學習及實踐
    自從深度學習在語音識別和圖像識別任務中取得突破性成果後,使用深度學習的應用數量開始呈爆炸式增加。深度學習方法被大量應用在身份識別、無人駕駛、癌症檢測、遊戲AI等方面,甚至在許多領域,深度神經網絡的準確度已經超過人類自身的操作。深度學習的數學原理並不複雜,但它的一些設計思想很巧妙。入門深度學習,在數學方面只要知道如何對函數求導以及知道與矩陣相乘相關的知識即可。
  • 贈書|從阿里到Facebook,一線大廠這樣做深度學習推薦系統
    本文內容節選自《深度學習推薦系統》一書。由美國Roku推薦系統架構負責人、前Hulu高級研究員王喆精心編著,書中包含了這場革命中一系列的主流技術要點:深度學習推薦模型、Embedding技術、推薦系統工程實現、模型評估體系、業界前沿實踐…………深度學習在推薦系統領域掀起了一場技術革命,本書是一本致力於提高一線算法工程師們工業級推薦系統實踐能力的技術乾貨。
  • 【新書推薦】TensorFlow深度學習及實踐
    TensorFlow是2015年年底開源的一套深度學習框架,也是目前最活躍的深度學習框架之一。《TensorFlow深度學習及實踐》從深度學習的基礎講起,深入TensorFlow的基本框架、原理、原始碼和實現等各個方面,其目的在於降低學習門檻,為讀者解決問題提供詳細的方法和指導。
  • 推薦系統從零單排系列(五)—Word2Vec理論與實踐(下)
    - 2019年已經過去132天-【導讀】上一篇推薦系統從零單排系列(四)—Word2Vec理論與實踐(上)中介紹了CBOW模型,是指根據上下文來預測當前詞
  • 深度學習技術在美圖個性化推薦的應用實踐
    挑戰在實際生產實踐過程當中,主要遇到挑戰如下:海量美圖內容社區有月活超過 1 億的用戶,每天有 100 多萬的候選圖片和視頻。在這種數據規模下,只在小數據規模下驗證有效的複雜算法模型無法直接應用到工業界線上系統。