0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于乘法的運(yùn)算來(lái)體現(xiàn)體征交叉的DNN網(wǎng)絡(luò)結(jié)構(gòu)

lviY_AI_shequ ? 來(lái)源:未知 ? 作者:李倩 ? 2018-08-20 16:41 ? 次閱讀

1、原理

PNN,全稱(chēng)為Product-based Neural Network,認(rèn)為在embedding輸入到MLP之后學(xué)習(xí)的交叉特征表達(dá)并不充分,提出了一種product layer的思想,既基于乘法的運(yùn)算來(lái)體現(xiàn)體征交叉的DNN網(wǎng)絡(luò)結(jié)構(gòu),如下圖:

按照論文的思路,我們也從上往下來(lái)看這個(gè)網(wǎng)絡(luò)結(jié)構(gòu):

輸出層輸出層很簡(jiǎn)單,將上一層的網(wǎng)絡(luò)輸出通過(guò)一個(gè)全鏈接層,經(jīng)過(guò)sigmoid函數(shù)轉(zhuǎn)換后映射到(0,1)的區(qū)間中,得到我們的點(diǎn)擊率的預(yù)測(cè)值:

l2層根據(jù)l1層的輸出,經(jīng)一個(gè)全鏈接層 ,并使用relu進(jìn)行激活,得到我們l2的輸出結(jié)果:

l1層l1層的輸出由如下的公式計(jì)算:

重點(diǎn)馬上就要來(lái)了,我們可以看到在得到l1層輸出時(shí),我們輸入了三部分,分別是lz,lp 和 b1,b1是我們的偏置項(xiàng),這里可以先不管。lz和lp的計(jì)算就是PNN的精華所在了。我們慢慢道來(lái)

Product Layer

product思想來(lái)源于,在ctr預(yù)估中,認(rèn)為特征之間的關(guān)系更多是一種and“且”的關(guān)系,而非add"加”的關(guān)系。例如,性別為男且喜歡游戲的人群,比起性別男和喜歡游戲的人群,前者的組合比后者更能體現(xiàn)特征交叉的意義。

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

在這里,我們要使用到論文中所定義的一種運(yùn)算方式,其實(shí)就是矩陣的點(diǎn)乘啦:

我們先繼續(xù)介紹網(wǎng)絡(luò)結(jié)構(gòu),有關(guān)Product Layer的更詳細(xì)的介紹,我們?cè)谙乱徽轮薪榻B。

Embedding Layer

Embedding Layer跟DeepFM中相同,將每一個(gè)field的特征轉(zhuǎn)換成同樣長(zhǎng)度的向量,這里用f來(lái)表示。

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

2、Product Layer詳細(xì)介紹

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

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

論文中使用的等號(hào)加一個(gè)三角形,其實(shí)就是相等的意思,你可以認(rèn)為z就是embedding層的復(fù)制。

對(duì)于p來(lái)說(shuō),這里需要一個(gè)公式進(jìn)行映射:

不同的g的選擇使得我們有了兩種PNN的計(jì)算方法,一種叫做Inner PNN,簡(jiǎn)稱(chēng)IPNN,一種叫做Outer PNN,簡(jiǎn)稱(chēng)OPNN。

接下來(lái),我們分別來(lái)具體介紹這兩種形式的PNN模型,由于涉及到復(fù)雜度的分析,所以我們這里先定義Embedding的大小為M,field的大小為N,而lz和lp的長(zhǎng)度為D1。

2.1 IPNN

IPNN的示意圖如下:

IPNN中p的計(jì)算方式如下,即使用內(nèi)積來(lái)代表pij:

