在《關(guān)于LDA, pLSA, SVD, Word2Vec的一些看法》一文中我們提到了SVD的算法戒突。之前TensorFlow剛出來時(shí)俯艰,就聽說可以很容易的用TF實(shí)現(xiàn)這個(gè)算法(參考這篇文章)寺渗。所以丽惭,就一直想著怎么用mxnet也搞一把岗仑。我們先看看公式
r(ui) = dot(p(u), q(i))
一開始卡在了dot這個(gè)操作上定欧,沒有找到mxnet支持的這個(gè)操作渔呵。后來經(jīng)人提醒,發(fā)現(xiàn)mxnet的python庫中重載了symbol類的運(yùn)算符砍鸠。所以elementwise的乘法可以直接寫成
a = b * c
所以扩氢,迅速就可以寫出網(wǎng)絡(luò)結(jié)構(gòu)了:
def get_net(max_user, max_item):
hidden = 500
user = mx.symbol.Variable('user')
item = mx.symbol.Variable('item')
score = mx.symbol.Variable('score')
user = mx.symbol.Embedding(data = user, input_dim = max_user, output_dim = 1000)
user = mx.symbol.Flatten(data = user)
user = mx.symbol.FullyConnected(data = user, num_hidden = hidden)
item = mx.symbol.Embedding(data = item, input_dim = max_item, output_dim = 1000)
item = mx.symbol.FullyConnected(data = item, num_hidden = hidden)
item = mx.symbol.Flatten(data = item)
pred = user * item
pred = mx.symbol.sum_axis(data = pred, axis = 1)
pred = mx.symbol.Flatten(data = pred)
pred = mx.symbol.LinearRegressionOutput(data = pred, label = score)
return pred
這里user和item各自通過一個(gè)embedding和fc層變成了2個(gè)latent factor。然后pred是這兩個(gè)lantent factor的點(diǎn)積爷辱。然后最后通過一個(gè)LinearRegressionOutput轉(zhuǎn)成一個(gè)回歸問題录豺。
訓(xùn)練了一下,發(fā)現(xiàn)效果很好饭弓,RMSE可以很容易的收斂到0.8x双饥。所以,我們?cè)俅晤I(lǐng)略了自動(dòng)求導(dǎo)框架的威力弟断。而且這個(gè)程序還是GPU就可以train的咏花。
全部的程序見這里。數(shù)據(jù)集就是用的簡單的movielens數(shù)據(jù)集阀趴。
其實(shí)昏翰,這個(gè)程序可以很容易的擴(kuò)展成word2vec的程序,有興趣的同學(xué)可以試一下刘急。另外棚菊,還有一個(gè)思路,是關(guān)于圖片的叔汁。如果我們有一個(gè)很大的關(guān)于圖片相似度的數(shù)據(jù)集统求,那么我們可以用CNN講圖片embeding到一個(gè)vector,然后兩個(gè)圖片的vector點(diǎn)擊作為它們的相似度目標(biāo)攻柠,不知道可以train出什么效果球订。(不要問我從哪兒弄到很大的圖片相似度的數(shù)據(jù)集)