합성곱 신경망(Convolutional neural network)
이미지와 같은 2차원 데이터의 특징을 효과적으로 추출
importimport torch # 핵심 라이브러리
import torch.nn as nn # neural networks 신경망 구성
import torch.optim as optim # 최적화(함수를 최소 또는 최대로 맞추는 변수를 찾는 것)
import torchvision # 이미지 처리
import torchvision.transforms as transforms # 이미지 처리 전처리
transform = transforms.Compose([
#
transforms.ToTensor(),
# 이미지를 Tensor(파이토치 자료구조)로 전환
transforms.Normalize((0.5,), (0.5,))
# 이미지 정규화(평균, 표준편차)
])
# MNIST 데이터셋 로드
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
# 경로 # train(학습용) 데이터셋 여부 # 다운로드 여부 #transform 전달-전처리한 상태로
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
# 토치.유틸.데이터 기능.데이터 로더(데이터 셋, batch_size(쪼갠단위로 학습), suffle(섞어서 쪼갬))
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
for (X_train, Y_train) in trainloader:
print(f"X_train: {X_train.size()} type: {X_train.type()}")
print(f"Y_train: {Y_train.size()} type: {Y_train.type()}")
break
# batch_size, channel, width, height
# X_train: torch.Size([64, 1, 28, 28]) type: torch.FloatTensor
# Y_train: torch.Size([64]) type: torch.LongTensor
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(1, 32, 3, padding=1)
# 입력 채널(1: 흑백, 3: RGB), 출력 채널(입력채널과 별도), 커널(필터) 크기 3x3
self.pool = nn.MaxPool2d(2, 2)
# 풀링 크기 2x2 # kernel, stride
# Pooling 크기가 (2, 2) 라면 출력 데이터 크기는 입력 데이터의 행과 열 크기를 2로 나눈 몫
self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
# 입력 채널(이전 출력 채널과 동일) 32, 출력 채널 64, 커널 크기 3x3
self.fc1 = nn.Linear(64 * 7 * 7, 512) # 완전 연결 층
self.fc2 = nn.Linear(512, 10) # 출력 층 (10개의 클래스)
# ANN 레이어 여러개 사용 가능
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x)))
x = self.pool(torch.relu(self.conv2(x)))
x = x.view(-1, 64 * 7 * 7) # 플래튼 # ANN에 전달하기 위해 변환
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)
# 최적화, lr- 학습률(적당히 작은값), momentum - 치후 설명
# 모델 학습
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}%')
# Accuracy of the network on the 10000 test images: 99.27%
순환 신경망(Recurrent Neural Network)
시계열 데이터나 순차적인 데이터를 처리 = 시퀀스 데이터
다른 모델: [내 이름은] -> 분석
[코난] -> 분석
[탐정이죠] -> 분석
RNN : [내 이름은] -> 분석
[(내 이름은) 코난] -> 분석
[(내 이름은 코난)탐정이죠] - > 분석
# () = 은닉 데이터
# 모든 시점의 데이터에서 분석
# 역전파 - 모든 시점의 가중치를 업데이트
importimport torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
# 시각화 도구
# Sine 함수 데이터 생성
def create_sine_wave_data(seq_length, num_samples):
X = []
y = []
for _ in range(num_samples):
start = np.random.rand()
x = np.linspace(start, start + 2 * np.pi, seq_length)
X.append(np.sin(x))
y.append(np.sin(x + 0.1))
return np.array(X), np.array(y)
seq_length = 50
num_samples = 1000
X, y = create_sine_wave_data(seq_length, num_samples)
# 데이터셋을 PyTorch 텐서로 변환 / tensor = 기울기를 계산 할 수 있는 데이터 형태
X = torch.tensor(X, dtype=torch.float32).unsqueeze(-1)
y = torch.tensor(y, dtype=torch.float32).unsqueeze(-1)
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleRNN, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size) # 출력 레이어이기 때문에 output_size를 정해줌
def forward(self, x):
h0 = torch.zeros(1, x.size(0), hidden_size) # 초기 은닉 상태/제일 처음의 값은 은닉 상태가 없기 떄문에 지정해중
out, _ = self.rnn(x, h0)
out = self.fc(out) # 전체
# out = self.fc(out[:, -1, :]) # 마지막 시간 단계의 출력
return out
input_size = 1
hidden_size = 32
output_size = 1
model = SimpleRNN(input_size, hidden_size, output_size)
class SimpleLSTM(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleLSTM, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(1, x.size(0), hidden_size) # 초기 은닉 상태
c0 = torch.zeros(1, x.size(0), hidden_size) # 초기 셀 상태
# RNN 모델 에 초기 셀 상태 추가
out, _ = self.lstm(x, (h0, c0)) # 셀 상태 추가
out = self.fc(out[:, -1, :]) # 마지막 시간 단계의 출력
return out
model = SimpleLSTM(input_size, hidden_size, output_size)
# 손실 함수와 최적화 알고리즘 정의
criterion = nn.MSELoss()
# 평균 제곱 오차 손실함수
optimizer = optim.Adam(model.parameters(), lr=0.01)
# ADAM 최적화 방식
# 모델 학습
num_epochs = 100
for epoch in range(num_epochs):
outputs = model(X)
optimizer.zero_grad()
# 이전 단계에서 계산된 기울기 초기화
loss = criterion(outputs, y)
loss.backward()
# 역전파를 통한 기울기 계산
optimizer.step()
# 가중치 업데이트
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
print('Finished Training')
# 모델 평가
model.eval()
with torch.no_grad():
predicted = model(X).detach().numpy()
# 시각화
plt.figure(figsize=(10, 5))
plt.plot(y.numpy().flatten()[:100], label='True')
plt.plot(predicted.flatten()[:100], label='Predicted')
plt.legend()
plt.show()