rueki

6. Pytorch를 이용한 ANN 구현 본문

pytorch

6. Pytorch를 이용한 ANN 구현

륵기 2020. 3. 7. 18:54
728x90
반응형
import torch
import numpy as np
import matplotlib.pyplot as plt
import torch.nn.functional as F

# ANN 모델 생성
class Model(nn.Module):
	def __init__(self, in_features=4, h1 =8,h2=9, out_features=3):
    	super().__init__()
        
        self.fc1 = nn.Linear(in_features, h1)
        self.fc2 = nn.Linear(h1,h2)
        self.out = nn.Linear(h2, out_features)
        
        # 입력 -> 은닉층 1 -> 은닉층 2 -> 출력
        
    #순전파
    def forward(self, x):
    	x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.out(x)
        
        return x

기본 ANN 구조 설계 -> 입,출력층 + 은닉층 2개

layer는 전부 fully connected layer로 구성

 

#model 객체 생성
torch.manual_seed(32)
model = Model()

 예제로 iris 데이터 사용을 하였다.

iris data 에는 4개의 features와 1개의 target 값이 존재한다.

iris data의 분류는 multiclassification에 해당된다.

import pandas as pd

df = pd.read_csv('iris.csv')

#iris 데이터에서 train 데이터와 레이블 데이터를 분류하기 위함
X = df.drop('target',axis=1) 
y = df['target']


# array 형태 추출
X=X.values
y=y.values

딥러닝을 위해 데이터의 행렬화를 수행하였다.

추가적으로 torch에 FloatTensor과 같은 텐서화 함수가 있음

이제 sklearn의 train_test_split을 통해 데이터를 나누어 보자

from sklearn.model_selection import train_test_split

#train/test 비율 8 : 2
X_train,X_test, y_train, y_test = train_test_split(X,y, test_size=0.2, random_state=33)

#위에서 설명한 데이터 텐서화
X_train = torch.FloatTensor(X_train)
X_test = torch.FloatTensor(X_test)
y_train = torch.LongTensor(y_train)
y_test = torch.LongTensor(y_test)

#손실함수 정의
criterion = torch.nn.CrossEntropyLoss()

#최적화 함수 정의
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

이로서 훈련을 위한 준비는 완료하였다.

손실을 최소화하는 것이 목적이다.

epochs = 100 #훈련 횟수 100번
losses = [] # loss를 담을 리스트, 시각화 하기 위함

for i in rnage(epochs):
	model.train()
    y_pred = model(X_train)
    
    loss = criterion(y_pred, y_train)
    losses.append(loss)
    
    if i % 10 ==0:
        print(f'epoch {i}, loss is {loss}')
        
    # 역전파 수행
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
'''
epoch 0, loss is 1.150745153427124
epoch 10, loss is 0.937144935131073
epoch 20, loss is 0.7796427011489868
epoch 30, loss is 0.6080240607261658
epoch 40, loss is 0.39879193902015686
epoch 50, loss is 0.25233572721481323
epoch 60, loss is 0.14915479719638824
epoch 70, loss is 0.10022767633199692
epoch 80, loss is 0.08097168058156967
epoch 90, loss is 0.07214364409446716
'''
plt.plot(range(epochs),  losses)
plt.ylabel('loss')
plt.xlabel('Epoch')

모델 훈련이 되었으니 이제 테스트 셋을 적용시켜 보자.

correct = 0

with torch.no_grad():
	for i, data in enumerate(X_test):
    	y_val = model.forward(data)
        
        print(f'{i+1}.) {str(y_val.argmax().item())} {y_test[i]}')
        
        if y_val.argmax().item() == y_test[i]:
            correct += 1
            
print(f'We got {correct} correct!')



'''
1.) 1 1
2.) 1 1
3.) 0 0
4.) 1 1
5.) 2 2
6.) 2 2
7.) 0 0
8.) 0 0
9.) 2 2
10.) 2 2
11.) 2 2
12.) 0 0
13.) 2 2
14.) 1 1
....
We got 30 correct!
'''

이로써 테스트 데이터를 이용해 검증을 해보았고, y_test의 레이블 값과 비교해보았다.

이제 이 model의 가중치와 편향을 저장하는 state_dict()를 통해 모델을 저장하고, 불러와서

새로운 값에 적용시켜서 label을 어떤 것을 출력시키는지 확인해보자.

#모델 저장
torch.save(model.state_dict(),'my_iris_model.pt')

#새 모델 생성
new_model = Model()

#모델 불러오기
new_model.load_state_dict(torch.load('my_iris_model.pt'))

mystery_iris = torch.tensor([5.6,3.7,2.2,0.5])

with torch.no_grad():
	print(new_model(mystery_iris))
    print(new_model(mystery_iris).argmax())
    
'''
tensor([  5.9822,   1.5737, -10.0733])
tensor(0)
'''

argmax를 통해 가장 높은 값을 가지고 있는 인덱스를 반환

 

728x90
반응형
Comments