2023年CS22Wassignment中的所有colab答案以及注释已经上传到github:https://github.com/yuyu990116/CS224W-assignment
CS224W课程地址:http://web.stanford.edu/class/cs224w/
class GCN(torch.nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim, num_layers,dropout, return_embeds=False):
super(GCN, self).__init__()
self.convs = torch.nn.ModuleList()
for i in range(num_layers - 1):
self.convs.append(GCNConv(input_dim, hidden_dim))
input_dim = hidden_dim
self.convs.append(GCNConv(hidden_dim, output_dim))
self.bns=torch.nn.ModuleList([torch.nn.BatchNorm1d
(hidden_dim) for i in range(num_layers-1)])
self.softmax=torch.nn.LogSoftmax()
self.dropout = dropout
self.return_embeds = return_embeds
def reset_parameters(self):
for conv in self.convs:
conv.reset_parameters()
for bn in self.bns:
bn.reset_parameters()
def forward(self, x, adj_t):
for layer in range(len(self.convs)-1):
x=self.convs[layer](x,adj_t)
x=self.bns[layer](x)
x=F.relu(x)
x=F.dropout(x,self.dropout,self.training)
out=self.convs[-1](x,adj_t)
if not self.return_embeds:
out=self.softmax(out)
return out
def train(model, data, train_idx, optimizer, loss_fn):
model.train()
loss = 0
optimizer.zero_grad()
out=model(data.x,data.adj_t)
train_output=out[train_idx]
train_label=data.y[train_idx,0]
loss=loss_fn(train_output,train_label)
loss.backward()
optimizer.step()
return loss.item()
@torch.no_grad()
def test(model, data, split_idx, evaluator):
model.eval()
out=model(data.x,data.adj_t)
y_pred = out.argmax(dim=-1, keepdim=True)
train_acc = evaluator.eval({
'y_true': data.y[split_idx['train']],
'y_pred': y_pred[split_idx['train']],
})['acc']
valid_acc = evaluator.eval({
'y_true': data.y[split_idx['valid']],
'y_pred': y_pred[split_idx['valid']],
})['acc']
test_acc = evaluator.eval({
'y_true': data.y[split_idx['test']],
'y_pred': y_pred[split_idx['test']],
})['acc']
return train_acc, valid_acc, test_acc
args = {
'device': device,
'num_layers': 3,
'hidden_dim': 256,
'dropout': 0.5,
'lr': 0.01,
'epochs': 100,
}
model = GCN(data.num_features, args['hidden_dim'],
dataset.num_classes, args['num_layers'],
args['dropout']).to(device)
evaluator = Evaluator(name='ogbn-arxiv')
import copy
model.reset_parameters()
optimizer = torch.optim.Adam(model.parameters(), lr=args['lr'])
loss_fn = F.nll_loss #交叉熵损失函数
best_model = None
best_valid_acc = 0
for epoch in range(1, 1 + args["epochs"]):
loss = train(model, data, train_idx, optimizer, loss_fn)
result = test(model, data, split_idx, evaluator)
train_acc, valid_acc, test_acc = result
if valid_acc > best_valid_acc:
best_valid_acc = valid_acc
best_model = copy.deepcopy(model)
print(f'Epoch: {epoch:02d}, '
f'Loss: {loss:.4f}, '
f'Train: {100 * train_acc:.2f}%, '
f'Valid: {100 * valid_acc:.2f}% '
f'Test: {100 * test_acc:.2f}%')
best_result = test(best_model, data, split_idx, evaluator)
train_acc, valid_acc, test_acc = best_result
print(f'Best model: '
f'Train: {100 * train_acc:.2f}%, '
f'Valid: {100 * valid_acc:.2f}% '
f'Test: {100 * test_acc:.2f}%')
在外面先另model = GCN(跟模型有关的参数,在init中用到的参数)
再另Out=model(data.x,data.adj_t) 其中data.x,data.adj_t是def forward中用到的参数
init:
self.convs.append(GCNConv(hidden_dim, output_dim))
self.bns=torch.nn.ModuleList([torch.nn.BatchNorm1d
(hidden_dim) for i in range(num_layers-1)])
self.softmax=torch.nn.LogSoftmax()
self.dropout = dropout
self.return_embeds = return_embeds
def forward(self, x, adj_t):
for layer in range(len(self.convs)-1):
x=self.convs[layer](x,adj_t)
x=self.bns[layer](x)
x=F.relu(x)
x=F.dropout(x,self.dropout,self.training)
out=self.convs[-1](x,adj_t)