본문 바로가기
Python/ML&DL

[파이썬, Python] 딥러닝(DeepLearning) - 퍼셉트론과 역전파

by coding-choonsik 2023. 6. 29.
728x90
반응형
SMALL

1. 퍼셉트론(Perceptron)

 

1-1. 생물학적 뉴런

  • 인간의 뇌는 수십억 개의 뉴런을 가지고 있음
  • 뉴런은 화학적, 전기적 신호를 처리하고 전달하는 연결된 뇌신경 세포

 

 

1-2. 인공 뉴런(Perceptron)

  • 1943년에 워렌 맥컬록, 월터 피츠 단순화된 뇌세포 개념을 발표
  • 신경 세포를 이진 출력을 가진 단순한 논리 게이트라고 설명
  • 생물학적 뉴런의 모델에 기초한 수학적 기능으로, 각 뉴런이 입력을 받아 개별적으로 가중치를 곱하여 나온 합계를 비선형 함수를 전달하여 출력을 생성

 

1-3. 논리 회귀(단층 퍼셉트론)로  OR 문제 풀기

 

▲ or 연산의 구조


import torch
import torch.nn as nn
import torch.optim as optim

X = torch.FloatTensor([[0, 0], [0, 1], [1, 0], [1, 1]])
y = torch.FloatTensor([[0], [1], [1], [1]])


model = nn.Sequential(
    nn.Linear(2, 1),
    nn.Sigmoid()  # Sotmax가 아니기 때문에 직접 확률을 구하는 Sigmoid()를 넣어주어야 함
)
print(model)

>>> 
Sequential(
  (0): Linear(in_features=2, out_features=1, bias=True)
  (1): Sigmoid()
)

# 학습
optimizer = optim.SGD(model.parameters(), lr=1)

epochs = 1000

for epoch in range(epochs + 1):
  y_pred = model(X)   # 0과 1 사이에 있으며, 양성 클래스(Positive Class)에 대한 예측 확률
  loss = nn.BCELoss()(y_pred, y)  # 단순 논리 회귀의 loss
  optimizer.zero_grad()
  loss.backward()
  optimizer.step()

  if epoch % 100 == 0:
    y_bool = (y_pred >= 0.5).float()    # y_pred >= 0.5 -> True/False로 반환
    accuracy = (y == y_bool).float().sum() / len(y) * 100

    print(f'Epoch: {epoch:4d}/{epochs} Loss: {loss:.6f} Accuracy: {accuracy:.2f}%')

 


1-4. 논리 회귀(단층 퍼셉트론)로 AND 문제 풀기

 

# 학습 
X = torch.FloatTensor([[0, 0], [0, 1], [1, 0], [1, 1]])
y = torch.FloatTensor([[0], [0], [0], [1]])

model = nn.Sequential(
    nn.Linear(2, 1),
    nn.Sigmoid()  # Softmax가 아니기 때문에 직접 확률을 구하는 Sigmoid()를 넣어주어야 함
)

optimizer = optim.SGD(model.parameters(), lr=1)

epochs = 1000

for epoch in range(epochs + 1):
  y_pred = model(X)   # 0과 1 사이에 있으며, 양성 클래스(Positive Class)에 대한 예측 확률
  loss = nn.BCELoss()(y_pred, y)  # 단순 논리 회귀의 loss
  optimizer.zero_grad()
  loss.backward()
  optimizer.step()

  if epoch % 100 == 0:
    y_bool = (y_pred >= 0.5).float()    # y_pred >= 0.5 -> True/False로 반환
    accuracy = (y == y_bool).float().sum() / len(y) * 100

    print(f'Epoch: {epoch:4d}/{epochs} Loss: {loss:.6f} Accuracy: {accuracy:.2f}%')

 


1-5. 논리 회귀(단층 퍼셉트론)로 XOR 문제 풀기

  • 서로 다른 값이면 True
  • 선형으로 풀 수 없는 문제!

 

X = torch.FloatTensor([[0, 0], [0, 1], [1, 0], [1, 1]])
y = torch.FloatTensor([[0], [1], [1], [0]])

model = nn.Sequential(
    nn.Linear(2, 1),
    nn.Sigmoid()  # Sotmax가 아니기 때문에 직접 확률을 구하는 Sigmoid()를 넣어주어야 함
)

optimizer = optim.SGD(model.parameters(), lr=1)

epochs = 5000  # 학습 반복 수를 늘려도 못맞춤!

for epoch in range(epochs + 1):
  y_pred = model(X)   # 0과 1 사이에 있으며, 양성 클래스(Positive Class)에 대한 예측 확률
  loss = nn.BCELoss()(y_pred, y)  # 단순 논리 회귀의 loss
  optimizer.zero_grad()
  loss.backward()
  optimizer.step()

  if epoch % 100 == 0:
    y_bool = (y_pred >= 0.5).float()    # y_pred >= 0.5 -> True/False로 반환
    accuracy = (y == y_bool).float().sum() / len(y) * 100

    print(f'Epoch: {epoch:4d}/{epochs} Loss: {loss:.6f} Accuracy: {accuracy:.2f}%')

▲ 선형회귀로 풀 수 없음!


2. 역전파(Backpropagation)

  • 1974, by Paul Werbos
  • 1986, by Hinton 재발견

 

# 모델 
model = nn.Sequential(
    nn.Linear(2, 64),  # 여러개의 결과로 다양한 차원으로 기울기를 그림
    nn.Sigmoid(),      # 비선형으로 만듦
    nn.Linear(64, 32),  # 여러개의 Linear 레이어를 쌓음, 한 Layer의 출력 값을 input 개수로 연결
    nn.Sigmoid(),
    nn.Linear(32, 16),
    nn.Sigmoid(),
    nn.Linear(16, 1),
    nn.Sigmoid()
)
print(model)

 

# 학습
optimizer = optim.SGD(model.parameters(), lr=1)

epochs = 5000  # 학습 수를 더 높임

for epoch in range(epochs + 1):
  y_pred = model(X)   # 0과 1 사이에 있으며, 양성 클래스(Positive Class)에 대한 예측 확률
  loss = nn.BCELoss()(y_pred, y)  # 단순 논리 회귀의 loss
  optimizer.zero_grad()
  loss.backward()
  optimizer.step()

  if epoch % 100 == 0:
    y_bool = (y_pred >= 0.5).float()    # y_pred >= 0.5 -> True/False로 반환
    accuracy = (y == y_bool).float().sum() / len(y) * 100

    print(f'Epoch: {epoch:4d}/{epochs} Loss: {loss:.6f} Accuracy: {accuracy:.2f}%')

 

📍 Accuracy 높이는 법
- epoch 수 증가
- 모델 layer 수 증가

 

728x90
반응형
LIST