Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hid_net #200

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 228 additions & 0 deletions examples/Hid_net/hid_trainer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
import os
import sys
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要添加设置运行后端的代码

import argparse
import gammagl.transforms as T
import tensorlayerx as tlx
from gammagl.datasets import Planetoid
from tensorlayerx.model import TrainOneStep, WithLoss
import argparse
import numpy as np
import warnings
import sys
import argparse
from gammagl.datasets import WikipediaNetwork
from gammagl.models import hid_net
from gammagl.utils import mask_to_index

warnings.filterwarnings('ignore')

class SemiSpvzLoss(WithLoss):
def __init__(self, net, loss_fn):
super(SemiSpvzLoss, self).__init__(backbone=net, loss_fn=loss_fn)

def forward(self, data, graph):
logits = self.backbone_network(data['x'], data['edge_index'],num_nodes=data['num_nodes'])
train_logits = tlx.gather(logits, data['train_mask'])
train_y = tlx.gather(data['y'], data['train_mask'])

loss = self._loss_fn(train_logits,train_y)

return loss
def get_split(y, nclass, seed=0):

percls_trn = int(round(0.6 * len(y) / nclass))
val_lb = int(round(0.2 * len(y)))

indices = []
for i in range(nclass):
h = tlx.convert_to_numpy((y == i))
res = np.nonzero(h)
res = np.array(res).reshape(-1)
index = tlx.convert_to_tensor(res)
n = tlx.get_tensor_shape(index)[0]
index = tlx.gather(index, np.random.permutation(n))
indices.append(index)

train_index = tlx.concat(values=[i[:percls_trn] for i in indices], axis=0)
rest_index = tlx.concat(values=[i[percls_trn:] for i in indices], axis=0)
m = tlx.get_tensor_shape(rest_index)[0]
index2 = tlx.convert_to_tensor(np.random.permutation(m))
index2 = tlx.cast(index2, dtype=tlx.int64)

rest_index = tlx.gather(rest_index, index2)
valid_index = rest_index[:val_lb]
test_index = rest_index[val_lb:]

return train_index, valid_index, test_index
def calculate_acc(logits, y, metrics):
"""
Args:
logits: node logits
y: node labels
metrics: tensorlayerx.metrics

Returns:
rst
"""

metrics.update(logits, y)
rst = metrics.result()
metrics.reset()
return rst

def main(args):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分代码可以放在 if __name__=='__main__':

if args.gpu >= 0:

tlx.set_device("GPU", args.gpu)

else:
tlx.set_device("CPU")


if args.dataset in ['cora', 'citeseer', 'pubmed']:
dataset = Planetoid(args.dataset_path, args.dataset)
graph = dataset[0]
train_idx = mask_to_index(graph.train_mask)
test_idx = mask_to_index(graph.test_mask)
val_idx = mask_to_index(graph.val_mask)
elif args.dataset in ['chameleon', 'squirrel']:
dataset = WikipediaNetwork(root=f'./data', name=args.dataset,transform=T.NormalizeFeatures())
i = args.split
graph = dataset[0]
train_idx, val_idx, test_idx = get_split(y=graph.y, nclass=dataset.num_classes)
data = {
"x": graph.x,
"y": graph.y,
"edge_index": graph.edge_index,
"edge_weight": graph.edge_weight,
"train_mask": train_idx,
"test_mask": test_idx,
"val_mask": val_idx,
"num_nodes": graph.num_nodes,
}
accs = []



if args.gpu >= 0:
tlx.set_device("GPU", args.gpu)
else:
tlx.set_device("CPU")

model = hid_net(in_feats=dataset.num_features,
n_hidden=args.hidden,
n_classes=dataset.num_classes,
k=args.k,
alpha=args.alpha,
beta=args.beta,
gamma=args.gamma,
bias=args.bias,
normalize=args.normalize,
add_self_loops=args.add_self_loops,
drop=args.drop,
dropout=args.dropout,
sigma1=args.sigma1,
sigma2=args.sigma2)



# TODO

optimizer = tlx.optimizers.Adam(lr=args.lr, weight_decay=args.weight_decay)
metrics = tlx.metrics.Accuracy()
train_weights = model.trainable_weights
criterion = tlx.losses.softmax_cross_entropy_with_logits
loss_func = SemiSpvzLoss(model, criterion)

val_accs = []
test_accs = []





Comment on lines +136 to +143
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果只运行一次的话,不需要定义 val_accs, test_accs, accs 等变量,同时,记得删除多余的空行,删除之后更美观一些

