728x90
들어가며
포스팅된 글은 아래에 첨부된 논문과 유튜브 영상을 바탕으로 공부를 한 내용입니다.
이외에도 구글링을 통해 다양한 글들을 참고하며 공부한 내용을 포스팅 한 것 입니다.
또한 본 프로젝트는 클론코딩을 기반으로 공부한 것 입니다.
더보기
논문 제목: Image Style Transfer Using Convolutional Neural Networks (CVPR 2016)
논문 링크: https://rn-unison.github.io/articulos/style_transfer.pdf
프로젝트 과정
실습에 필요한 라이브러리 불러오기 및 환경 설정¶
In [1]:
# 필요한 PyTorch 라이브러리 불러오기
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision.transforms as transforms
import torchvision.models as models
import PIL
import matplotlib.pyplot as plt
import copy
In [2]:
# GPU 장치 사용 설정
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
In [3]:
# 이미지를 불러와 다운받아 텐서(Tensor) 객체로 변환하는 함수
def image_loader(img_path, imsize):
loader = transforms.Compose([
transforms.Resize(imsize), # 이미지의 크기를 변경
transforms.ToTensor() # torch.Tensor 형식으로 변경 [0, 255] → [0, 1]
])
image = PIL.Image.open(img_path)
# 네트워크 입력에 들어갈 이미지에 배치 목적의 차원(dimension) 추가
image = loader(image).unsqueeze(0)
return image.to(device, torch.float) # GPU로 올리기
# torch.Tensor 형태의 이미지를 화면에 출력하는 함수
def imshow(tensor):
# matplotlib는 CPU 기반이므로 CPU로 옮기기
image = tensor.cpu().clone()
# torch.Tensor에서 사용되는 배치 목적의 차원(dimension) 제거
image = image.squeeze(0)
# PIL 객체로 변경
image = transforms.ToPILImage()(image)
# 이미지를 화면에 출력(matplotlib는 [0, 1] 사이의 값이라고 해도 정상적으로 처리)
plt.imshow(image)
plt.show()
In [4]:
# 저장소의 소스코드를 다운로드하여 실습용 이미지 준비하기
!git clone https://github.com/ndb796/Deep-Learning-Paper-Review-and-Practice
%cd Deep-Learning-Paper-Review-and-Practice
C:\Users\Jung_dayoung\git_upload\HYPER\Neural_Style_Transfer\Deep-Learning-Paper-Review-and-Practice
Cloning into 'Deep-Learning-Paper-Review-and-Practice'...
Image Reconstruction 실습하기¶
In [5]:
# 목표 이미지(target image) 불러오기
img_path = './code_practices/images/cat.jpg'
target_image = image_loader(img_path, (512, 512))
imshow(target_image)
In [6]:
# 동일한 크기의 노이즈 이미지 준비하기
noise = torch.empty_like(target_image).uniform_(0, 1).to(device)
imshow(noise)
In [7]:
loss = nn.MSELoss() # 손실(loss) 함수 설정
iters = 100 # 반복(iteration) 횟수 설정
lr = 1e4
print("[ Start ]")
imshow(noise)
for i in range(iters):
# required_grad 속성의 값을 True로 설정하여 해당 torch.Tensor의 연산을 추적
noise.requires_grad = True
# 손실 함수에 대하여 미분하여 기울기(gradient) 계산
output = loss(noise, target_image)
output.backward()
# 계산된 기울기(gradient)를 이용하여 손실 함수가 감소하는 방향으로 업데이트
gradient = lr * noise.grad
# 결과적으로 노이즈(perturbation)의 각 픽셀의 값이 [-eps, eps] 사이의 값이 되도록 자르기
noise = torch.clamp(noise - gradient, min=0, max=1).detach_() # 연산을 추적하는 것을 중단하기 위해 detach() 호출
if (i + 1) % 10 == 0:
print(f'[ Step: {i + 1} ]')
print(f'Loss: {output}')
imshow(noise)
[ Start ]
[ Step: 10 ]
Loss: 0.10433844476938248
[ Step: 20 ]
Loss: 0.06232945993542671
[ Step: 30 ]
Loss: 0.03723423555493355
[ Step: 40 ]
Loss: 0.02224290370941162
[ Step: 50 ]
Loss: 0.01328741479665041
[ Step: 60 ]
Loss: 0.007937606424093246
[ Step: 70 ]
Loss: 0.004741749260574579
[ Step: 80 ]
Loss: 0.002832615515217185
[ Step: 90 ]
Loss: 0.001692141406238079
[ Step: 100 ]
Loss: 0.001010847627185285
다음 프로젝트 과정