수업 복습/머신러닝과 딥러닝
딥러닝
김복칠
2024. 1. 16. 19:07
1. 뉴런(neuron)
1-1. 생물학적 뉴런
- 인간의 뇌는 수십억 개의 뉴런을 가지고 있음
- 뉴런은 화학적, 전기적 신호를 처리하고 전달하는 연결된 뇌신경 세포
1-2.인공 뉴런
- 1943년에 워렌 맥컬록, 월터 피츠가 단순화된 뇌세포 개념을 발표
- 신경 세포를 이진 출력을 가진 단순한 논리 게이트라고 설명
- 생물학적 뉴런의 모델에 기초한 수학적 기능으로, 각 뉴런이 입력을 받아 개별적으로 가중치를 곱하여 나온 합계를 비선형 함수를 전달하여 출력을 생성
2. 퍼셉트론(Perceptron)
- 인공 신경망의 가장 기본적인 형태로 1957년에 처음 소개됨
- 입력과 출력을 가진 단일 뉴런 모델을 기반
- 초기의 기꼐 학습 알고리즘 중 하나로 이진 분류 문제를 해결하기 위해 설계
2-1. 논리 회귀(단층 퍼셉트론)로 AND 문제 풀기
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
x_data = torch.FloatTensor([[0,0],[0,1],[1,0],[1,1]])
y_data = torch.FloatTensor([[0],[0],[0],[1]])
model = nn.Sequential(
nn.Linear(2,1),
nn.Sigmoid()
)
optimizer = optim.SGD(model.parameters(), lr=1)
epochs = 1000
for epoch in range(epochs + 1):
y_pred = model(x_data)
loss = nn.BCELoss()(y_pred, y_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
y_bool = (y_pred >= 0.5).float()
accuracy = (y_data == y_bool).float().sum() / len(y_data) * 100
print(f'Epoch : {epoch:4d}/{epochs} Loss : {loss : .6f} Accuracy : {accuracy : .2f}')
- 딥러닝을 진행하기 전에 첫번째 러닝 과정을 진행해 보겠습니다
- 먼저 임의의 입력데이터와 출력데이터를 만들어준뒤 그에 맞는 모델을 구성해 줍니다
- 랜덤으로 데이터를 뽑는 SGD 활성화 함수를 사용해 줍니다
- 이제 학습을 진행해 주는데 이 경우에는 이중분류에 해당하는 학습이기 때문에 BCELoss() 함수를 이용해 줍니다
2-2. 논리 회귀로 OR 문제 풀기
x_data = torch.FloatTensor([[0,0],[0,1],[1,0],[1,1]])
y_data = torch.FloatTensor([[0],[1],[1],[1]])
model = nn.Sequential(
nn.Linear(2,1),
nn.Sigmoid()
)
optimizer = optim.SGD(model.parameters(), lr=1)
epochs = 1000
for epoch in range(epochs + 1):
y_pred = model(x_data)
loss = nn.BCELoss()(y_pred, y_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
y_bool = (y_pred >= 0.5).float()
accuracy = (y_data == y_bool).float().sum() / len(y_data) * 100
print(f'Epoch : {epoch:4d}/{epochs} Loss : {loss : .6f} Accuracy : {accuracy : .2f}')
- OR의 경우도 AND와 동일합니다
- 이렇게 두번의 학습을 통해 확인한 결과로는 AND, OR 의 이중분류의 경우에는 단층 퍼셉트론으로 충분히 학습이 가능하다는 것을 알 수 있습니다
2-3. 논리 회귀로 XOR 문제 풀기
x_data = torch.FloatTensor([[0,0],[0,1],[1,0],[1,1]])
y_data = torch.FloatTensor([[0],[1],[1],[0]])
model = nn.Sequential(
nn.Linear(2,1),
nn.Sigmoid()
)
optimizer = optim.SGD(model.parameters(), lr=1)
epochs = 1000
for epoch in range(epochs + 1):
y_pred = model(x_data)
loss = nn.BCELoss()(y_pred, y_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
y_bool = (y_pred >= 0.5).float()
accuracy = (y_data == y_bool).float().sum() / len(y_data) * 100
print(f'Epoch : {epoch:4d}/{epochs} Loss : {loss : .6f} Accuracy : {accuracy : .2f}')
- XOR은 AND, OR과 다르게 단층 퍼셉트론(단일 레이어)로는 학습이 되지 않는걸 확인 할 수 있습니다
- 그 이유는 한번 모델에 들어갔다 온다고 해서 규칙을 파악하기가 쉽지 않기 때문입니다
- 이를 해결하기 위해 더 많은 레이어를 넣어서 학습을 진행하는 방법이 있습니다
2-4. 다층 퍼셉트론으로 XOR 문제 풀기
- 여러개의 층을 만들어 해결
model = nn.Sequential(
nn.Linear(2,64),
nn.Sigmoid(),
nn.Linear(64,32),
nn.Sigmoid(),
nn.Linear(32,16),
nn.Sigmoid(),
nn.Linear(16,1),
nn.Sigmoid()
)
- 모델의 층을 여러번 주면서 데이터가 입력되었을때 다양한 경우를 학습하고 out 할 수 있게끔 구조를 만들어 줍니다
optimizer = optim.SGD(model.parameters(), lr=1)
epochs = 5000
for epoch in range(epochs + 1):
y_pred = model(x_data)
loss = nn.BCELoss()(y_pred, y_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
y_bool = (y_pred >= 0.5).float()
accuracy = (y_data == y_bool).float().sum() / len(y_data) * 100
print(f'Epoch : {epoch:4d}/{epochs} Loss : {loss : .6f} Accuracy : {accuracy : .2f}')
- 만들어진 모델을 학습을 시켜주면 정확한 AC를 출력하는걸 확인할 수 있습니다