퍼셉트론
퍼셉트론의 자세한 내용은 이전에 다룬적이 있기 때문에 파이토치에서 퍼셉트론을 구현하는 방법만 다룬다.
2023.09.13 - [책/밑바닥부터 시작하는 딥러닝] - 2장 퍼셉트론
퍼셉트론 모델 실습
데이터셋에 perceptron.csv 파일을 사용해 퍼셉트론을 구현해본다. 데이터는 다음과 같은 형태로 제공된다.
데이터가 bool형이기 때문에 CustomDataset 클래스에서 float으로 바꿔주어야 한다.
class CustomDataset(Dataset):
def __init__(self, file_path):
df = pd.read_csv(file_path)
self.x1 = df.iloc[:, 0].values
self.x2 = df.iloc[:, 1].values
self.y = df.iloc[:, 2].values
self.length = len(df)
def __getitem__(self, index):
x = torch.tensor([self.x1[index], self.x2[index]], dtype=torch.float)
y = torch.tensor([self.y[index]], dtype=torch.float)
return x, y
def __len__(self):
return self.length
train_dataset = CustomDataset(DATA_PATH / "perceptron.csv")
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True, drop_last=True)
단층 퍼셉트론
class CustomModel(nn.Module):
def __init__(self):
super().__init__()
self.layer = nn.Sequential(
nn.Linear(2, 1),
nn.Sigmoid()
)
def forward(self, x):
x = self.layer(x)
return x
학습
device = "cuda" if torch.cuda.is_available() else "cpu"
model = CustomModel().to(device)
criterion = nn.BCELoss().to(device)
optimizer = optim.SGD(model.parameters(), lr=0.01)
for epoch in range(1000):
cost = 0.0
for x, y in train_dataloader:
x = x.to(device)
y = y.to(device)
output = model(x)
loss = criterion(output, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
cost += loss
cost = cost / len(train_dataloader)
if (epoch + 1) % 100 == 0:
print(f"Epoch : {epoch+1:4d}, Cost : {cost:.3f}")
출력 결과
Epoch : 100, Cost : 0.693
Epoch : 200, Cost : 0.692
Epoch : 300, Cost : 0.692
Epoch : 400, Cost : 0.692
Epoch : 500, Cost : 0.692
Epoch : 600, Cost : 0.692
Epoch : 700, Cost : 0.692
Epoch : 800, Cost : 0.692
Epoch : 900, Cost : 0.693
Epoch : 1000, Cost : 0.692
단층 퍼셉트론 구조로 XOR 문제를 해결하려고 한다면, 비용이 더 이상 감소되지 않는 것을 확인할 수 있다.
with torch.no_grad():
model.eval()
inputs = torch.FloatTensor([
[0, 0],
[0, 1],
[1, 0],
[1, 1]
]).to(device)
outputs = model(inputs)
print("---------")
print(outputs)
print(outputs <= 0.5)
출력 결과
---------
tensor([[0.4665],
[0.4981],
[0.5023],
[0.5340]], device='cuda:0')
tensor([[ True],
[ True],
[False],
[False]], device='cuda:0')
모델에 값을 입력했을 때도 출력값이 0.5 내외로 출력돼 학습이 정상적으로 진행되지 않은 것을 확인할 수 있다.
다층 퍼셉트론
class CustomModel(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Sequential(
nn.Linear(2, 2),
nn.Sigmoid()
)
self.layer2 = nn.Sequential(
nn.Linear(2, 1),
nn.Sigmoid()
)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
return x
XOR 문제를 해결하기 위해 계층을 하나 더 추가하였다.
device = "cuda" if torch.cuda.is_available() else "cpu"
model = CustomModel().to(device)
criterion = nn.BCELoss().to(device)
optimizer = optim.SGD(model.parameters(), lr=0.1)
for epoch in range(1000):
cost = 0.0
for x, y in train_dataloader:
x = x.to(device)
y = y.to(device)
output = model(x)
loss = criterion(output, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
cost += loss
cost = cost / len(train_dataloader)
if (epoch + 1) % 100 == 0:
print(f"Epoch : {epoch+1:4d}, Cost : {cost:.3f}")
출력 결과
Epoch : 100, Cost : 0.693
Epoch : 200, Cost : 0.693
Epoch : 300, Cost : 0.693
Epoch : 400, Cost : 0.690
Epoch : 500, Cost : 0.634
Epoch : 600, Cost : 0.187
Epoch : 700, Cost : 0.056
Epoch : 800, Cost : 0.031
Epoch : 900, Cost : 0.021
Epoch : 1000, Cost : 0.016
학습이 진행될수록 비용이 감소하는 것을 확인할 수 있다.
with torch.no_grad():
model.eval()
inputs = torch.FloatTensor([
[0, 0],
[0, 1],
[1, 0],
[1, 1]
]).to(device)
outputs = model(inputs)
print("---------")
print(outputs)
print(outputs <= 0.5)
출력 결과
---------
tensor([[0.0150],
[0.9854],
[0.9799],
[0.0135]], device='cuda:0')
tensor([[ True],
[False],
[False],
[ True]], device='cuda:0')
모델에 값을 입력했을 때 출력값이 XOR 게이트의 출력값과 동일하다는 것도 확인할 수 있다.
퍼셉트론은 이진 분류 작업에서 여전히 사용되는 간단하고 효율적인 모델이지만, 데이터의 복잡한 패턴을 학습하 ㄹ수 없으며, 선형으로 분리되지 않는 데이터를 분류할 수 없는 등 몇 가지 제한 사항이 있다.
'책 > 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습' 카테고리의 다른 글
04 파이토치 심화 (2) 가중치 초기화 (0) | 2024.01.04 |
---|---|
04 파이토치 심화 (1) 과대적합과 과소적합, 배치 정규화 (0) | 2024.01.04 |
03 파이토치 기초 (5) 활성화 함수 (0) | 2024.01.04 |
03 파이토치 기초 (4) 데이터세트와 데이터로더, 모델 저장 및 불러오기 (0) | 2023.12.19 |
03 파이토치 기초 (3) 손실 함수, 최적화 (0) | 2023.12.16 |