[Python/PyTorch] GCN을 사용한 모델 만들고 평가하기(accuracy)

들어가기에 앞서 이 글은 신원용교수님 수업의 과제를 수행하며 정리한 글임을 밝힙니다.

데이터 준비

1. 필요한 라이브러리 import

import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid, CoraFull, Actor

from torch_geometric.nn import GCNConv

2. 데이터 셋 불러오기

# Load the Cora dataset
cora_dataset =  Planetoid(root='/tmp/Cora', name='Cora')
cora_data = cora_dataset[0]


# Load the Corafull dataset
corafull_dataset =  CoraFull(root='/tmp/Corafull')
corafull_data = corafull_dataset[0]


# Load the Actor dataset
actor_dataset =  Actor(root='/tmp/Actor')
actor_data = actor_dataset[0]

추가적으로 데이터셋의 정보를 출력해봤다.

# print dataset info
print("  DATASET || nodes | edges | features ")
print("---------------------------------------")
# Q1-a: Print the number of nodes, edges, and features of the Cora network
print(" {0:9}||{1:7}|{2:7}|{3:9}".format("Cora",cora_data.num_nodes, cora_data.num_edges, cora_data.num_node_features))

# Q1-b: Print the number of nodes, edges, and features of the Corafull network
print(" {0:9}||{1:7}|{2:7}|{3:9}".format("Corafull",corafull_data.num_nodes, corafull_data.num_edges, corafull_data.num_node_features))

# Q1-c: Print the number of nodes, edges, and features of the Actor network
print(" {0:9}||{1:7}|{2:7}|{3:9}".format("Actor",actor_data.num_nodes, actor_data.num_edges, actor_data.num_node_features))

결과
picture 1



Graph Neural Network(GNNs)

신경망은 데이터에 대한 연산을 수행하는 계층(layer)/모듈(module)로 구성되어 있다. 신경망은 torch.nn 패키지를 사용하여 생성할 수 있다. torch.nn.Module 신경망은 데이터에 대한 연산을 수행하는 계층(layer)/모듈(module)로 구성되어 있다.

torch.nn.Module은 모든 뉴럴 네트워크 모듈의 기본 클래스이다. 일반적인 모델들은 이 클래스를 상속받아야 한다. 모듈들은 다른 모듈을 또 포함할 수 있다. 이러한 중첩된 구조는 복잡한 아키텍처를 쉽게 구축하고 관리할 수 있다.

init() 메소드에는 신경망 레이어의 구성요소들을 정의하고, forward()에서는 호출 될 때 수행되는 연산을 정의한다. 이 두가지 메소드는 torch.nn.Module을 상속받는 모든 클래스에서 반드시 정의해야 하고 override되어야 한다. nn.Module에서 상속받아 하위 클라스로 처리하는 것은 forward 계산까지 깔끔하게 한 묶음 처리가 가능해지므로 학습 루틴 코딩이 간단해지는 장점이 있을 수 있다.

신경망의 일반적인 학습과정은 다음과 같다.

  1. 학습 가능한 매개 변수(또는 가중치(weight)를 갖는 신경망을 정의한다.
  2. 데이터셋(dataset)입력을 반복한다.
  3. 입력을 신경망에서 전파(process)한다.
  4. 손실(loss: 출력이 정답으로부터 얼마나 떨어져 있는지)을 계산한다.
  5. 변화도(gradient)를 신경망의 매개변수들에 역으로 전파한다. (Backpropagation)
  6. 신경망의 가중치를 갱신한다. 일반적으로 다음과 같은 간단한 규칙을 사용한다.
    업데이트된 가중치(weight) = 가중치(weight) - 학습률(learning rate) * 변화도(gradient)

(출처:[3])



예제코드 분석하기

이를 구현하기 위해 pytorch-geometric의 introduction doc에 소개된 예제를 읽어봤다.

1) Class GCN 정의
예제 코드

import torch
import torch.nn.functional as F # 파이토치에서 제공하는 함수
from torch_geometric.nn import GCNConv

class GCN(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = GCNConv(dataset.num_node_features, 16)
        self.conv2 = GCNConv(16, dataset.num_classes)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index

        x = self.conv1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.conv2(x, edge_index)

        return F.log_softmax(x, dim=1)
  • Class GCN : torch.nn.Module을 상속받는다.
  • __init__() : 모델의 구조와 동작을 정의하는 생성자를 정의한다.
  • super() : 함수를 호출해서 이 클래스가 torch.nn.Module 클래스의 속성들을 가지고 초기화 됨
  • forward() : Class GCN에 해당하는 객체를 데이터와 함께 호출하면 자동으로 실행됨
    model = GCN()
    model(input_data) # 여기서 forward() 자동 수행
  • forward 연산 : H(x)식에 입력 x로부터 예측된 y를 얻는 것

doc에 따르면 non-linearity는 conv에 integrated 되지 않았기 때문에 이후에 적용되어야한다고 한다.
이 코드는 ReLU를 intermediate non-linearity로 골랐고, softmax를 최종 출력으로 사용했다.


2) 모델 학습 시키기

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GCN().to(device)
data = dataset[0].to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)

model.train()
for epoch in range(200):
    optimizer.zero_grad()
    out = model(data)
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()

3) 모델 평가하기

model.eval()
pred = model(data).argmax(dim=1)
correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()
acc = int(correct) / int(data.test_mask.sum())
print(f'Accuracy: {acc:.4f}')
>>> Accuracy: 0.8150



reference
[1] 03-05 클래스로 파이토치 모델 구현하기
[2] Module - PyTorch2.0 documentation
[3] Introduction by Example - pytorch_geometric documentation
[4] 3-3 신경망(torch.nn) Model (MNIST) - PyTorch 딥러닝 챗봇

728x90