| 530 | return loss |
| 531 | |
| 532 | class GraphConvolution(nn.Module): |
| 533 | def __init__(self, input_dim, output_dim, dropout=0., is_sparse_inputs=False, bias=False, activation = F.relu,featureless=False): |
| 534 | super(GraphConvolution, self).__init__() |
| 535 | self.dropout = dropout |
| 536 | self.bias = bias |
| 537 | self.activation = activation |
| 538 | self.is_sparse_inputs = is_sparse_inputs |
| 539 | self.featureless = featureless |
| 540 | # self.num_features_nonzero = num_features_nonzero |
| 541 | # self.user_weight = nn.Parameter(torch.randn(input_dim, output_dim)) |
| 542 | # self.item_weight = nn.Parameter(torch.randn(input_dim, output_dim)) |
| 543 | self.user_weight = nn.Parameter(torch.empty(input_dim, output_dim)) |
| 544 | self.item_weight = nn.Parameter(torch.empty(input_dim, output_dim)) |
| 545 | nn.init.xavier_uniform_(self.user_weight) |
| 546 | nn.init.xavier_uniform_(self.item_weight) |
| 547 | self.bias = None |
| 548 | if bias: |
| 549 | self.bias = nn.Parameter(torch.zeros(output_dim)) |
| 550 | |
| 551 | |
| 552 | def forward(self, user_x, item_x, ui_graph, iu_graph): |
| 553 | # print('inputs:', inputs) |
| 554 | # x, support = inputs |
| 555 | # if self.training and self.is_sparse_inputs: |
| 556 | # x = sparse_dropout(x, self.dropout, self.num_features_nonzero) |
| 557 | # elif self.training: |
| 558 | user_x = F.dropout(user_x, self.dropout) |
| 559 | item_x = F.dropout(item_x, self.dropout) |
| 560 | # convolve |
| 561 | if not self.featureless: # if it has features x |
| 562 | if self.is_sparse_inputs: |
| 563 | xw = torch.sparse.mm(user_x, self.user_weight) |
| 564 | xw = torch.sparse.mm(item_x, self.item_weight) |
| 565 | else: |
| 566 | xw_user = torch.mm(user_x, self.user_weight) |
| 567 | xw_item = torch.mm(item_x, self.item_weight) |
| 568 | else: |
| 569 | xw = self.weight |
| 570 | out_user = torch.sparse.mm(ui_graph, xw_item) |
| 571 | out_item = torch.sparse.mm(iu_graph, xw_user) |
| 572 | |
| 573 | if self.bias is not None: |
| 574 | out += self.bias |
| 575 | return self.activation(out_user), self.activation(out_item) |
| 576 | |
| 577 | |
| 578 | def sparse_dropout(x, rate, noise_shape): |
nothing calls this directly
no outgoing calls
no test coverage detected