forked from chennnM/GCNII
-
Notifications
You must be signed in to change notification settings - Fork 0
/
full-supervised.py
120 lines (107 loc) · 4.53 KB
/
full-supervised.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from __future__ import division
from __future__ import print_function
import time
import random
import argparse
import numpy as np
import torch
import torch.nn.functional as F
import torch.optim as optim
from process import *
from utils import *
from model import *
import uuid
# Training settings
parser = argparse.ArgumentParser()
parser.add_argument('--seed', type=int, default=42, help='Random seed.')
parser.add_argument('--epochs', type=int, default=1500, help='Number of epochs to train.')
parser.add_argument('--lr', type=float, default=0.01, help='learning rate.')
parser.add_argument('--weight_decay', type=float, default=0.01, help='weight decay (L2 loss on parameters).')
parser.add_argument('--layer', type=int, default=64, help='Number of layers.')
parser.add_argument('--hidden', type=int, default=64, help='hidden dimensions.')
parser.add_argument('--dropout', type=float, default=0.5, help='Dropout rate (1 - keep probability).')
parser.add_argument('--patience', type=int, default=100, help='Patience')
parser.add_argument('--data', default='cora', help='dateset')
parser.add_argument('--dev', type=int, default=0, help='device id')
parser.add_argument('--alpha', type=float, default=0.5, help='alpha_l')
parser.add_argument('--lamda', type=float, default=0.5, help='lamda.')
parser.add_argument('--variant', action='store_true', default=False, help='GCN* model.')
args = parser.parse_args()
random.seed(args.seed)
np.random.seed(args.seed)
torch.manual_seed(args.seed)
torch.cuda.manual_seed(args.seed)
cudaid = "cuda:"+str(args.dev)
device = torch.device(cudaid)
checkpt_file = 'pretrained/'+uuid.uuid4().hex+'.pt'
print(cudaid,checkpt_file)
def train_step(model,optimizer,features,labels,adj,idx_train):
model.train()
optimizer.zero_grad()
output = model(features,adj)
acc_train = accuracy(output[idx_train], labels[idx_train].to(device))
loss_train = F.nll_loss(output[idx_train], labels[idx_train].to(device))
loss_train.backward()
optimizer.step()
return loss_train.item(),acc_train.item()
def validate_step(model,features,labels,adj,idx_val):
model.eval()
with torch.no_grad():
output = model(features,adj)
loss_val = F.nll_loss(output[idx_val], labels[idx_val].to(device))
acc_val = accuracy(output[idx_val], labels[idx_val].to(device))
return loss_val.item(),acc_val.item()
def test_step(model,features,labels,adj,idx_test):
model.load_state_dict(torch.load(checkpt_file))
model.eval()
with torch.no_grad():
output = model(features, adj)
loss_test = F.nll_loss(output[idx_test], labels[idx_test].to(device))
acc_test = accuracy(output[idx_test], labels[idx_test].to(device))
return loss_test.item(),acc_test.item()
def train(datastr,splitstr):
adj, features, labels, idx_train, idx_val, idx_test, num_features, num_labels = full_load_data(datastr,splitstr)
features = features.to(device)
adj = adj.to(device)
model = GCNII(nfeat=num_features,
nlayers=args.layer,
nhidden=args.hidden,
nclass=num_labels,
dropout=args.dropout,
lamda = args.lamda,
alpha=args.alpha,
variant=args.variant).to(device)
optimizer = optim.Adam(model.parameters(), lr=args.lr,
weight_decay=args.weight_decay)
bad_counter = 0
best = 999999999
for epoch in range(args.epochs):
loss_tra,acc_tra = train_step(model,optimizer,features,labels,adj,idx_train)
loss_val,acc_val = validate_step(model,features,labels,adj,idx_val)
if(epoch+1)%1 == 0:
print('Epoch:{:04d}'.format(epoch+1),
'train',
'loss:{:.3f}'.format(loss_tra),
'acc:{:.2f}'.format(acc_tra*100),
'| val',
'loss:{:.3f}'.format(loss_val),
'acc:{:.2f}'.format(acc_val*100))
if loss_val < best:
best = loss_val
torch.save(model.state_dict(), checkpt_file)
bad_counter = 0
else:
bad_counter += 1
if bad_counter == args.patience:
break
acc = test_step(model,features,labels,adj,idx_test)[1]
return acc*100
t_total = time.time()
acc_list = []
for i in range(10):
datastr = args.data
splitstr = 'splits/'+args.data+'_split_0.6_0.2_'+str(i)+'.npz'
acc_list.append(train(datastr,splitstr))
print(i,": {:.2f}".format(acc_list[-1]))
print("Train cost: {:.4f}s".format(time.time() - t_total))
print("Test acc.:{:.2f}".format(np.mean(acc_list)))