在《關(guān)于LDA, pLSA, SVD, Word2Vec的一些看法》一文中我們提到了SVD的算法。之前TensorFlow剛出來時,就聽說可以很容易的用TF實現(xiàn)這個算法(參考這篇文章)。所以,就一直想著怎么用mxnet也搞一把。我們先看看公式
r(ui) = dot(p(u), q(i))
一開始卡在了dot這個操作上,沒有找到mxnet支持的這個操作。后來經(jīng)人提醒,發(fā)現(xiàn)mxnet的python庫中重載了symbol類的運算符。所以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各自通過一個embedding和fc層變成了2個latent factor。然后pred是這兩個lantent factor的點積。然后最后通過一個LinearRegressionOutput轉(zhuǎn)成一個回歸問題。
訓(xùn)練了一下,發(fā)現(xiàn)效果很好,RMSE可以很容易的收斂到0.8x。所以,我們再次領(lǐng)略了自動求導(dǎo)框架的威力。而且這個程序還是GPU就可以train的。
全部的程序見這里。數(shù)據(jù)集就是用的簡單的movielens數(shù)據(jù)集。
其實,這個程序可以很容易的擴(kuò)展成word2vec的程序,有興趣的同學(xué)可以試一下。另外,還有一個思路,是關(guān)于圖片的。如果我們有一個很大的關(guān)于圖片相似度的數(shù)據(jù)集,那么我們可以用CNN講圖片embeding到一個vector,然后兩個圖片的vector點擊作為它們的相似度目標(biāo),不知道可以train出什么效果。(不要問我從哪兒弄到很大的圖片相似度的數(shù)據(jù)集)