所以,pij其實(shí)是一個(gè)數(shù),得到一個(gè)pij的時(shí)間復(fù)雜度為M,p的大小為N*N,因此計(jì)算得到p的時(shí)間復(fù)雜度為N*N*M。而再由p得到lp的時(shí)間復(fù)雜度是N*N*D1。因此 對(duì)于IPNN來(lái)說(shuō),總的時(shí)間復(fù)雜度為N*N(D1+M)。文章對(duì)這一結(jié)構(gòu)進(jìn)行了優(yōu)化,可以看到,我們的p是一個(gè)對(duì)稱(chēng)矩陣,因此我們的權(quán)重也可以是一個(gè)對(duì)稱(chēng)矩陣,對(duì)稱(chēng)矩陣就可以進(jìn)行如下的分解:

因此:

因此:

從而得到:

可以看到,我們的權(quán)重只需要D1 * N就可以了,時(shí)間復(fù)雜度也變?yōu)榱薉1*M*N。

2.2 OPNN

OPNN的示意圖如下:

OPNN中p的計(jì)算方式如下:

此時(shí)pij為M*M的矩陣,計(jì)算一個(gè)pij的時(shí)間復(fù)雜度為M*M,而p是N*N*M*M的矩陣,因此計(jì)算p的事件復(fù)雜度為N*N*M*M。從而計(jì)算lp的時(shí)間復(fù)雜度變?yōu)镈1 * N*N*M*M。這個(gè)顯然代價(jià)很高的。為了減少負(fù)責(zé)度,論文使用了疊加的思想,它重新定義了p矩陣:

這里計(jì)算p的時(shí)間復(fù)雜度變?yōu)榱薉1*M*(M+N)

3、代碼實(shí)戰(zhàn)

終于到了激動(dòng)人心的代碼實(shí)戰(zhàn)環(huán)節(jié)了,一直想找一個(gè)實(shí)現(xiàn)比較好的代碼,找來(lái)找去tensorflow沒(méi)有什么合適的,倒是pytorch有一個(gè)不錯(cuò)的。沒(méi)辦法,只能自己來(lái)實(shí)現(xiàn)啦,因此本文的代碼嚴(yán)格根據(jù)論文得到,有不對(duì)的的地方或者改進(jìn)之處還望大家多多指正。

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

本文的代碼根據(jù)之前DeepFM的代碼進(jìn)行改進(jìn),我們只介紹模型的實(shí)現(xiàn)部分,其他數(shù)據(jù)處理的細(xì)節(jié)大家可以參考我的github上的代碼.

模型輸入

模型的輸入主要有下面幾個(gè)部分:

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是特征的一個(gè)序號(hào),主要用于通過(guò)embedding_lookup選擇我們的embedding。feat_value是對(duì)應(yīng)的特征值,如果是離散特征的話,就是1,如果不是離散特征的話,就保留原來(lái)的特征值。label是實(shí)際值。還定義了dropout來(lái)防止過(guò)擬合。

權(quán)重構(gòu)建

權(quán)重由四部分構(gòu)成,首先是embedding層的權(quán)重,然后是product層的權(quán)重,有線性信號(hào)權(quán)重,還有平方信號(hào)權(quán)重,根據(jù)IPNN和OPNN分別定義。最后是Deep Layer各層的權(quán)重以及輸出層的權(quán)重。

對(duì)線性信號(hào)權(quán)重來(lái)說(shuō),大小為D1 * N * M對(duì)平方信號(hào)權(quán)重來(lái)說(shuō),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 ifself.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這個(gè)部分很簡(jiǎn)單啦,是根據(jù)feat_index選擇對(duì)應(yīng)的weights['feature_embeddings']中的embedding值,然后再與對(duì)應(yīng)的feat_value相乘就可以了:

# Embeddingsself.embeddings = tf.nn.embedding_lookup(self.weights['feature_embeddings'],self.feat_index) # N * F * Kfeat_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根據(jù)之前的介紹,我們分別計(jì)算線性信號(hào)向量,二次信號(hào)向量,以及偏置項(xiàng),三者相加同時(shí)經(jīng)過(guò)relu激活得到深度網(wǎng)絡(luò)部分的輸入。

