GNNRecom/gnnrec/hge/rgcn/train.py

61 lines
2.3 KiB
Python

import argparse
import torch
import torch.nn.functional as F
import torch.optim as optim
from gnnrec.hge.rgcn.model import RGCN
from gnnrec.hge.utils import set_random_seed, get_device, load_data, calc_metrics, METRICS_STR
def train(args):
set_random_seed(args.seed)
device = get_device(args.device)
data, g, features, labels, predict_ntype, train_idx, val_idx, test_idx, evaluator = \
load_data(args.dataset, device, reverse_self=False)
model = RGCN(
features.shape[1], args.num_hidden, data.num_classes, [predict_ntype],
{ntype: g.num_nodes(ntype) for ntype in g.ntypes}, g.etypes,
predict_ntype, args.num_layers, args.dropout
).to(device)
optimizer = optim.Adam(model.parameters(), lr=args.lr)
features = {predict_ntype: features}
for epoch in range(args.epochs):
model.train()
logits = model(g, features)
loss = F.cross_entropy(logits[train_idx], labels[train_idx])
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(('Epoch {:d} | Loss {:.4f} | ' + METRICS_STR).format(
epoch, loss.item(),
*evaluate(model, g, features, labels, train_idx, val_idx, test_idx, evaluator)
))
@torch.no_grad()
def evaluate(model, g, features, labels, train_idx, val_idx, test_idx, evaluator):
model.eval()
logits = model(g, features)
return calc_metrics(logits, labels, train_idx, val_idx, test_idx, evaluator)
def main():
parser = argparse.ArgumentParser(description='训练R-GCN模型')
parser.add_argument('--seed', type=int, default=8, help='随机数种子')
parser.add_argument('--device', type=int, default=0, help='GPU设备')
parser.add_argument('--dataset', choices=['acm', 'dblp', 'ogbn-mag', 'oag-venue'], default='ogbn-mag', help='数据集')
parser.add_argument('--num-hidden', type=int, default=32, help='隐藏层维数')
parser.add_argument('--num-layers', type=int, default=2, help='模型层数')
parser.add_argument('--dropout', type=float, default=0.8, help='Dropout概率')
parser.add_argument('--epochs', type=int, default=50, help='训练epoch数')
parser.add_argument('--lr', type=float, default=0.01, help='学习率')
args = parser.parse_args()
print(args)
train(args)
if __name__ == '__main__':
main()