| 410 | return loss |
| 411 | |
| 412 | class GraphConvolution(nn.Module): |
| 413 | def __init__(self, input_dim, output_dim, dropout=0., is_sparse_inputs=False, bias=False, activation = F.relu,featureless=False): |
| 414 | super(GraphConvolution, self).__init__() |
| 415 | self.dropout = dropout |
| 416 | self.bias = bias |
| 417 | self.activation = activation |
| 418 | self.is_sparse_inputs = is_sparse_inputs |
| 419 | self.featureless = featureless |
| 420 | # self.num_features_nonzero = num_features_nonzero |
| 421 | # self.user_weight = nn.Parameter(torch.randn(input_dim, output_dim)) |
| 422 | # self.item_weight = nn.Parameter(torch.randn(input_dim, output_dim)) |
| 423 | self.user_weight = nn.Parameter(torch.empty(input_dim, output_dim)) |
| 424 | self.item_weight = nn.Parameter(torch.empty(input_dim, output_dim)) |
| 425 | nn.init.xavier_uniform_(self.user_weight) |
| 426 | nn.init.xavier_uniform_(self.item_weight) |
| 427 | self.bias = None |
| 428 | if bias: |
| 429 | self.bias = nn.Parameter(torch.zeros(output_dim)) |
| 430 | |
| 431 | |
| 432 | def forward(self, user_x, item_x, ui_graph, iu_graph): |
| 433 | # print('inputs:', inputs) |
| 434 | # x, support = inputs |
| 435 | # if self.training and self.is_sparse_inputs: |
| 436 | # x = sparse_dropout(x, self.dropout, self.num_features_nonzero) |
| 437 | # elif self.training: |
| 438 | user_x = F.dropout(user_x, self.dropout) |
| 439 | item_x = F.dropout(item_x, self.dropout) |
| 440 | # convolve |
| 441 | if not self.featureless: # if it has features x |
| 442 | if self.is_sparse_inputs: |
| 443 | xw = torch.sparse.mm(user_x, self.user_weight) |
| 444 | xw = torch.sparse.mm(item_x, self.item_weight) |
| 445 | else: |
| 446 | xw_user = torch.mm(user_x, self.user_weight) |
| 447 | xw_item = torch.mm(item_x, self.item_weight) |
| 448 | else: |
| 449 | xw = self.weight |
| 450 | out_user = torch.sparse.mm(ui_graph, xw_item) |
| 451 | out_item = torch.sparse.mm(iu_graph, xw_user) |
| 452 | |
| 453 | if self.bias is not None: |
| 454 | out += self.bias |
| 455 | return self.activation(out_user), self.activation(out_item) |
| 456 | |
| 457 | |
| 458 | def sparse_dropout(x, rate, noise_shape): |
nothing calls this directly
no outgoing calls
no test coverage detected