728x90
반응형
*해당 글은 학습을 목적으로 위의 포스팅 내용 중 일부 내용만을 요약하여 작성한 포스팅입니다.
상세한 내용 및 전체 내용 확인은 위의 링크에서 확인하실 수 있습니다.
합성곱 신경망
- 이미지 처리에 탁월한 성능을 보이는 신경망
- 합성곱층과 풀링층으로 구성된다.
- 기존의 DNN은 반드시 데이터를 1차원 데이터로 Flatten 시켜야 했다.
- 하지만 이는 이미지의 공간적인 구조 정보의 유실을 만들었고, 학습을 불안정하게 만들었다.
- 그래서 이미지의 공간적인 구조 정보를 보존하면서 학습을 할 수 있는 방법이 필요해졌고, 이를 위해 CNN이 등장했다.
채널 (Channel)
- 이미지는 (높이, 너비, 채널)로 이루어진 3차원 텐서이다.
- 높이는 세로, 너비는 가로 방향의 픽셀 수이고, 채널은 색 성분을 의미한다.
- 흑백 이미지의 채널 수는 1, 컬러 이미지의 채널 수는 3이다.
- 각 픽셀은 0~255 사이의 값을 가진다.
- 채널은 때로는 깊이라고도 한다.
합성곱 연산 (Convolution operation)
- 이미지의 특징을 추출하는 과정
- 커널 또는 필터를 활용해 이미지를 훑으면서 각 이미지와 커널의 원소의 값을 보두 더한 값을 출력으로 한다.
- 해당 과청을 거쳐 나온 결과를 특성 맵이라고 한다.
- 특성 맵은 커널의 크기와 스트라이드에 따라 달라질 수 있는데, 패딩을 하면 입력의 크기와 동일하게 유지할 수도 있다.
- 커널을 활용해 가중치를 줄 수 있고, 별도로 편향을 추가해 특성맵의 모든 원소에 특정 값을 더할 수도 있다.
*다수의 채널을 가질 경우 (3차원 텐서의 경우)에는 각 채널을 채널간 합성곱 연산을 실시하여 모두 더한다.
풀링층
- 합성곱층 다음에 추가하여 특성 맵을 다운샘플링하여 특성 맵의 크기를 줄인다.
- 일반적으로 최대 풀링과 평균 풀링이 사용된다.
- 풀링 연산에서도 커널과 스트라이드의 개념을 가진다.
- 특성 맵의 크기를 줄임으로써 특성 맵의 가중치의 개수를 줄이는 역할을 수행한다.
CNN_MNIST
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import torch.nn.init
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 랜덤 시드 고정
torch.manual_seed(777)
# GPU 사용 가능일 경우 랜덤 시드 고정
if device == 'cuda':
torch.cuda.manual_seed_all(777)
mnist_train = dsets.MNIST(root='MNIST_data/', # 다운로드 경로 지정
train=True, # True를 지정하면 훈련 데이터로 다운로드
transform=transforms.ToTensor(), # 텐서로 변환
download=True)
mnist_test = dsets.MNIST(root='MNIST_data/', # 다운로드 경로 지정
train=False, # False를 지정하면 테스트 데이터로 다운로드
transform=transforms.ToTensor(), # 텐서로 변환
download=True)
data_loader = torch.utils.data.DataLoader(dataset=mnist_train,
batch_size=128,
shuffle=True,
drop_last=True)
#모델
class CNNModel(nn.Module) :
def __init__(self, input_size, output_size) :
super().__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size = 3, stride = 1, padding = 1) #순서대로 in_channel, out_channel 28*28 => 28 (패딩으로 양쪽에 2 추가해서.)
self.pool1 = nn.MaxPool2d(kernel_size = 2, stride = 2) #28 -> 14 오버랩 풀링은 귀찮으니 패스
self.conv2 = nn.Conv2d(32, 64, kernel_size = 3, stride = 1, padding = 1) #14 -> 14
self.pool2 = nn.MaxPool2d(kernel_size = 2, stride = 2) #14 -> 7
self.conv3 = nn.Conv2d(64, 128, kernel_size = 3, stride = 1, padding = 1) #7 -> 7
self.pool3 = nn.MaxPool2d(kernel_size = 2, stride = 2) #7 -> 3
self.linear1 = nn.Linear(3*3*128, 256, bias = True)
self.linear2 = nn.Linear(256, 128, bias = True)
self.linear3 = nn.Linear(128, output_size, bias=True)
def forward(self, x) :
output = self.conv1(x)
output = self.pool1(output)
output = self.conv2(output)
output = F.relu(output)
output = self.pool2(output)
output = self.conv3(output)
output = F.relu(output)
output = self.pool3(output)
output = output.view(output.size(0), -1) #flatten (128,128,3,3) => (128, 1152)
output = self.linear1(output)
output = F.relu(output)
ourpur = nn.Dropout(0.5)
output = self.linear2(output)
output = F.relu(output)
ourpur = nn.Dropout(0.5)
output = self.linear3(output)
output = F.softmax(output)
return output
model = CNNModel(28*28, 10).to(device)
criterion = nn.CrossEntropyLoss().to(device) # 비용 함수에 소프트맥스 함수 포함되어져 있음.
optimizer = optim.Adam(model.parameters(), lr=0.001)
n_epoch = 20
total_batch = len(data_loader)
for epoch in range(n_epoch):
avg_cost = 0
for X, Y in data_loader: # 미니 배치 단위로 꺼내온다. X는 미니 배치, Y느 ㄴ레이블.
# image is already size of (28x28), no reshape
# label is not one-hot encoded
X = X.to(device)
Y = Y.to(device)
hypothesis = model(X)
cost = criterion(hypothesis, Y)
optimizer.zero_grad()
cost.backward()
optimizer.step()
avg_cost += cost / total_batch
print('[Epoch: {:>4}] cost = {:>.9}'.format(epoch + 1, avg_cost))
# 학습을 진행하지 않을 것이므로 torch.no_grad()
with torch.no_grad():
X_test = mnist_test.test_data.view(len(mnist_test), 1, 28, 28).float().to(device)
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('Accuracy:', accuracy.item())
728x90
반응형
'IT 도서 > Pytorch로 시작하는 딥 러닝 입문' 카테고리의 다른 글
08. 단어의 표현 방법 (0) | 2021.03.02 |
---|---|
07. 자연어 처리의 전처리 (0) | 2021.03.02 |
05. 인공 신경망 (Artificial Neural Network) (0) | 2021.03.02 |
04. 소프트맥스 회귀 (Softmax Regression) (0) | 2021.03.01 |
03. 로지스틱 회귀 (Logistic Regression) (0) | 2021.03.01 |