train_one_step = TrainOneStep(loss_func, optimizer, train_weights)

for epoch in range(args.repeat):

val_accs = []
test_accs = []


model.set_train()
train_loss = train_one_step(data, graph.y)


model.set_eval()
out= model(data['x'], data['edge_index'],data['edge_weight'],num_nodes=data['num_nodes'])


train_preds=tlx.gather(out,data['train_mask'])
train_y=tlx.gather(data['y'],data['train_mask'])
train_acc=calculate_acc(train_preds,train_y,metrics)


val_preds=tlx.gather(out,data['val_mask'])
val_y=tlx.gather(data['y'],data['val_mask'])
val_loss = criterion(val_preds, val_y)
val_acc=calculate_acc(val_preds,val_y,metrics)
val_accs.append(val_acc)


test_preds=tlx.gather(out,data['test_mask'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在每个epoch中,只需要跑模型在验证集上的结果即可,模型训练完成之后,可以在测试集上进行测试,这部分代码可以参考其他模型的实现代码。

test_y=tlx.gather(data['y'],data['test_mask'])
test_acc=calculate_acc(test_preds,test_y,metrics)
test_accs.append(test_acc)

print(f"Epoch {epoch}: "
f"Train loss = {train_loss:.2f}, "
f"train acc = {train_acc * 100:.2f}, "
f"val loss = {val_loss:.2f}, "
f"val acc = {val_acc * 100:.2f} "
f"test acc = {test_acc * 100:.2f} "
)

max_iter = val_accs.index(max(val_accs))
accs.append(test_accs[max_iter])


print("\t[Classification] acc_mean {:.4f} acc_std {:.4f}"
.format(
np.mean(accs),
np.std(accs),
)
)
if __name__=='__main__':
# Training settings
parser = argparse.ArgumentParser()
parser.add_argument('--times', type=int, default=3, help='config times')
parser.add_argument('--seed', type=int, default=9, help='random seed')
parser.add_argument('--repeat', type=int, default=150, help='repeat time')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议把超参数名称设置为:n_epoch

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

而且在超参数中,好像有些超参数有些并没有用到,后续可以删除。

parser.add_argument('--lr', type=float, default=0.01, help='learning rate')
parser.add_argument('--weight_decay', type=float, default=0.00, help='weight decay (L2 loss on parameters)')
parser.add_argument('--hidden', type=int, default=128, help='hidden size')
parser.add_argument('--head1', type=int, default=1, help='gat head1')
parser.add_argument('--head2', type=int, default=1, help='gat head2')
parser.add_argument('--dropout', type=float, default=0.55, help='dropout rate')
parser.add_argument('--drop', type=str, default='False', help='whether to dropout or not')
parser.add_argument('--dataset', type=str, default='cora', choices=['cora', 'citeseer', 'pubmed', 'chameleon', 'squirrel', 'actor', 'sbm'])
parser.add_argument('--dataset_path', type=str, default='./data', help='path to save dataset')
parser.add_argument('--split', type=int, default=0)
parser.add_argument('--k', type=int, default=10, help='k')
parser.add_argument('--alpha', type=float, default=0.1, help='tolerance to stop EM algorithm')
parser.add_argument('--beta', type=float, default=0.9, help='tolerance to stop EM algorithm')
parser.add_argument('--gamma', type=float, default=0.3, help='tolerance to stop EM algorithm')
parser.add_argument('--sigma1', type=float, default=0.5, help='tolerance to stop EM algorithm')
parser.add_argument('--sigma2', type=float, default=0.5, help='tolerance to stop EM algorithm')
parser.add_argument('--gpu', default='-1', type=int, help='-1 means cpu')
parser.add_argument('--bias', type=bool, default=False, help='if tune')
parser.add_argument('--add_self_loops', type=bool, default=True, help='if tune')
parser.add_argument('--normalize', type=bool, default=True, help='if tune')
args = parser.parse_args()
print(args)
main(args)
os._exit(0)




38 changes: 38 additions & 0 deletions examples/Hid_net/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Representation Learning on Graphs with Jumping Knowledge Networks (JK-Net)
============

- Paper link: [https://arxiv.org/abs/2312.08616](https://arxiv.org/abs/2312.08616)
- Author's code repo: [https://github.com/BUPT-GAMMA/HiD-Net](https://github.com/BUPT-GAMMA/HiD-Net). Note that the original code is
implemented with Tensorflow for the paper.


How to run
----------
Run with following (available dataset: "cora", "citeseer", "pubmed")
```bash
python hid_trainer.py --dataset cora
```
> For details settings, please refer to [here](https://github.com/BUPT-GAMMA/GammaGL/tree/main/examples/gcn#how-to-run).


Results
-------
```bash
TL_BACKEND="mindspore" python hid_trainer.py --dataset cora --alpha 0.1 --beta 0.9 --gamma 0.3 --k 10 --hidden 128 --lr 0.01 --weight_decay 0 --dropout 0.55
TL_BACKEND="mindspore" python hid_trainer.py --dataset citeseer --alpha 0.1 --beta 0.9 --gamma 0.2 --k 10 --hidden 64 --lr 0.005 --weight_decay 0.05 --dropout 0.5
TL_BACKEND="mindspore" python hid_trainer.py --dataset pubmed --alpha 0.08 --beta 0.92 --gamma 0.3 --k 8 --hidden 32 --lr 0.02 --weight_decay 0.0005 --dropout 0.5
TL_BACKEND="paddle" python hid_trainer.py --dataset cora --alpha 0.1 --beta 0.9 --gamma 0.3 --k 10 --hidden 128 --lr 0.01 --weight_decay 0 --dropout 0.55
TL_BACKEND="paddle" python hid_trainer.py --dataset citeseer --alpha 0.1 --beta 0.9 --gamma 0.2 --k 10 --hidden 64 --lr 0.005 --weight_decay 0.05 --dropout 0.5
TL_BACKEND="paddle" python hid_trainer.py --dataset pubmed --alpha 0.08 --beta 0.92 --gamma 0.3 --k 8 --hidden 32 --lr 0.02 --weight_decay 0.0005 --dropout 0.5
TL_BACKEND="tensorflow" python hid_trainer.py --dataset cora --alpha 0.1 --beta 0.9 --gamma 0.3 --k 10 --hidden 128 --lr 0.01 --weight_decay 0 --dropout 0.55
TL_BACKEND="tensorflow" python hid_trainer.py --dataset citeseer --alpha 0.1 --beta 0.9 --gamma 0.2 --k 10 --hidden 64 --lr 0.005 --weight_decay 0.05 --dropout 0.5
TL_BACKEND="tensorflow" python hid_trainer.py --dataset pubmed --alpha 0.08 --beta 0.92 --gamma 0.3 --k 8 --hidden 32 --lr 0.02 --weight_decay 0.0005 --dropout 0.5
TL_BACKEND="torch" python hid_trainer.py --dataset cora --alpha 0.1 --beta 0.9 --gamma 0.3 --k 10 --hidden 128 --lr 0.01 --weight_decay 0 --dropout 0.55
TL_BACKEND="torch" python hid_trainer.py --dataset citeseer --alpha 0.1 --beta 0.9 --gamma 0.2 --k 10 --hidden 64 --lr 0.005 --weight_decay 0.05 --dropout 0.5
TL_BACKEND="torch" python hid_trainer.py --dataset pubmed --alpha 0.08 --beta 0.92 --gamma 0.3 --k 8 --hidden 32 --lr 0.02 --weight_decay 0.0005 --dropout 0.5
```
| Dataset | Paper | Our(ms) | Our(pd) | Our(tf) | Our(th) |
| ---- | ---- | --- | ---- | ---- | ---- |
| cora | 0.8156(±0.0050) | 0.8078(±0.0049) | 0.8274(±0.0190) | 0.8218(±0.0024) | 0.8138(±0.00024) |
| citeseer | 0.6782(±0.00474) | 0.7138(±0.0019) | 0.7134(±0.0012) | 0.7140(±0.0022)| 0.7134(±0.0022)|
| pubmed | | 0.7996(±0.0030) | 0.7910(±0.0044) | 0.8026(±0.0034) | 0.7938(±0.0151) | 0.7920(±0.0097)|
4 changes: 2 additions & 2 deletions examples/gcn/gcn_trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"""

import os
# os.environ['CUDA_VISIBLE_DEVICES'] = '0'
os.environ['CUDA_VISIBLE_DEVICES'] = '1'
# os.environ['TL_BACKEND'] = 'torch'
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分修改的代码不需要提交

# 0:Output all; 1:Filter out INFO; 2:Filter out INFO and WARNING; 3:Filter out INFO, WARNING, and ERROR

import argparse
Expand Down
Loading