227 lines
7.8 KiB
Python
227 lines
7.8 KiB
Python
|
||
import numpy as np
|
||
import tensorflow as tf
|
||
from used_for_test import load_data
|
||
from Utils import adj_to_bias
|
||
from gat import GAT
|
||
|
||
|
||
def train(model, inputs, bias_mat, lbl_in, msk_in, training):
|
||
with tf.GradientTape() as tape:
|
||
logits, accuracy, loss = model(inputs=inputs,
|
||
training=True,
|
||
bias_mat=bias_mat,
|
||
lbl_in=lbl_in,
|
||
msk_in=msk_in)
|
||
|
||
gradients = tape.gradient(loss, model.trainable_variables)
|
||
gradient_variables = zip(gradients, model.trainable_variables)
|
||
optimizer.apply_gradients(gradient_variables)
|
||
|
||
return logits, accuracy, loss
|
||
|
||
|
||
def evaluate(model, inputs, bias_mat, lbl_in, msk_in, training):
|
||
logits, accuracy, loss = model(inputs=inputs,
|
||
bias_mat=bias_mat,
|
||
lbl_in=lbl_in,
|
||
msk_in=msk_in,
|
||
training=False)
|
||
return logits, accuracy, loss
|
||
|
||
|
||
|
||
Dataset = 'cora' #param ["cora", "citeseer", "pubmed"]
|
||
Sparse = False #@param {type:"boolean"}
|
||
Batch_Size = 1 #@param {type:"slider", min:1, max:1000, step:1}
|
||
Epochs = 1 #@param {type:"slider", min:1000, max:1000000, step:1}
|
||
Patience = 100 #@param {type:"slider", min:1, max:500, step:1}
|
||
Learning_Rate = 0.005 #@param {type:"slider", min:0, max:0.1, step:0.0001}
|
||
Weight_Decay = 0.0005 #@param {type:"slider", min:0, max:0.1, step:0.0001}
|
||
ffd_drop = 0.6 #@param {type:"slider", min:0, max:1, step:0.01}
|
||
attn_drop = 0.6 #@param {type:"slider", min:0, max:1, step:0.01}
|
||
Residual = False #@param {type:"boolean"}
|
||
|
||
|
||
|
||
|
||
dataset = Dataset
|
||
|
||
# training params
|
||
batch_size = Batch_Size
|
||
nb_epochs = Epochs
|
||
patience = Patience
|
||
lr = Learning_Rate
|
||
l2_coef = Weight_Decay
|
||
residual = Residual
|
||
|
||
|
||
# hid_units = [8,8] # numbers of hidden units per each attention head in each layer
|
||
# n_heads = [1,1,1] # additional entry for the output layer
|
||
hid_units = [8] # numbers of hidden units per each attention head in each layer
|
||
n_heads = [1,1] # additional entry for the output layer
|
||
|
||
|
||
nonlinearity = tf.nn.elu
|
||
optimizer = tf.keras.optimizers.Adam(lr = lr)
|
||
|
||
|
||
print('Dataset: ' + dataset)
|
||
print('----- Opt. hyperparams -----')
|
||
print('lr: ' + str(lr))
|
||
print('l2_coef: ' + str(l2_coef))
|
||
print('----- Archi. hyperparams -----')
|
||
print('nb. layers: ' + str(len(hid_units)))
|
||
print('nb. units per layer: ' + str(hid_units))
|
||
print('nb. attention heads: ' + str(n_heads))
|
||
print('residual: ' + str(residual))
|
||
print('nonlinearity: ' + str(nonlinearity))
|
||
|
||
# 加载数据
|
||
adj, features, y_train, y_val, y_test, train_mask, val_mask, test_mask = load_data()
|
||
# adj, y_train, y_val, y_test, train_mask, val_mask, test_mask,c,r,s1,s2,num,task_cnt = load_data()
|
||
# adj: sparse matrix,边表信息。 2708x2708
|
||
# features:节点信息,2708x1433
|
||
# y_train:标签信息
|
||
# train_mask:哪些是训练样本的标志
|
||
|
||
# nb_nodes = features.shape[0] 3
|
||
# ft_size = features.shape[1] 3
|
||
# nb_classes = y_train.shape[1] 3
|
||
features = features[np.newaxis]
|
||
y_train = y_train[np.newaxis]
|
||
y_val = y_val[np.newaxis]
|
||
y_test = y_test[np.newaxis]
|
||
train_mask = train_mask[np.newaxis]
|
||
val_mask = val_mask[np.newaxis]
|
||
test_mask = test_mask[np.newaxis]
|
||
|
||
# print(f'These are the parameters')
|
||
# print(f'batch_size: {batch_size}')
|
||
# print(f'nb_nodes: {nb_nodes}')
|
||
# print(f'ft_size: {ft_size}')
|
||
# print(f'nb_classes: {nb_classes}')
|
||
|
||
|
||
# adj = adj.todense()
|
||
adj = adj[np.newaxis]
|
||
biases = adj_to_bias(adj, [3], nhood=1)
|
||
|
||
# 定义模型
|
||
# hid_units = [8],n_heads = [8, 1]
|
||
model = GAT(hid_units,n_heads, 3, 3,Sparse,ffd_drop = ffd_drop,attn_drop = attn_drop,activation = tf.nn.elu,residual=False)
|
||
print('model: ' + str('SpGAT' if Sparse else 'GAT'))
|
||
vlss_mn = np.inf
|
||
vacc_mx = 0.0
|
||
curr_step = 0
|
||
|
||
train_loss_avg = 0
|
||
train_acc_avg = 0
|
||
val_loss_avg = 0
|
||
val_acc_avg = 0
|
||
|
||
model_number = 0
|
||
|
||
# 训练
|
||
# initializer = tf.keras.initializers.GlorotUniform()
|
||
# f = initializer(shape=(2, 64))
|
||
# t = tf.Variable(f,name='embeddings', trainable = False)
|
||
|
||
for epoch in range(nb_epochs):
|
||
###Training Segment###
|
||
tr_step = 0
|
||
tr_size = features.shape[0]
|
||
while tr_step * batch_size < tr_size:
|
||
|
||
if Sparse:
|
||
bbias = biases
|
||
else:
|
||
bbias = biases[tr_step * batch_size:(tr_step + 1) * batch_size]
|
||
|
||
_, acc_tr, loss_value_tr = train(model,
|
||
inputs=features[tr_step * batch_size:(tr_step + 1) * batch_size],
|
||
bias_mat=bbias,
|
||
lbl_in=y_train[tr_step * batch_size:(tr_step + 1) * batch_size],
|
||
msk_in=train_mask[tr_step * batch_size:(tr_step + 1) * batch_size],
|
||
training=True)
|
||
train_loss_avg += loss_value_tr
|
||
train_acc_avg += acc_tr
|
||
tr_step += 1
|
||
|
||
###Validation Segment###
|
||
vl_step = 0
|
||
vl_size = features.shape[0]
|
||
while vl_step * batch_size < vl_size:
|
||
|
||
if Sparse:
|
||
bbias = biases
|
||
else:
|
||
bbias = biases[vl_step * batch_size:(vl_step + 1) * batch_size]
|
||
|
||
_, acc_vl, loss_value_vl = evaluate(model,
|
||
inputs=features[vl_step * batch_size:(vl_step + 1) * batch_size],
|
||
bias_mat=bbias,
|
||
lbl_in=y_val[vl_step * batch_size:(vl_step + 1) * batch_size],
|
||
msk_in=val_mask[vl_step * batch_size:(vl_step + 1) * batch_size],
|
||
training=False)
|
||
val_loss_avg += loss_value_vl
|
||
val_acc_avg += acc_vl
|
||
vl_step += 1
|
||
|
||
print('Training: loss = %.5f, acc = %.5f | Val: loss = %.5f, acc = %.5f' %
|
||
(train_loss_avg / tr_step, train_acc_avg / tr_step,
|
||
val_loss_avg / vl_step, val_acc_avg / vl_step))
|
||
|
||
###Early Stopping Segment###
|
||
|
||
if val_acc_avg / vl_step >= vacc_mx or val_loss_avg / vl_step <= vlss_mn:
|
||
if val_acc_avg / vl_step >= vacc_mx and val_loss_avg / vl_step <= vlss_mn:
|
||
vacc_early_model = val_acc_avg / vl_step
|
||
vlss_early_model = val_loss_avg / vl_step
|
||
working_weights = model.get_weights()
|
||
vacc_mx = np.max((val_acc_avg / vl_step, vacc_mx))
|
||
vlss_mn = np.min((val_loss_avg / vl_step, vlss_mn))
|
||
curr_step = 0
|
||
else:
|
||
curr_step += 1
|
||
if curr_step == patience:
|
||
print('Early stop! Min loss: ', vlss_mn, ', Max accuracy: ', vacc_mx)
|
||
print('Early stop model validation loss: ', vlss_early_model, ', accuracy: ', vacc_early_model)
|
||
model.set_weights(working_weights)
|
||
break
|
||
|
||
train_loss_avg = 0
|
||
train_acc_avg = 0
|
||
val_loss_avg = 0
|
||
val_acc_avg = 0
|
||
|
||
###Testing Segment### Outside of the epochs
|
||
|
||
ts_step = 0
|
||
ts_size = features.shape[0]
|
||
ts_loss = 0.0
|
||
ts_acc = 0.0
|
||
while ts_step * batch_size < ts_size:
|
||
|
||
if Sparse:
|
||
bbias = biases
|
||
else:
|
||
bbias = biases[ts_step * batch_size:(ts_step + 1) * batch_size]
|
||
|
||
_, acc_ts, loss_value_ts = evaluate(model,
|
||
inputs=features[ts_step * batch_size:(ts_step + 1) * batch_size],
|
||
bias_mat=bbias,
|
||
lbl_in=y_test[ts_step * batch_size:(ts_step + 1) * batch_size],
|
||
msk_in=test_mask[ts_step * batch_size:(ts_step + 1) * batch_size],
|
||
training=False)
|
||
ts_loss += loss_value_ts
|
||
ts_acc += acc_ts
|
||
ts_step += 1
|
||
|
||
print('Test loss:', ts_loss / ts_step, '; Test accuracy:', ts_acc / ts_step)
|
||
|
||
|
||
# print('Test loss: %.5f, acc = %.5f | Val: loss = %.5f, acc = %.5f' %
|
||
# (train_loss_avg/tr_step, train_acc_avg/tr_step,
|
||
# val_loss_avg/vl_step, val_acc_avg/vl_step))
|