# Linear Singallinear_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 * 1self.lz = tf.concat(linear_output,axis=1) # N * init_deep_size# Quardatic Singalquadratic_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 * 1else: 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 * 1self.lp = tf.concat(quadratic_output,axis=1) # N * init_deep_sizeself.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實(shí)際上只有一層,不過(guò)我們可以隨意設(shè)置,最后得到輸出:

# Deep componentfor 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'])

剩下的代碼就不介紹啦!好啦,本文只是提供一個(gè)引子,有關(guān)PNN的知識(shí)大家可以更多的進(jìn)行學(xué)習(xí)呦。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴

原文標(biāo)題:推薦系統(tǒng)遇上深度學(xué)習(xí)(六)--PNN模型理論和實(shí)踐

文章出處:【微信號(hào):AI_shequ,微信公眾號(hào):人工智能愛(ài)好者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    求助。我國(guó)市級(jí)電話網(wǎng)絡(luò)結(jié)構(gòu)

    我國(guó)的市級(jí)的電話網(wǎng)絡(luò)結(jié)構(gòu)是一樣的么他的結(jié)構(gòu)圖是怎么樣的
    發(fā)表于 11-09 19:43

    【我是電子發(fā)燒友】如何加速DNN運(yùn)算?

    。鑒于篇幅,本文主要針對(duì)論文中的如下幾部分詳細(xì)介紹:DNN的背景,歷史和應(yīng)用DNN的組成部分,以及常見(jiàn)的DNN模型簡(jiǎn)介如何使用硬件加速DNN運(yùn)算
    發(fā)表于 06-14 21:01

    linux不同網(wǎng)絡(luò)結(jié)構(gòu)的不同IP設(shè)法

    Linux的裝系統(tǒng)設(shè)IP,這應(yīng)該是系統(tǒng)管理員的基本功,可是不同的網(wǎng)絡(luò)結(jié)構(gòu)有不同的IP設(shè)法,您知道嗎?
    發(fā)表于 07-05 06:52

    神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)搜索有什么優(yōu)勢(shì)?

    ,稍有不同就無(wú)法復(fù)現(xiàn)論文的結(jié)果。而網(wǎng)絡(luò)結(jié)構(gòu)作為一種特殊的超參數(shù),在深度學(xué)習(xí)整個(gè)環(huán)節(jié)中扮演著舉足輕重的角色。在圖像分類(lèi)任務(wù)上大放異彩的ResNet、在機(jī)器翻譯任務(wù)上稱(chēng)霸的Transformer等網(wǎng)絡(luò)結(jié)構(gòu)
    發(fā)表于 09-11 11:52

    手繪網(wǎng)絡(luò)結(jié)構(gòu)

    手繪一些網(wǎng)絡(luò)結(jié)構(gòu)圖,很初級(jí)
    發(fā)表于 10-25 14:06

    網(wǎng)絡(luò)結(jié)構(gòu)與IP分組交換技術(shù)

    《計(jì)算機(jī)體系結(jié)構(gòu)網(wǎng)絡(luò)篇1、2》之 網(wǎng)絡(luò)結(jié)構(gòu)、IP分組交換技術(shù)、IP/MAC映射、NAT轉(zhuǎn)換等...
    發(fā)表于 12-23 06:05

    TD-SCDMA網(wǎng)絡(luò)結(jié)構(gòu)

    TD-SCDMA 系統(tǒng)的網(wǎng)絡(luò)結(jié)構(gòu)完全遵循3GPP 指定的UMTS 網(wǎng)絡(luò)結(jié)構(gòu),可以分為接入網(wǎng)(UTRAN)和核心網(wǎng)(CN)。本章首先介紹UMTS 的物理網(wǎng)絡(luò)結(jié)構(gòu)模型,根據(jù)TD-SCDMA 系統(tǒng)的接入網(wǎng)和核心網(wǎng)組成闡述
    發(fā)表于 06-19 14:10 ?217次下載

    DeviceNet 網(wǎng)絡(luò)結(jié)構(gòu)

    DeviceNet 網(wǎng)絡(luò)結(jié)構(gòu) 基于現(xiàn)場(chǎng)總線的開(kāi)放的自動(dòng)化系統(tǒng)底層結(jié)構(gòu)近年來(lái)發(fā)展起來(lái)的現(xiàn)場(chǎng)總線技術(shù)以其靈活的控制方式信息共享和低成本等特點(diǎn)被廣泛的用于復(fù)的
    發(fā)表于 03-22 15:46 ?30次下載

    HFC網(wǎng)絡(luò),HFC網(wǎng)絡(luò)結(jié)構(gòu)組成是什么?

    HFC網(wǎng)絡(luò),HFC網(wǎng)絡(luò)結(jié)構(gòu)組成是什么? 一、區(qū)域網(wǎng) 多業(yè)務(wù)系統(tǒng)服務(wù)商(MSO)越來(lái)越常見(jiàn),他們將幾個(gè)相鄰的系統(tǒng)做到一起而組成一個(gè)更大的區(qū)域
    發(fā)表于 03-20 14:04 ?9862次閱讀

    環(huán)形網(wǎng)絡(luò),環(huán)形網(wǎng)絡(luò)結(jié)構(gòu)是什么?

    環(huán)形網(wǎng)絡(luò),環(huán)形網(wǎng)絡(luò)結(jié)構(gòu)是什么? 這種結(jié)構(gòu)網(wǎng)絡(luò)形式主要應(yīng)用于令牌網(wǎng)中,在這種網(wǎng)絡(luò)結(jié)構(gòu)中各設(shè)備是直接通過(guò)電纜來(lái)串接的,最后形成一個(gè)閉環(huán),
    發(fā)表于 03-22 11:14 ?6142次閱讀

    4G網(wǎng)絡(luò)結(jié)構(gòu)及關(guān)鍵技術(shù)

    4G網(wǎng)絡(luò)結(jié)構(gòu)及關(guān)鍵技的精彩講解
    發(fā)表于 11-10 17:19 ?114次下載
    4G<b class='flag-5'>網(wǎng)絡(luò)結(jié)構(gòu)</b>及關(guān)鍵技術(shù)

    幾種典型神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的比較與分析

    幾種典型神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的比較與分析說(shuō)明。
    發(fā)表于 04-28 10:11 ?3次下載

    融合網(wǎng)絡(luò)結(jié)構(gòu)和節(jié)點(diǎn)屬性的鏈接預(yù)測(cè)模型

    融合網(wǎng)絡(luò)結(jié)構(gòu)和節(jié)點(diǎn)屬性的鏈接預(yù)測(cè)模型
    發(fā)表于 06-09 11:41 ?29次下載

    古籍版面分析和風(fēng)格融合網(wǎng)絡(luò)結(jié)構(gòu)分析

    古籍版面分析和風(fēng)格融合網(wǎng)絡(luò)結(jié)構(gòu)分析
    發(fā)表于 06-25 11:45 ?0次下載

    如何優(yōu)化PLC的網(wǎng)絡(luò)結(jié)構(gòu)?

    優(yōu)化PLC的網(wǎng)絡(luò)結(jié)構(gòu)可以提高通信的效率和穩(wěn)定性。以下是一些優(yōu)化PLC網(wǎng)絡(luò)結(jié)構(gòu)的方法: (1)設(shè)計(jì)合理的拓?fù)?b class='flag-5'>結(jié)構(gòu):根據(jù)應(yīng)用需求和設(shè)備分布情況,設(shè)計(jì)合理的網(wǎng)絡(luò)拓?fù)?/div>
    的頭像 發(fā)表于 12-23 08:15 ?654次閱讀
    如何優(yōu)化PLC的<b class='flag-5'>網(wǎng)絡(luò)結(jié)構(gòu)</b>?