Data Science/Algorithms
Pytorch 로 XOR 구현해보기
We will implement a simple XOR sample example while understanding the overall flow of training with PyTorch.
XOR 샘플 예제를 간단하게 구현하면서, PyTorch를 이용한 학습의 전반적인 흐름을 파악해본다. 학습이라는 개념과 학습을 시키기 위한 대상은 어떻게 정의할 수 있는지를 알아보고, PyTorch를 이용할 때, 자동완성? 기능처럼 보이지 않는 동작 내용을 파악하려고 한다.
개념정리
- Tensor 와 Numpy 사이
- Weight와 Bias란?
- requires_grad True와 False?
- Tensor가 동적 그래프로 짜여졌다?
- Optimizer 가 필요한 이유
- Loss Function Backward 와 편미분
- KL Diversity
- Binaray / Logitstic Cross Entropy
- 기타
- 시각화가 필요한 이유
- Tensorboard
- 하이퍼파라미터 튜닝
- Optimizer parameter
- 평가 ( Evaluation )
- 오버피팅 vs 언더피팅
- Early stopping
- Dropout
- L1 , L2( Mean Squared Error ) Loss
- 시각화가 필요한 이유
Note: 항시 마인드 셋을 갖고, 새롭게 도전전하는 일에 대해 “왜?” 해야하는지 스스로의 동기가 필요합니다 :D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import torch
import numpy as np
from tqdm import tqdm
# XOR 문제 1개의 input/hidden/output 레이어의 MLP를 classification으로 활용하여 XOR 문제를 푼다
X = np.array([[0,0],[1,0],[0,1],[1,1]]) # 입력
Y = np.array([[1,0],[0,1],[0,1],[1,0]]) # 출력
print('numpy:',X,Y)
X = torch.tensor(X, dtype=torch.float64) # numpy -> torch (double)
Y = torch.tensor(Y, dtype=torch.float64) # numpy -> torch (double)
print('torch:',X,Y)
# MLP
w1 = torch.tensor(np.random.normal(size=(2,2)), requires_grad=True) # 학습을 위해 requires_grad 옵션 추가
b1 = torch.tensor(np.random.normal(size=(1,2)), requires_grad=True) # 학습을 위해 requires_grad 옵션 추가
print('w1:',w1) # tensor([[ 0.8241, -1.8039], [ 0.6684, -0.6701]], dtype=torch.float64, requires_grad=True)
w2 = torch.tensor(np.random.normal(size=(2,2))) # 학습 불가
b2 = torch.tensor(np.random.normal(size=(1,2))) # 학습 불가
print(w2) # tensor([[ 1.2678, 0.4371], [-1.4530, -0.9344]], dtype=torch.float64) # require_grad가 없음
# 학습을 위해 requires_grad 추가
w2.requires_grad_(True)
print(w2) # tensor([[ 1.2678, 0.4371], [-1.4530, -0.9344]], dtype=torch.float64, requires_grad=True) # requires_grad가 있음
# torch 함수 특징, 함수 끝에 '_'가 있으면 변수 자체에 바로 적용됨. (ex: require_grad, require_grad_)
print(b2) # tensor([[-0.7115], [-0.0490]], dtype=torch.float64)
try:
b2.requires_grad(True) # 함수 명령어는 있으나 이렇게 사용하면 에러
except Exception as e:
print(e)
print('b2:',b2) # tensor([[-0.7115], [-0.0490]], dtype=torch.float64) # 아직 적용 안됨
b2.requires_grad_(True)
print('b2:',b2) # tensor([[-0.7115], [-0.0490]], dtype=torch.float64, requires_grad=True) # 적용 됨
print('''[참고]
신경망 weight 초기화를 위한 권장되는 방법
xavier uniform 이나 normal을 사용하는 것.(코드 참고)
XOR 문제도 local minima가 있음을 기억할 것.
hyperparameter 변경을 통해 극복 가능할지도?''')
# torch.nn.init.xavier_normal_(w1)
# torch.nn.init.xavier_normal_(b1)
# torch.nn.init.xavier_normal_(w2)
# torch.nn.init.xavier_normal_(b2)
# 학습을 위한 준비
opt = torch.optim.Adam([w1,b1,w2,b2]) # optimizer는 Adam, hyperparameter는 임의 입력이 가능하지만, 일단 default값 사용 (learning rate:0.001, beta = (0.9, 0.999), eps=1e-8)
# [학습 1회]
opt.zero_grad()
# 네트워크 동적 계산
xor_mlp_input_layer = X
xor_mlp_hidden_layer = torch.sigmoid(xor_mlp_input_layer@w1+b1)
xor_mlp_output_layer = torch.sigmoid(xor_mlp_hidden_layer@w2+b2)
print('out:',xor_mlp_output_layer) # 현재 모델의 output
loss = torch.mean((xor_mlp_output_layer-Y)**2) # mean-square loss
print('loss:',loss) # 현재 모델의 loss
print('loss(value only):',loss.item())
loss.backward()
print('b2(before):',b2)
opt.step()
print('b2(after):',b2)
# [학습 100000회 반복]
for i in (pbar := tqdm(range(100000))):
opt.zero_grad()
# 네트워크 동적 계산
xor_mlp_input_layer = X
xor_mlp_hidden_layer = torch.sigmoid(xor_mlp_input_layer@w1+b1)
xor_mlp_output_layer = torch.sigmoid(xor_mlp_hidden_layer@w2+b2)
loss = torch.mean((xor_mlp_output_layer-Y)**2) # mean-square loss
loss.backward()
opt.step()
if i%1000 == 0:
pbar.set_description(f'loss:{loss.item()}')
print('입력 데이터:',X)
print('희망 데이터:',Y)
with torch.no_grad(): # 학습 할 필요가 없어서 gradient를 적용하지 않고 계산만 하길 원하는 경우 no_grad 사용
xor_mlp_input_layer = X
xor_mlp_hidden_layer = torch.sigmoid(xor_mlp_input_layer@w1+b1)
xor_mlp_output_layer = torch.sigmoid(xor_mlp_hidden_layer@w2+b2)
xor_classifier_value = xor_mlp_output_layer
print('XOR 신경망 결과:',xor_classifier_value)
*추가 응용 예제
Working on something like this?
I take a small number of paid, scoped reviews: AI agent/RAG architecture diagnosis, Unity CI & build-automation audits, and multimodal QA design review. Each one ends in a written findings document.
Work with me This post is licensed under CC BY 4.0 by the author.
