torchvision.datasets.ImageFolder()
메소드 이용Receptive Field가 이미지를 돌면서 feature를 뽑을 때 이동하는 칸 수
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias)
conv = torch.nn.Conv2d(1,1,11,stride=4, padding=0)
inputs = torch.Tensor(1,1,227,227)
out = conv(inputs)
print(f'Input Size: {inputs.shape}, Output Size: {out.shape}')
torch.nn.MaxPool2d(kernel_size, stride, padding, dilation, return_indices, ceil_mode)
import numpy as np
import matplotlib.pyplot as plt
import torch
from torchvision import transforms, datasets
if torch.cuda.is_available():
device = torch.device('cuda')
else:
device = torch.device('cpu')
batch_size = 32
epochs = 10
# transforms 함수 이용 시 augmentation 쉽게 적용
train_dataset = datasets.CIFAR10(root='data/CIFAR_10',
train=True, download=True,
transform = transforms.Compose([ # torch.Compose() 는 불러오는 이미지 데이터에 전처리 및 Augmentation을 다양하게 적용할 때 이용
transforms.RandomHorizontalFlip(), # 해당 이미지를 50% 확률로 좌우 반전
transforms.ToTensor(), # 데이터를 tensor 형태로 변환 및 0~1로 정규화
transforms.Normalize((0.5,0.5,0.5), (0.5,0.5,0.5)) # red, green, blue 순으로 평균, 표준편차를 0.5씩 적용
]))
test_dataset = datasets.CIFAR10(root='data/CIFAR_10',
train=False, download=True,
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.5,0.5,0.5), (0.5,0.5,0.5))
]))
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
batch_size=batch_size, shuffle=False)
class CNN(torch.nn.Module): # torch.nn.Module: PyTorch Module 내에 딥러닝 모델 관련 함수 포함하는 클래스 상속(그대로 사용)
def __init__(self): # 인스턴스 생성 시 지니는 성질 정의
super(CNN, self).__init__() # torch.nn.Module 내에 있는 메소드 상속받아 이용
self.conv1 = nn.Conv2d( # Convolution 연산 수행하는 filter 정의
in_channels = 3, # 채널 수를 이미지의 채널 수와 동일하게 맞춰야 함(red, green, blue)
out_channels = 8, # filter 개수 설정
kernel_size = 3, # filter size 설정
padding = 1 # padding size 결정
)
self.conv2 = nn.Conv2d(
in_channels = 8, # 이전 feature map의 채널 수와 동일하게 채널 수 맞춤
out_channels = 16,
kernel_size = 3, padding = 1
)
self.pool = nn.MaxPool2d( # Max Pooling 사용
kernel_size = 2, # pooling filter size 결정
stride = 2
)
self.fc1 = nn.Linear(8*8*16, 64) # 8*8의 2차원 데이터 16개가 겹쳐 있는 형태로 존재하는 데이터를 input으로
self.fc2 = nn.Linear(64, 32)
self.fc3 = nn.Linear(32, 10)
def forward(self, x):
x = self.conv1(x)
x = torch.nn.functional.relu(x)
x = self.pool(x)
x = self.conv2(x)
x = torch.nn.functional.relu(x)
x = self.pool(x)
x = x.view(-1, 8*8*16) # fully-connected layer에 input으로 넣기 위해 shape 변환
x = self.fc1(x)
x = torch.nn.functional.relu(x)
x = self.fc2(x)
x = torch.nn.functional.relu(x)
x = self.fc3(x)
return x
model = CNN().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = torch.nn.CrossEntrophyLoss() # softmax 내포
def train(model, train_loader, optimizer, log_interval):
model.train()
for batch_idx, (image, label) in enumerate(train_loader):
image = image.to(device)
label = label.to(device)
optimizer.zero_grad()
output = model(image)
loss = criterion(output, label)
loss.backward()
optimizer.step()
if batch_idx % log_interval == 0:
print(f'Train Epoch: {epoch}\tTrain Loss: {loss.item()}')
def evaluate(model, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for image, label in test_loader:
image = image.to(device)
label = label.to(device)
output = model(image)
test_loss += criterion(output, label).item()
prediction = output.max(1, keepdim=True)[1]
correct += prediction.eq(label.view_as(prediction)).sum().item()
test_loss /= len(test_loader.dataset)
test_accuracy = 100 * correct/len(test_loader.dataset)
return test_loss, test_accuracy
for epoch in range(1, epochs+1):
train(model, train_loader, optimizer, log_interval=200)
test_loss, test_accuracy = evaluate(model, test_loader)
print(f'\nEpoch: {epoch},\t Test Loss: {test_loss},\t Test Accuracy: {test_accuracy}')
# 라이브러리 가져오기
import torch
import torch.nn as nn
from torchvision import datasets, transforms
# GPU 설정 및 random seed 고정
device = 'cuda' if torch.cuda.is_available() else 'cpu'
torch.manual_seed(777)
if device == 'cuda':
torch.cuda.manual_seed_all(777)
# parameters
learning_rate = 0.001
traning_epochs = 15
batch_size = 100
# MNIST dataset
mnist_train = datasets.MNIST(root='MNIST_data/',
train=True, download=True,
transform=transforms.ToTensor())
# root: 데이터 저장 위치, train data 여부, transform=변환
mnist_test = datasets.MNIST(root='MNIST_data/',
train=False, download=True,
transform=transforms.ToTensor())
data_loader = torch.utils.DataLoader(DataLoader=mnist_train, batch_size=batch_size,
shuffle=True, drop_last=True) # 불러오기
# Modeling
class CNN(nn.module):
def __init__(self):
super(CNN, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(1, 32, 3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.layer2 = nn.Sequential(
nn.Conv2d(32, 64, 3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.fc = nn.Linear(7*7*64, 10, bias=True)
torch.nn.init.xavier_uniform_(self.fc.weight)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(x)
out = out.view(out.size(0), -1) # batch_size만 고정하고 나머지는 flatten
out = self.fc(x)
return out
model = CNN.to(device)
criterion = nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr = learning_rate)
# Training
total_batch = len(data_loader)
for epoch in range(training_epochs):
avg_cost = 0
for X,Y in data_loader:
X = X.to(device)
Y = Y.to(device)
optimizer.zero_grad()
hypothesis = model(X)
cost = criterion(hypothesis, Y)
cost.backward()
optimizer.step()
avg_cost += cost/total_batch
print(f'Epoch: {epoch+1}, Cost = {avg_cost}')
# Evaluate
with torch.no_grad():
X_test = mnist_test.test_data.view(len(mnist_test), 1, 28, 28).float().to(device)
# 한번에 집어넣기 위해 펼침(flatten)
Y_test = mnist_test.test_labels.to(device)
prediction = model(X_test)
correct_prediction = torch.argmax(prediction, 1) == Y_test
accuracy = correct_prediction.float().mean()
print(f'Accuracy: {accuracy.item()}')
!pip install visdom
python -m visdom.server
import visdom
vis = visdom.Visdom()
# text
vis.text('Hello, world!', env='main')
# image
vis.image(torch.randn(3,200,200), env='main')
# images
vis.images(torch.Tensor(3,3,28,28), env='main')
# Line Plot
X_data = torch.randn(5)
Y_data = torch.randn(5)
plt = vis.line(Y=Y_data, X=X_data,
opts = dict(title='Test', showlegend=True, legend=['1번']))
# Update Line Plot
Y_append = torch.randn(1)
X_append = torch.Tensor([6])
vis.line(Y=Y_append, X=X_append, win=plt, update='append')
vis.close(env='main')
참고
파이썬 딥러닝 파이토치 (이경택, 방성수, 안상준)
모두를 위한 딥러닝 시즌 2 Lab 10-1, 10-2, 10-3, 10-4-1