def test_gradient(self): gnn = GraphNeuralNetwork(vector_size=2) gnn2 = copy.deepcopy(gnn) gnn.params["W"] = -np.arange(1, 5).reshape(2, 2) gnn.params["b"] = np.array([-100]) graph = [[0, 0, 1, 0, 0], [0, 0, 1, 1, 1], [1, 1, 0, 1, 0], [0, 1, 1, 0, 1], [0, 1, 0, 1, 0]] vertex_size = 5 label = 1 step_size = 3 epsilon1 = -100 expected1 = repr(np.array([-1.])) actual1 = repr(gnn.gradient("b", graph, vertex_size, label, step_size, epsilon=epsilon1)) self.assertEqual(expected1, actual1) epsilon2 = 1.0e-4 for key in gnn.params.keys(): expected2 = gnn2.params _ = gnn2.gradient(key, graph, vertex_size, label, step_size, epsilon=epsilon2) actual2 = gnn2.params self.assertEqual(expected2, actual2)
def test_aggregate(self): gnn = GraphNeuralNetwork() gnn.params["W"] = IDENTITY_WEIGHT H = np.zeros((4, 8)) H[:, 0] = 1 for t in range(4): self.assertTrue(np.array_equal(H, SAMPLE_OUT[t])) H = gnn._aggregate(SAMPLE_GRAPH, H)
def test_call(self): gnn1 = GraphNeuralNetwork(vector_size=2) gnn1.params["W"] = np.arange(1, 5).reshape(2, 2) vertex_size1 = 4 graph1 = [[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]] expected1 = [ [8., 16.], # 集約1~3回 [126., 180.], [1406., 2052.] ] gnn1_2 = GraphNeuralNetwork(vector_size=2) # ReLU確認 gnn1_2.params["W"] = -np.arange(1, 5).reshape(2, 2) expected1_2 = [[0., 0.], [0., 0.], [0., 0.]] gnn2 = GraphNeuralNetwork(vector_size=3) gnn2.params["W"] = np.arange(1, 10).reshape(3, 3) vertex_size2 = 5 graph2 = np.array([[0, 0, 1, 0, 0], [0, 0, 1, 1, 1], [1, 1, 0, 1, 0], [0, 1, 1, 0, 1], [0, 1, 0, 1, 0]]) expected2 = [[12., 24., 36.], [960., 1152., 1344.], [39312., 48384., 57456.]] for i in range(0, 3): actual1 = gnn1(graph1, vertex_size1, i + 1).tolist() self.assertEqual(expected1[i], actual1) actual1_2 = gnn1_2(graph1, vertex_size1, i + 1).tolist() self.assertEqual(expected1_2[i], actual1_2) actual2 = gnn2(graph2, vertex_size2, i + 1).tolist() self.assertEqual(expected2[i], actual2)
def test_predict(self): gnn1 = GraphNeuralNetwork(2) gnn1.params["W"] = np.arange(1, 5).reshape(2, 2) gnn1.params["A"] = np.arange(1, 3) gnn1.params["b"] = np.array([1]) sgd = SGD() trainer1 = Trainer(gnn1, sgd) graphs = [[[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]]] * 10 vertex_sizes = [4] * 10 expected1 = [1] * 10 actual1 = trainer1.predict(graphs, vertex_sizes) self.assertEqual(expected1, actual1) gnn2 = GraphNeuralNetwork(3) gnn2.params["W"] = -np.arange(1, 10).reshape(3, 3) gnn2.params["b"] = -np.array([1]) trainer2 = Trainer(gnn2, sgd) expected2 = [0] * 10 actual2 = trainer2.predict(graphs, vertex_sizes) self.assertEqual(expected2, actual2)
def test_loss(self): gnn = GraphNeuralNetwork(vector_size=3) gnn.params["W"] = -np.arange(1, 10).reshape(3, 3) gnn.params["b"] = np.array([-100]) graphs = [[[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]] ] * 10 vertex_sizes = [4] * 10 labels = [1] * 10 expected = "array([100.])" actual = repr(gnn.loss(graphs, vertex_sizes, labels)) self.assertEqual(expected, actual)
def test_update(self): for vector_size in range(1, 10): sgd = MomentumSGD() gnn = GraphNeuralNetwork(vector_size) expected = gnn.params sgd.update(gnn) actual = gnn.params self.assertEqual(expected, actual) gnn.grads["W"] = np.random.rand(vector_size, vector_size) gnn.grads["A"] = np.random.rand(vector_size) gnn.grads["b"] = np.random.rand(1) v = {} for key, grad in gnn.grads.items(): v[key] = np.zeros_like(grad) params = copy.deepcopy(gnn.params) for _ in range(0, 100): gnn.grads["W"] = np.random.rand(vector_size, vector_size) gnn.grads["A"] = np.random.rand(vector_size) gnn.grads["b"] = np.random.rand(1) sgd.update(gnn) for key, param in params.items(): params[key] = param - sgd.lr * gnn.grads[key]\ + sgd.momentum * v[key] expected1 = repr(params[key]) actual1 = repr(gnn.params[key]) self.assertEqual(expected1, actual1) v[key] = np.array(-sgd.lr * gnn.grads[key] + sgd.momentum * v[key]) expected2 = (repr(v[key])) actual2 = repr(sgd.w[key]) self.assertEqual(expected2, actual2)
def test_backward(self): gnn = GraphNeuralNetwork(vector_size=2) gnn2 = copy.deepcopy(gnn) graphs = [[[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]] ] * 10 vertex_sizes = [4] * 10 labels = [1] * 10 step_size = 4 epsilon = 1.0e-4 params = gnn.params gnn.backward(graphs, vertex_sizes, labels, step_size, epsilon) for key, param in params.items(): expected = repr( gnn2.gradient(key, graphs, vertex_sizes, labels, step_size, epsilon)) actual = repr(gnn.grads[key]) self.assertEqual(expected, actual)
def test_update(self): sgd = SGD() gnn = GraphNeuralNetwork(vector_size=2) expected = gnn.params sgd.update(gnn) actual = gnn.params self.assertEqual(expected, actual) params = copy.deepcopy(gnn.params) for _ in range(100): gnn.grads["W"] = np.random.rand() gnn.grads["A"] = np.random.rand() gnn.grads["b"] = np.random.rand() sgd.update(gnn) for key, param in params.items(): params[key] = param - gnn.grads[key] * sgd.lr expected = repr(params[key]) actual = repr(gnn.params[key]) self.assertEqual(expected, actual)
def test_fit(self): gnn1 = GraphNeuralNetwork(2) gnn2 = GraphNeuralNetwork(2) sgd = MomentumSGD() trainer1 = Trainer(gnn1, sgd) trainer2 = Trainer(gnn2, sgd) graphs = [np.random.randint(0, 2, (10, 10))] * 10 vertex_sizes = [10] * 10 labels1 = [0] * 10 expected1 = [0] * 10 trainer1.fit(graphs, vertex_sizes, labels1) actual1 = trainer1.predict(graphs, vertex_sizes) self.assertEqual(expected1, actual1) labels2 = [1] * 10 expected2 = [1] * 10 trainer2.fit(graphs, vertex_sizes, labels2) actual2 = trainer2.predict(graphs, vertex_sizes) self.assertEqual(expected2, actual2)
def test_get_embedding(self): gnn = GraphNeuralNetwork() gnn.params["W"] = IDENTITY_WEIGHT for t in range(4): gnn.T = t out = gnn._get_embedding(SAMPLE_GRAPH) self.assertTrue(np.array_equal(out, gnn._readout(SAMPLE_OUT[t])))
def test_forward(self): gnn = GraphNeuralNetwork(vertex_size=4, vector_size=2) gnn.W = np.arange(1, 5).reshape(2, 2) graph = np.array([[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]]) # 集約1回目 actual_output1 = gnn.forward(graph, 1).tolist() expected_output1 = [8., 16.] self.assertEqual(expected_output1, actual_output1) actual_x1 = gnn.x.tolist() expected_x1 = [[1., 2.], [2., 4.], [3., 6.], [2., 4.]] self.assertEqual(expected_x1, actual_x1) # 集約2回目 expected_output2 = [126., 180.] actual_output2 = gnn.forward(graph, 1).tolist() self.assertEqual(expected_output2, actual_output2) actual_x2 = gnn.x.tolist() expected_x2 = [[21., 30.], [35., 50.], [35., 50.], [35., 50.]] self.assertEqual(expected_x2, actual_x2) # 集約3回目 expected_output3 = [1406., 2052.] actual_output3 = gnn.forward(graph, 1).tolist() self.assertEqual(expected_output3, actual_output3) actual_x3 = gnn.x.tolist() expected_x3 = [[185., 270.], [370., 540.], [481., 702.], [370., 540.]] self.assertEqual(expected_x3, actual_x3)
def test_accuracy(self): gnn = GraphNeuralNetwork(2) gnn.params["W"] = np.arange(1, 5).reshape(2, 2) gnn.params["A"] = np.arange(1, 3) gnn.params["b"] = np.array([1]) sgd = SGD() trainer = Trainer(gnn, sgd) graphs = [[[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]]] * 10 vertex_sizes = [4] * 10 labels1 = [1] * 10 expected1 = 1. actual1 = trainer.accuracy(graphs, vertex_sizes, labels1) self.assertEqual(expected1, actual1) labels2 = [1] * 7 + [0] * 3 expected2 = 0.7 actual2 = trainer.accuracy(graphs, vertex_sizes, labels2) self.assertEqual(expected2, actual2)
def test__loss(self): gnn = GraphNeuralNetwork(vector_size=2) gnn.params["W"] = -np.arange(1, 5).reshape(2, 2) gnn.params["b"] = np.array([0]) vertex_size = 4 graph = [[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]] label = [0, 1] params = [[0], [-100], [100]] expecteds = [[0.6931471805599453] * 2, [0., 100.], [100., 0.]] for param, expected in zip(params, expecteds): gnn.params["b"] = np.array(param) actual1 = gnn._loss(graph, vertex_size, label[0]) self.assertEqual(expected[0], actual1) actual2 = gnn._loss(graph, vertex_size, label[1]) self.assertEqual(expected[1], actual2)
def test_forward(self): gnn = GraphNeuralNetwork(vector_size=2) gnn.params["W"] = np.arange(1, 5).reshape(2, 2) gnn.params["A"] = np.arange(1, 3) gnn.params["b"] = np.array([1]) vertex_size = 4 graph = [[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]] expected = [[41.], [487.], [5511.]] # 集約1~3回 for i in range(0, 3): actual = gnn.forward(graph, vertex_size, i + 1).tolist() self.assertEqual(expected[i], actual)
def test_kfold_cross_val(self): gnn = GraphNeuralNetwork(2) sgd = SGD() trainer = Trainer(gnn, sgd) graphs = [[[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]]] * 100 vertex_sizes = [4] * 100 labels = [0] * 100 expected = gnn.params _ = trainer.kfold_cross_validation(graphs, vertex_sizes, labels) actual = gnn.params self.assertEqual(expected, actual) with self.assertRaises(SplitError): trainer.kfold_cross_validation(graphs, vertex_sizes, labels, minibatch_size=20) trainer.kfold_cross_validation(graphs, vertex_sizes, labels, k=20)
def test_update(self): for vector_size in range(1, 10): adam = Adam() gnn = GraphNeuralNetwork(vector_size) expected = gnn.params adam.update(gnn) actual = gnn.params self.assertEqual(expected, actual) gnn.grads["W"] = np.random.rand(vector_size, vector_size) gnn.grads["A"] = np.random.rand(vector_size) gnn.grads["b"] = np.random.rand(1) v = {} m = {} for key, grad in gnn.grads.items(): v[key] = np.zeros_like(grad) m[key] = np.zeros_like(grad) params = copy.deepcopy(gnn.params) for i in range(1, 100): gnn.grads["W"] = np.random.rand(vector_size, vector_size) gnn.grads["A"] = np.random.rand(vector_size) gnn.grads["b"] = np.random.rand(1) adam.update(gnn) for key, param in params.items(): m[key] = adam.beta1 * m[key] + ( (1 - adam.beta1) * gnn.grads[key]) v[key] = adam.beta2 * v[key] + ( (1 - adam.beta2) * gnn.grads[key]**2) m_hat = m[key] / (1 - adam.beta1**i) v_hat = v[key] / (1 - adam.beta2**i) params[key] = param - adam.lr * m_hat / (np.sqrt(v_hat) + 1.0e-8) expected1 = repr( np.round(np.abs(params[key] - gnn.params[key]), 6)) actual1 = repr(np.zeros_like(params[key])) self.assertEqual(expected1, actual1)
for epoch in range(epoch_num): np.random.shuffle(train_data) iter_num = TRAIN_NUM // MINIBATCH_SIZE for mb_idx in range(iter_num): minibatch = train_data[mb_idx * MINIBATCH_SIZE:(mb_idx + 1) * MINIBATCH_SIZE] gnn.gradient_descent(minibatch) # 1 epoch中に2回testを計算 if mb_idx in [0, iter_num // 2]: loss, accuracy = test(gnn, test_data) if loss < loss_uppper_bound and accuracy > accuracy_lower_bound: print("epoch: {}, loss: {}, accuracy: {}".format( epoch, loss, accuracy)) return True return False if __name__ == "__main__": train_data = read_train_data() test_data = read_test_data() for i in range(100): print("{}th model".format(i)) gnn = GraphNeuralNetwork(Adam()) if train_best(gnn, train_data, test_data, epoch_num=100): path_name = "model/best_model.pickle" os.makedirs(os.path.dirname(path_name), exist_ok=True) with open(path_name, mode="wb") as f: pickle.dump(gnn, f) print("{} saved!".format(path_name)) exit(0)
import sys sys.path.append("src/") from gnn import GraphNeuralNetwork from optimizer import SGD, Momentum from train import read_train_data, read_test_data, train if __name__ == "__main__": train_data = read_train_data() test_data = read_test_data() optimizers = {"SGD": SGD, "Momentum": Momentum} for i in range(5): for name, Optimizer in optimizers.items(): print("{}th {} start!".format(i, name)) gnn = GraphNeuralNetwork(Optimizer()) train(gnn, train_data, test_data, epoch_num=100, print_train_loss=True)
from gnn import GraphNeuralNetwork from optimizer import Adam from trainer import Trainer if __name__ == "__main__": train_len = 2000 test_len = 500 train_vertex = [np.loadtxt(f"../datasets/train/{i}_graph.txt", dtype=np.int, usecols=0)[0] for i in range(train_len)] train_graph = [np.loadtxt(f"../datasets/train/{i}_graph.txt", dtype=np.int, skiprows=1) for i in range(train_len)] train_label = [np.loadtxt(f"../datasets/train/{i}_label.txt", dtype=np.int) for i in range(train_len)] test_vertex = [np.loadtxt(f"../datasets/test/{i}_graph.txt", dtype=np.int, usecols=0)[0] for i in range(test_len)] test_graph = [np.loadtxt(f"../datasets/test/{i}_graph.txt", dtype=np.int, skiprows=1) for i in range(test_len)] gnn = GraphNeuralNetwork(vector_size=8) adam = Adam() trainer = Trainer(gnn, adam) loss = trainer.fit(train_graph, train_vertex, train_label, minibatch_size=140, epoch=25) pred = trainer.predict(test_graph, test_vertex) np.savetxt("../pred.txt", np.array(pred).reshape(-1, 1), fmt='%d') plt.xlabel("iterations") plt.ylabel("loss") plt.plot(np.arange(len(loss)), loss, label="Adam") plt.legend() plt.show()
import numpy as np import matplotlib.pyplot as plt from gnn import GraphNeuralNetwork from sgd import SGD if __name__ == "__main__": gnn = GraphNeuralNetwork(8, 0) sgd = SGD() graph = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0]] vertex_size = 11 label = 1 loss = [] print("A") for i in range(0, 50): loss.append(gnn.loss(graph, vertex_size, label)) gnn.backward(graph, vertex_size, label) sgd.update(gnn) loss.append(gnn.loss(graph, vertex_size, label)) print(f"最初の損失:{loss[0]}, 最後の損失:{loss[-1]}")
def test_predict(self): gnn1 = GraphNeuralNetwork(vector_size=2) gnn1.params["W"] = np.arange(1, 5).reshape(2, 2) gnn1.params["A"] = np.arange(1, 3) gnn1.params["b"] = np.array([1]) gnn2 = GraphNeuralNetwork(vector_size=2) gnn2.params["W"] = -np.arange(1, 5).reshape(2, 2) gnn2.params["b"] = np.array([-1]) vertex_size = 4 graph = [[0, 0, 1, 0], [0, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]] expected1 = 1 actual1 = gnn1.predict(graph, vertex_size) self.assertEqual(expected1, actual1) expected2 = 0 actual2 = gnn2.predict(graph, vertex_size) self.assertEqual(expected2, actual2)
import numpy as np from gnn import GraphNeuralNetwork from optimizer import MomentumSGD from trainer import Trainer if __name__ == "__main__": file_len = 2000 vertex_data = [np.loadtxt(f"../train/{i}_graph.txt", dtype=np.int, usecols=0)[0] for i in range(file_len)] graph_data = [np.loadtxt(f"../train/{i}_graph.txt", dtype=np.int, skiprows=1) for i in range(file_len)] label_data = [np.loadtxt(f"../train/{i}_label.txt", dtype=np.int) for i in range(file_len)] gnn = GraphNeuralNetwork(vector_size=8, seed=0) sgd = MomentumSGD() trainer = Trainer(gnn, sgd) print("10分割交差検証を行った時の平均損失と平均精度") train_loss, test_loss, train_score, test_score = trainer.kfold_cross_validation(graph_data, vertex_data, label_data, minibatch_size=140, epoch=25) print(f"学習時の平均損失:{train_loss}, 平均:{np.mean(train_loss)}") print(f"検定時の平均損失:{test_loss}, 平均:{np.mean(test_loss)}") print(f"学習時の平均精度:{train_score}, 平均:{np.mean(train_score)}") print(f"検定時の平均精度:{test_score}, 平均:{np.mean(test_score)}")
import sys sys.path.append("src/") from gnn import GraphNeuralNetwork from optimizer import SGD from train import read_graph, read_label if __name__ == "__main__": graph = read_graph(0) label = read_label(0) print("label: {}".format(label)) gnn = GraphNeuralNetwork(optimizer=SGD()) for i in range(1000): print("[{}th iteration] loss: {}, p: {}".format( i, gnn.loss(graph, label)[0], gnn._get_p(graph)[0], )) gnn.gradient_descent([(graph, label)])