《现代推荐算法》神经协同过滤之MLP算法

关注公众号 长歌大腿,发送“机器学习”关键字,可获取包含机器学习(包含深度学习),统计概率,优化算法等系列文本与视频经典资料,如《ESL》《PRML》《MLAPP》等。
《现代推荐算法》神经协同过滤之MLP算法

神经协同过滤简介

前面的文章介绍了协同过滤算法,主要分为基于用户的协同过滤算法与基于物品的协同过滤算法,同时指出,矩阵分解也属于广义的协同过滤算法。
那么之前的文章介绍的SVD,SVD++等等矩阵分解算法都是在传统矩阵分解上面进行的改进。随着神经网络的兴起,神经网络应用到协同过滤算法上,有研究者(何教授)提出了神经协同过滤算法,并将其分为GMF,MLP,NeuMF三种具体的网络结构。
这篇文章为神经协同过滤系列的第二篇文章,我们在本篇文章中介绍其中的MLP模型,在下篇短文中我们再介绍借鉴Wide-Deep结构由GMF与MLP融合而成的NeuMF网络结构。

多层感知机分解(MLP)

MLP是多层感知器分解的简写(Multi-Layer Perceptron).MLP的设计初衷是为了得到关于用户隐空间向量与物品隐空间向量更多的交互特征,故采用多层感知器的结构来进行特征提取。具体而言,MLP使用大量的非线性网络层来提取用户隐向量 p u p_{u} pu与物品隐向量 q i q_{i} qi的交互特征。如下所示
y ^ u , i = σ ( h T ( a L ( W L T ( a L − 1 ( . . . a 2 ( W 2 T [ p u q i ] + b 2 ) . . . ) ) + b L ) ) ) \hat y_{u,i} = \sigma(h^{T}(a_{L}(W_{L}^{T}(a_{L-1}(...a_{2}(W_{2}^{T}\begin{bmatrix} p_{u}\\q_{i} \end{bmatrix}+b_{2})...))+b_{L}))) y^u,i=σ(hT(aL(WLT(aL1(...a2(W2T[puqi]+b2)...))+bL)))
其中 W x W_{x} Wx, b x b_{x} bx, 与 a x a_{x} ax 是权重矩阵,偏执向量,激活函数。

代码实现

我们采用pytorch计算框架来示例MLP的网络结构部分。MLP网络类如下所示,

class MLP(nn.Module):
    def __init__(self, user_num, item_num, factor_num, num_layers, dropout):
        super(MLP, self).__init__()

        self.embed_user_MLP = nn.Embedding(user_num, factor_num * (2 ** (num_layers - 1)))
        self.embed_item_MLP = nn.Embedding(item_num, factor_num * (2 ** (num_layers - 1)))

        MLP_modules = []
        for i in range(num_layers):
            input_size = factor_num * (2 ** (num_layers - i))
            MLP_modules.append(nn.Dropout(p=dropout))
            MLP_modules.append(nn.Linear(input_size, input_size // 2))
            MLP_modules.append(nn.ReLU())
        self.MLP_layers = nn.Sequential(*MLP_modules)

        self.predict_layer = nn.Linear(factor_num, 1)

        self._init_weight_()

    def _init_weight_(self):
        nn.init.normal_(self.embed_user_MLP.weight, std=0.01)
        nn.init.normal_(self.embed_item_MLP.weight, std=0.01)

        for m in self.MLP_layers:
            if isinstance(m, nn.Linear):
                nn.init.xavier_uniform_(m.weight)
                nn.init.kaiming_uniform_(self.predict_layer.weight, a=1, nonlinearity='sigmoid')

    def forward(self, user, item):
        embed_user_MLP = self.embed_user_MLP(user)
        embed_item_MLP = self.embed_item_MLP(item)
        interaction = torch.cat((embed_user_MLP, embed_item_MLP), -1)
        output_MLP = self.MLP_layers(interaction)
        prediction = self.predict_layer(output_MLP)
        return prediction.view(-1)

先根据嵌入层维度等信息初始化网络,同时初始化权重。
网络传播层如代码所示,输入为用户与物品的ID,然后经过嵌入编码,再进行横向拼接,然后经过几个全连接层进行特征提取,最后通过一个全连接线性层加权输出。

你可能感兴趣的:(机器学习)