PyTorch를 사용하여 XOR 문제를 해결
2024. 11. 29. 10:21ㆍAI
반응형
XOR 문제는 비선형 문제로, 선형 계층만으로는 해결할 수 없다. 따라서, 이 모델은 신경망 계층과 비선형 활성화 함수(시그모이드)를 조합하여 XOR 문제를 해결한다.
코드 분석
1. 클래스 정의
class XORModel(nn.Module):
- XORModel은 PyTorch의 nn.Module을 상속받아 정의된 사용자 정의 신경망 클래스이다.
2. 초기화 메서드 (__init__)
def __init__(self):
super(XORModel, self).__init__()
self.layer1 = nn.Linear(2, 2) # 입력 노드 2개, 출력 노드 2개
self.layer2 = nn.Linear(2, 1) # 입력 노드 2개, 출력 노드 1개
self.sigmoid = nn.Sigmoid() # 시그모이드 활성화 함수
- super(XORModel, self).__init__():
- 부모 클래스(nn.Module)의 초기화를 호출하여 PyTorch의 모듈 기능을 활성화한다.
- self.layer1:
- 입력 차원이 2, 출력 차원이 2인 선형 계층 (fully connected layer).
- 첫 번째 계층으로, XOR 문제의 입력 데이터(x1, x2)를 받아 처리한다.
- self.layer2:
- 두 번째 계층으로, layer1의 출력을 입력으로 받아 최종 결과(0 또는 1)를 출력한다.
- self.sigmoid:
- 시그모이드 활성화 함수는 출력값을 [0,1][0, 1] 범위로 정규화한다.
- 비선형성을 도입하여 XOR 문제를 해결할 수 있게 한다.
3. 순전파 메서드 (forward)
def forward(self, x):
x = self.sigmoid(self.layer1(x)) # 첫 번째 계층 + 시그모이드
x = self.sigmoid(self.layer2(x)) # 두 번째 계층 + 시그모이드
return x
- self.layer1(x):
- 입력 데이터(x)를 첫 번째 선형 계층(layer1)에 전달한다.
- 출력은 선형 변환: y=Wx+by = Wx + b 형태이다.
- self.sigmoid:
- 첫 번째 계층의 출력을 비선형 시그모이드 함수에 통과시켜 활성화한다.
- self.layer2(x):
- 첫 번째 계층에서 활성화된 출력값을 두 번째 선형 계층에 전달한다.
- 최종 출력값을 계산한다.
- 반환값:
- [0,1][0, 1] 범위의 값이 반환된다.
- XOR 문제의 출력으로 사용된다.
import torch
import torch.nn as nn
class XORModel(nn.Module):
def __init__(self):
super(XORModel, self).__init__()
self.layer1 = nn.Linear(2, 2) # 입력 2개, 출력 2개
self.layer2 = nn.Linear(2, 1) # 입력 2개, 출력 1개
self.sigmoid = nn.Sigmoid() # 시그모이드 활성화 함수
def forward(self, x):
x = self.sigmoid(self.layer1(x)) # 첫 번째 계층 + 시그모이드
x = self.sigmoid(self.layer2(x)) # 두 번째 계층 + 시그모이드
return x
사용 예시
# 모델 생성
model = XORModel()
# XOR 문제의 입력 데이터
x = torch.tensor([[0.0, 0.0],
[0.0, 1.0],
[1.0, 0.0],
[1.0, 1.0]])
# 출력 예측
output = model(x)
print(output)
모델 구조
- 입력 계층: 2개의 입력 노드.
- 은닉 계층: 2개의 출력 노드를 가진 선형 계층 + 시그모이드 활성화 함수.
- 출력 계층: 1개의 출력 노드를 가진 선형 계층 + 시그모이드 활성화 함수.
- XOR 문제를 해결하기 위해 비선형 활성화 함수를 사용하여 학습 가능.
XOR 문제를 해결하기 위해 정의된 모델을 학습시키는 과정
1. 에포크 반복
for epoch in range(10001):
- XOR 문제의 학습을 10,001번 반복한다.
- epoch: 현재 학습 단계(몇 번째 반복인지)를 나타낸다.
2. 순전파 (Forward pass)
outputs = model(x_data)
- 입력 데이터 x_data를 모델에 전달하여 출력값 outputs를 계산한다.
- 순전파 과정은 모델의 forward 메서드에 의해 정의된 연산을 수행한다.
3. 손실 계산
loss = criterion(outputs, y_data)
- criterion: 손실 함수로, 예측값(outputs)과 실제값(y_data)의 차이를 계산한다.
- XOR 문제에서는 보통 이진 교차 엔트로피 손실(nn.BCELoss)을 사용한다.
- 손실 값은 학습 과정에서 모델이 얼마나 잘못 예측했는지를 나타낸다.
4. 역전파 (Backward pass) 및 최적화
optimizer.zero_grad()
loss.backward()
optimizer.step()
- optimizer.zero_grad(): 이전 에포크에서 계산된 그래디언트를 초기화한다. 그래디언트는 매번 누적되기 때문에 초기화가 필요하다.
- loss.backward(): 현재 에포크에서 계산된 손실값을 기준으로 그래디언트를 계산한다.
- optimizer.step(): 그래디언트를 사용하여 모델의 가중치와 편향을 업데이트한다. 이 과정이 학습이다.
5. 중간 출력
if epoch % 1000 == 0:
print(f'Epoch [{epoch}/10000], Loss: {loss.item():.4f}')
- 매 1,000 에포크마다 현재 에포크 번호와 손실값을 출력한다.
- loss.item(): 텐서 형태의 손실 값을 숫자로 변환하여 출력한다.
import torch
import torch.nn as nn
import torch.optim as optim
# XOR 데이터셋
x_data = torch.tensor([[0.0, 0.0],
[0.0, 1.0],
[1.0, 0.0],
[1.0, 1.0]])
y_data = torch.tensor([[0.0],
[1.0],
[1.0],
[0.0]])
# 모델 정의 (XORModel은 이전에 정의한 클래스 사용)
class XORModel(nn.Module):
def __init__(self):
super(XORModel, self).__init__()
self.layer1 = nn.Linear(2, 2)
self.layer2 = nn.Linear(2, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
x = self.sigmoid(self.layer1(x))
x = self.sigmoid(self.layer2(x))
return x
model = XORModel()
# 손실 함수와 옵티마이저 정의
criterion = nn.BCELoss() # Binary Cross Entropy Loss
optimizer = optim.SGD(model.parameters(), lr=0.1) # Stochastic Gradient Descent
# 학습 루프
for epoch in range(10001):
# 순전파
outputs = model(x_data)
loss = criterion(outputs, y_data)
# 역전파 및 최적화
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 중간 결과 출력
if epoch % 1000 == 0:
print(f'Epoch [{epoch}/10000], Loss: {loss.item():.4f}')
# 학습 결과 확인
print("\nTraining complete!")
with torch.no_grad():
for x, y in zip(x_data, y_data):
prediction = model(x).item()
print(f"Input: {x.tolist()}, Predicted: {prediction:.4f}, Actual: {y.item():.4f}")
- 데이터 정의:
- x_data: XOR 문제의 입력 데이터.
- y_data: XOR 문제의 출력 라벨.
- 모델 및 손실 함수:
- XORModel은 이전에 정의한 모델.
- criterion: 이진 교차 엔트로피 손실을 사용하여 출력값과 실제값의 차이를 계산.
- 학습 과정:
- 10,001번 학습하며 손실을 줄이는 방향으로 모델 가중치를 업데이트.
- 학습 결과:
- 학습이 끝나면 각 입력 데이터에 대해 예측값과 실제값을 비교하여 출력.
학습 결과 예시 출력
Epoch [0/10000], Loss: 0.6931
Epoch [1000/10000], Loss: 0.5023
Epoch [2000/10000], Loss: 0.2789
...
Epoch [10000/10000], Loss: 0.0176
Training complete!
Input: [0.0, 0.0], Predicted: 0.0251, Actual: 0.0000
Input: [0.0, 1.0], Predicted: 0.9736, Actual: 1.0000
Input: [1.0, 0.0], Predicted: 0.9738, Actual: 1.0000
Input: [1.0, 1.0], Predicted: 0.0273, Actual: 0.0000
반응형
'AI' 카테고리의 다른 글
Critical Render Path (0) | 2024.11.15 |
---|---|
PyTorch 환경설정 (0) | 2024.11.13 |
전사 함수(Surjective), 단사 함수(Injective), 전단사 함수(Bijective) (1) | 2024.10.09 |
출력층과 활성화 함수 종류 (1) | 2024.09.30 |
1.x TensorFlow 텐서 선언 방법 (0) | 2024.09.24 |