forked from winterant/DeepCoNN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.py
74 lines (56 loc) · 2.96 KB
/
model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import torch
from torch import nn
class CNN(nn.Module):
def __init__(self, config, word_dim):
super(CNN, self).__init__()
self.kernel_count = config.kernel_count
self.review_count = config.review_count
self.conv = nn.Sequential(
nn.Conv1d(
in_channels=word_dim,
out_channels=config.kernel_count,
kernel_size=config.kernel_size,
padding=(config.kernel_size - 1) // 2), # out shape(new_batch_size, kernel_count, review_length)
nn.ReLU(),
nn.MaxPool2d(kernel_size=(1, config.review_length)), # out shape(new_batch_size,kernel_count,1)
nn.Dropout(p=config.dropout_prob))
self.linear = nn.Sequential(
nn.Linear(config.kernel_count * config.review_count, config.cnn_out_dim),
nn.ReLU(),
nn.Dropout(p=config.dropout_prob))
def forward(self, vec): # input shape(new_batch_size, review_length, word2vec_dim)
latent = self.conv(vec.permute(0, 2, 1)) # out(new_batch_size, kernel_count, 1) kernel count指一条评论潜在向量
latent = self.linear(latent.reshape(-1, self.kernel_count * self.review_count))
return latent # out shape(batch_size, cnn_out_dim)
class FactorizationMachine(nn.Module):
def __init__(self, p, k): # p=cnn_out_dim
super().__init__()
self.v = nn.Parameter(torch.rand(p, k) / 10)
self.linear = nn.Linear(p, 1, bias=True)
self.dropout = nn.Dropout(0.5)
def forward(self, x):
linear_part = self.linear(x) # input shape(batch_size, cnn_out_dim), out shape(batch_size, 1)
inter_part1 = torch.mm(x, self.v) ** 2
inter_part2 = torch.mm(x ** 2, self.v ** 2)
pair_interactions = torch.sum(inter_part1 - inter_part2, dim=1, keepdim=True)
pair_interactions = self.dropout(pair_interactions)
output = linear_part + 0.5 * pair_interactions
return output # out shape(batch_size, 1)
class DeepCoNN(nn.Module):
def __init__(self, config, word_emb):
super(DeepCoNN, self).__init__()
self.embedding = nn.Embedding.from_pretrained(torch.Tensor(word_emb))
self.cnn_u = CNN(config, word_dim=self.embedding.embedding_dim)
self.cnn_i = CNN(config, word_dim=self.embedding.embedding_dim)
self.fm = FactorizationMachine(config.cnn_out_dim * 2, 10)
def forward(self, user_review, item_review): # input shape(batch_size, review_count, review_length)
new_batch_size = user_review.shape[0] * user_review.shape[1]
user_review = user_review.reshape(new_batch_size, -1)
item_review = item_review.reshape(new_batch_size, -1)
u_vec = self.embedding(user_review)
i_vec = self.embedding(item_review)
user_latent = self.cnn_u(u_vec)
item_latent = self.cnn_i(i_vec)
concat_latent = torch.cat((user_latent, item_latent), dim=1)
prediction = self.fm(concat_latent)
return prediction