입력층 : 입력층의 뉴런수는 입력데이터 피쳐수와 동일
은닉층 : 은닉층의 뉴런수와 층수는 모델의 복잡성과 성능에 영향
출력층 : 출력층의 뉴런 수는 예측하려는 클래스 수 또는 회귀문제 출력차원과 동일
동작 방식
순전파 (Forward Propagation)
각 뉴런은 입력 값에 가중치(weight)를 곱하고, 바이어스(bias)를 더한 후 활성화 함수(activation function)를 통해 출력 값을 결정함
손실계산
예측값과 실제 값의 차이를 손실 함수로 계산함
역전파 (Backpropagation)
손실 함수의 기울기를 출력층에서 입력층 방향으로 계산하고, 이를 바탕으로 가중치를 업데이트 함
필요한 라이브러리 임포트
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
데이터 셋 로드 및 전처리
# 데이터셋 전처리
# 입력데이터를 정규화해주는 과정임
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# MNIST 데이터셋 로드
# 학습 dataset
# trainset: shuffle을 이용해 섞어줌
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
ANN 모델의 정의
# nnModule은 모든 신경망 모듈의 기본 클래스를 말함
# nn.Linear은 선형 변환을 적용하는 완전 연결 레이어를 정의함
# relu 함수 (입력 값이 조건에 걸리는 지 여부에 따라 출력하는 값을 달리하는 함수)
# view : 텐서의 크기를 변경함 (입력 이미지를 특정 벡터로 변환)
class SimpleANN(nn.Module):
# 레이어 정의에 해당
def __init__(self):
super(SimpleANN, self).__init__()
self.fc1 = nn.Linear(28 * 28, 128) # 입력층에서 은닉층으로
self.fc2 = nn.Linear(128, 64) # 은닉층에서 은닉층으로
self.fc3 = nn.Linear(64, 10) # 은닉층에서 출력층으로
# 자동적으로 레이어 간의 연결관계를 설정
def forward(self, x):
# 차원 변경해주는 view함수
# 배치의 차원은 알아서 정의해줌
# -1이란 2차원 데이터를 기준으로 변환할 데이터를 알아서 결정하라는 의미 (자동으로 주어진 값에 따라 차원을 결정함)
x = x.view(-1, 28 * 28) # 입력 이미지를 1차원 벡터로 변환
# 연결관계 명시
# 선형 -> 비선형 활성화 함수
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
# 로짓
x = self.fc3(x)
return x
모델 학습
다중 클래스 분류 문제에서 주로 사용되는 손실 함수,
예측 값과 실제 값 사이의 교차 엔트로피 손실을 계산함: nn.CrossEntropyLoss
optim.SGD : 확률적 경사 하강법 최적화 알고리즘을 정의함
기울기는 초기화가 진행되며 가중치 자체는 초기화된 기울기를 기반으로 업데이트 되는 것임
# 모델 초기화
model = SimpleANN()
# 손실 함수와 최적화 알고리즘 정의
# 분류모델에서 손실함수 계산 : CrossEntropy
# 실제로 어떻게 다르냐를 측정
criterion = nn.CrossEntropyLoss()
# 가중치를 업데이트할 때 사용
# 경사하강법 (SGD 사용, lr은 모멘텀으로 지역최적값에 갇치지 않게 해줌)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
# 모델 학습
for epoch in range(10): # 10 에포크 동안 학습
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
# 기울기 초기화 (이전 배치에서 계산된 기울기를 지워주는 것일 뿐, 모델의 가중치 자체는 업데이트되는 것임)
optimizer.zero_grad()
# 순전파 + 역전파 + 최적화
outputs = model(inputs)
loss = criterion(outputs, labels)
# 역전파를 통해 기울기를 계산
loss.backward()
# 계산된 기울기를 바탕으로 가중치를 업데이트함
optimizer.step()
# 손실 출력
running_loss += loss.item()
if i % 100 == 99: # 매 100 미니배치마다 출력
print(f'[Epoch {epoch + 1}, Batch {i + 1}] loss: {running_loss / 100:.3f}')
running_loss = 0.0
print('Finished Training')
모델 평가
correct = 0
total = 0
# 평가 단계에서는 기울기를 계산할 필요가 없으므로, 이를 비활성
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = model(images)
# 텐서의 최대 값을 찾음
# 지정한 차원(1)에서 (위에서 데이터가 2차원이기 때문에 1차원까지의 최댓값이 유의미하게 사용되겠음)
예측한 값들 가운데 가장 높은 값을 가지는 클래스의 인덱스를 반환함 (prediced에대가)
_, predicted = torch.max(outputs.data, 1)
# 배치 크기를 반환함
total += labels.size(0)
# 예측 값과 실제 값이 일치하는 샘플의 수를 계산함
correct += (predicted == labels).sum().item()
print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')
torch.max(outputs.data,1) 에 대한 이해
outputs = tensor([[0.1, 0.3, 0.6], # 첫 번째 샘플에 대한 예측
[0.2, 0.5, 0.3]]) # 두 번째 샘플에 대한 예측
torch.max(outputs,1)
# [2,1]
이미지에 특화 (2차원 데이터 분석)
출력 레이어로 ANN 사용해야 함
CNN은 ANN보다 함께 보는 접근이기 때문에 특징맵을 잘 뽑아낼 수 있다는 것이 특징임
CNN - Pool - CNN으로 확장할 수 있다는 장점이 있음
Pool링 레이어의 크기를 줄이고 늘리는 역할은 padding이 함
풀링 레이어의 필요성과 종류
이해
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(3, 32, 3, padding=1) # 입력 채널 3, 출력 채널 32, 커널 크기 3x3
self.pool = nn.MaxPool2d(2, 2) # 풀링 크기 2x2
# 필터 차원으로 동작하기 때문에 입력 차원과 출력차원은 독립적으로 동작 가능함
# 컬러여서 채널의 차원이 3
self.conv2 = nn.Conv2d(32, 64, 3, padding=1) # 입력 채널 32, 출력 채널 64, 커널 크기 3x3
self.fc1 = nn.Linear(64 * 8 * 8, 512) # 완전 연결 층
self.fc2 = nn.Linear(512, 10) # 출력 층 (10개의 클래스)
def forward(self, x):
# forward 함수 내에는 활성화 함수가 항상 존재해야 함
x = self.pool(torch.relu(self.conv1(x)))
x = self.pool(torch.relu(self.conv2(x)))
# For ANN
x = x.view(-1, 64 * 8 * 8) # 플래튼
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
모델학습
# 모델 초기화
model = SimpleCNN()
# 손실 함수와 최적화 알고리즘 정의
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
# 모델 학습
for epoch in range(10): # 10 에포크 동안 학습
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
# 기울기 초기화
optimizer.zero_grad()
# 순전파 + 역전파 + 최적화
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# 손실 출력
running_loss += loss.item()
if i % 100 == 99: # 매 100 미니배치마다 출력
print(f'[Epoch {epoch + 1}, Batch {i + 1}] loss: {running_loss / 100:.3f}')
running_loss = 0.0
print('Finished Training')
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')
LSTM
GRU
이해
BackPropagation은 함수를 계산할 때 가중치들을 조절해서 함수가 최소가 되도록 조절하는 역할을 함
단 RNN에서는 이 가중치들을 조절하는 LSTM, GRU가 존재하는 것임
시계열 데이터 처리
pytorch에서 tensor란 기울기를 계산하는 것임
은닉 상태는 이전 정보를 바탕으로 만들어지는 것을 말함
Attention 메커니즘은 시퀀스 데이터에서 중요한 부분에 더 많은 가중치를 할당하여 정보를 효율적으로 처리하는 기법
주로 자연어 처리와 시계열 데이터에서 사용되며, 기계 번역, 요약, 질의응답 시스템 등 다양한 분야에서 뛰어난 성능을 발휘함
중요한 부분에 가중치를 할당할 수 있는 메커니즘
그렇다면 이 중요한 정도는 어떻게 평가하느냐? -> 답과 질문을 갖고 평가함!
질문 : query
답 : key
최종 요약 : value
query와 key/value 간의 유사도를 판단함 (dot product)
Self-Attention
Self-Attention은 시퀀스 내의 각 요소가 서로를 참조하는 매커니즘임
입력 시퀀스의 모든 요소가 Query, Key, Value로 사용됨
각 요소가 시퀀스 내 다른 요소들과의 관계를 학습할 수 있음
Multi-Head Attention
Multi-Head Attention은 여러 개의 Self-Attention을 병렬로 수행하는 매커니즘임
각 헤드는 서로 다른 부분의 정보를 학습하며, 이를 통해 모델이 다양한 관점에서 데이터를 처리할 수 있음
중요도를 가중치로 바꾸는 것은 softmax 함수가 해주겠음
Word2Vec
CBOW
Skip - Gram
GloVe
학습한 단어는 벡터로 변환됨
시퀀스 모델
구조
인코더 : 셀프 어텐션 -> 피드 포워드 신경망
디코더 : 셀프 어텐션 -> 인코더, 디코더 어텐션 -> 피드 포워드 신경망
BERT
사전 학습(Pre-training)
파인튜닝(Fine-tuning)
비전 모델에서 성능을 대폭 올린 모델 (CNN에 결합하여 성능을 향상시킴)
DNN 기반 이미지 분류 모델
동작 원리
이미지 세그멘테이션 기법과 응용
주요 세그멘테이션 모델
그렇다면 오토인코더란?
입력데이터를 압축하고, 이를 다시 복원하는 과정을 통해 데이터를 효율적으로 표현하는 비지도 학습 모델임 -> 주로 자원 축소, 잡음 제거, 생성 모델 등 다양하게 활용됨
생성자
판별자
경쟁과정
다만 실제로 적용하기에는 조율해야 할 사항이 많아 다소 까다로운 모델이라고 할 수 있겠음
Recontruction Loss
원래 데이터와 복원된 데이터 간의 차이를 최소화하는 손실 함수
쿨백 라이블러 발산
인코더가 학습한 잠재 분포와 정규 분포 간의 차이를 최소화하는 손실 함수
CNN을 GPU로 학습시키면 빠른데 CPU로 학습시키면 느림 왜그렇지??
torch의 가장 큰 값을 받아오는 이유는 무엇인가?
모델의 성능을 결정하는 것은 배치 사이즈인가?
모델생성에서 절대적이라는 것은 없음