From 83f95dae398c49fa00e052cb6fcdc3d201cf715f Mon Sep 17 00:00:00 2001 From: Keon Date: Wed, 30 May 2018 00:50:09 -0400 Subject: [PATCH] compile python files --- .../torchvision-and-torchtext.py | 2 + .../basic-feed-forward.py | 8 + .../01-fashion-mnist.py | 120 +++++++++++++ .../02-neural-network.py | 146 +++++++++++++++ .../03-overfitting-and-regularization.py | 137 ++++++++++++++ 05-CNN-For-Image-Classification/01-cnn.py | 126 +++++++++++++ .../02-cifar-cnn.py | 168 ++++++++++++++++++ 06-Autoencoder/01-autoencoder.py | 162 +++++++++++++++++ .../01-text-classification.py | 154 ++++++++++++++++ .../02-sequence-to-sequence.py | 113 ++++++++++++ 08-Hacking-Deep-Learning/01-fgsm-attack.py | 85 +++++++++ .../02-iterative-target-attack.py | 86 +++++++++ .../01-cartpole-dqn.py | 109 ++++++++++++ .../README.md | 0 README.md | 2 +- 15 files changed, 1417 insertions(+), 1 deletion(-) create mode 100644 02-Getting-Started-With-PyTorch/torchvision-and-torchtext.py create mode 100644 03-Coding-Neural-Networks-In-PyTorch/basic-feed-forward.py create mode 100644 04-Neural-Network-For-Fashion/01-fashion-mnist.py create mode 100644 04-Neural-Network-For-Fashion/02-neural-network.py create mode 100644 04-Neural-Network-For-Fashion/03-overfitting-and-regularization.py create mode 100644 05-CNN-For-Image-Classification/01-cnn.py create mode 100644 05-CNN-For-Image-Classification/02-cifar-cnn.py create mode 100644 06-Autoencoder/01-autoencoder.py create mode 100644 07-RNN-For-Sequential-Data/01-text-classification.py create mode 100644 07-RNN-For-Sequential-Data/02-sequence-to-sequence.py create mode 100644 08-Hacking-Deep-Learning/01-fgsm-attack.py create mode 100644 08-Hacking-Deep-Learning/02-iterative-target-attack.py create mode 100644 10-DQN-Learns-From-Environment/01-cartpole-dqn.py rename {11-A2C-Self-Driving => 11-Self-Driving-Car}/README.md (100%) diff --git a/02-Getting-Started-With-PyTorch/torchvision-and-torchtext.py b/02-Getting-Started-With-PyTorch/torchvision-and-torchtext.py new file mode 100644 index 0000000..e56ad26 --- /dev/null +++ b/02-Getting-Started-With-PyTorch/torchvision-and-torchtext.py @@ -0,0 +1,2 @@ + +# coding: utf-8 diff --git a/03-Coding-Neural-Networks-In-PyTorch/basic-feed-forward.py b/03-Coding-Neural-Networks-In-PyTorch/basic-feed-forward.py new file mode 100644 index 0000000..3da543e --- /dev/null +++ b/03-Coding-Neural-Networks-In-PyTorch/basic-feed-forward.py @@ -0,0 +1,8 @@ + +# coding: utf-8 + +import torch +import numpy +from sklearn.datasets import make_blobs +import matplotlib.pyplot as plot + diff --git a/04-Neural-Network-For-Fashion/01-fashion-mnist.py b/04-Neural-Network-For-Fashion/01-fashion-mnist.py new file mode 100644 index 0000000..4212b08 --- /dev/null +++ b/04-Neural-Network-For-Fashion/01-fashion-mnist.py @@ -0,0 +1,120 @@ + +# coding: utf-8 + +# # 4.1 Fashion MNIST 데이터셋 알아보기 + +get_ipython().run_line_magic('matplotlib', 'inline') +from torchvision import datasets, transforms, utils +from torch.utils import data + +import matplotlib.pyplot as plt +import numpy as np + + +# ## [개념] Fashion MNIST 데이터셋 설명 + +transform = transforms.Compose([ + transforms.ToTensor() +]) + + +trainset = datasets.FashionMNIST( + root = './.data/', + train = True, + download = True, + transform = transform +) +testset = datasets.FashionMNIST( + root = './.data/', + train = False, + download = True, + transform = transform +) + + +batch_size = 16 + +train_loader = data.DataLoader( + dataset = trainset, + batch_size = batch_size +) +test_loader = data.DataLoader( + dataset = testset, + batch_size = batch_size +) + + +dataiter = iter(train_loader) +images, labels = next(dataiter) + + +# ## 멀리서 살펴보기 +# 누군가 "숲을 먼저 보고 나무를 보라"고 했습니다. 데이터셋을 먼저 전체적으로 살펴보며 어떤 느낌인지 알아보겠습니다. + +img = utils.make_grid(images, padding=0) +npimg = img.numpy() +plt.figure(figsize=(10, 7)) +plt.imshow(np.transpose(npimg, (1,2,0))) +plt.show() + + +CLASSES = { + 0: 'T-shirt/top', + 1: 'Trouser', + 2: 'Pullover', + 3: 'Dress', + 4: 'Coat', + 5: 'Sandal', + 6: 'Shirt', + 7: 'Sneaker', + 8: 'Bag', + 9: 'Ankle boot' +} + +KR_CLASSES = { + 0: '티셔츠/윗옷', + 1: '바지', + 2: '스웨터', + 3: '드레스', + 4: '코트', + 5: '샌들', + 6: '셔츠', + 7: '운동화', + 8: '가방', + 9: '앵클부츠' +} + +for label in labels: + index = label.item() + print(KR_CLASSES[index]) + + +# ## 가까이서 살펴보기 +# 또 누군가는 "숲만 보지 말고 나무를 보라"고 합니다. 이제 전체적인 느낌을 알았으니 개별적으로 살펴보겠습니다. + +idx = 1 + +item_img = images[idx] +item_npimg = item_img.squeeze().numpy() +plt.title(CLASSES[labels[idx].item()]) +print(item_npimg.shape) +plt.imshow(item_npimg, cmap='gray') +plt.show() + + +# plot one example +print(trainset.train_data.size()) # (60000, 28, 28) +print(trainset.train_labels.size()) # (60000) +plt.imshow(trainset.train_data[1].numpy(), cmap='gray') +plt.title('%i' % trainset.train_labels[1]) +plt.show() + + +img.max() + + +img.min() + + +img + diff --git a/04-Neural-Network-For-Fashion/02-neural-network.py b/04-Neural-Network-For-Fashion/02-neural-network.py new file mode 100644 index 0000000..49a71fe --- /dev/null +++ b/04-Neural-Network-For-Fashion/02-neural-network.py @@ -0,0 +1,146 @@ + +# coding: utf-8 + +# # 4.2 뉴럴넷으로 패션 아이템 구분하기 +# Fashion MNIST 데이터셋과 앞서 배운 인공신경망을 이용하여 패션아이템을 구분해봅니다. + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.nn.functional as F +from torchvision import transforms, datasets + + +torch.manual_seed(42) +USE_CUDA = torch.cuda.is_available() +DEVICE = torch.device("cuda" if USE_CUDA else "cpu") + + +EPOCHS = 20 +BATCH_SIZE = 64 + + +# ## 데이터셋 불러오기 + +transform = transforms.Compose([ + transforms.ToTensor() +]) + + +trainset = datasets.FashionMNIST( + root = './.data/', + train = True, + download = True, + transform = transform +) +testset = datasets.FashionMNIST( + root = './.data/', + train = False, + download = True, + transform = transform +) + +train_loader = torch.utils.data.DataLoader( + dataset = trainset, + batch_size = BATCH_SIZE, + shuffle = True, +) +test_loader = torch.utils.data.DataLoader( + dataset = testset, + batch_size = BATCH_SIZE, + shuffle = True, +) + + +# ## 뉴럴넷으로 Fashion MNIST 학습하기 +# 입력 `x` 는 `[배치크기, 색, 높이, 넓이]`로 이루어져 있습니다. +# `x.size()`를 해보면 `[64, 1, 28, 28]`이라고 표시되는 것을 보실 수 있습니다. +# Fashion MNIST에서 이미지의 크기는 28 x 28, 색은 흑백으로 1 가지 입니다. +# 그러므로 입력 x의 총 특성값 갯수는 28 x 28 x 1, 즉 784개 입니다. +# 우리가 사용할 모델은 3개의 레이어를 가진 뉴럴네트워크 입니다. + +class Net(nn.Module): + def __init__(self): + super(Net, self).__init__() + self.fc1 = nn.Linear(784, 256) + self.fc2 = nn.Linear(256, 128) + self.fc3 = nn.Linear(128, 10) + + def forward(self, x): + x = x.view(-1, 784) + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + x = self.fc3(x) + return x + + +# ## 모델 준비하기 +# `to()` 함수는 모델의 파라미터들을 지정한 곳으로 보내는 역할을 합니다. +# 일반적으로 CPU 1개만 사용할 경우 필요는 없지만, +# GPU를 사용하고자 하는 경우 `to("cuda")`로 지정하여 GPU로 보내야 합니다. +# 지정하지 않을 경우 계속 CPU에 남아 있게 되며 빠른 훈련의 이점을 누리실 수 없습니다. +# 최적화 알고리즘으로 파이토치에 내장되어 있는 `optim.SGD`를 사용하겠습니다. + +model = Net().to(DEVICE) +optimizer = optim.SGD(model.parameters(), lr=0.01) + + +# ## 훈련하기 + +def train(model, train_loader, optimizer, epoch): + model.train() + for batch_idx, (data, target) in enumerate(train_loader): + data, target = data.to(DEVICE), target.to(DEVICE) + optimizer.zero_grad() + output = model(data) + loss = F.cross_entropy(output, target) + loss.backward() + optimizer.step() + + if batch_idx % 200 == 0: + print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( + epoch, batch_idx * len(data), len(train_loader.dataset), + 100. * batch_idx / len(train_loader), loss.item())) + + +# ## 테스트하기 +# 아무리 훈련이 잘 되었다고 해도 실제 데이터를 만났을때 성능이 낮다면 쓸모 없는 모델일 것입니다. +# 우리가 진정 원하는 것은 훈련 데이터에 최적화한 모델이 아니라 모든 데이터에서 높은 성능을 보이는 모델이기 때문입니다. +# 세상에 존재하는 모든 데이터에 최적화 하는 것을 "일반화"라고 부르고 +# 모델이 얼마나 실제 데이터에 적응하는지를 수치로 나타낸 것을 "일반화 오류"(Generalization Error) 라고 합니다. +# 우리가 만든 모델이 얼마나 일반화를 잘 하는지 알아보기 위해, +# 그리고 언제 훈련을 멈추어야 할지 알기 위해 +# 매 이포크가 끝날때 마다 테스트셋으로 모델의 성능을 측정해보겠습니다. + +def test(model, test_loader): + model.eval() + test_loss = 0 + correct = 0 + with torch.no_grad(): + for data, target in test_loader: + data, target = data.to(DEVICE), target.to(DEVICE) + output = model(data) + + # sum up batch loss + test_loss += F.cross_entropy(output, target, + size_average=False).item() + + # get the index of the max log-probability + pred = output.max(1, keepdim=True)[1] + correct += pred.eq(target.view_as(pred)).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, epoch) + test_loss, test_accuracy = test(model, test_loader) + + print('[{}] Test Loss: {:.4f}, Accuracy: {:.2f}%'.format( + epoch, test_loss, test_accuracy)) + diff --git a/04-Neural-Network-For-Fashion/03-overfitting-and-regularization.py b/04-Neural-Network-For-Fashion/03-overfitting-and-regularization.py new file mode 100644 index 0000000..0e3338c --- /dev/null +++ b/04-Neural-Network-For-Fashion/03-overfitting-and-regularization.py @@ -0,0 +1,137 @@ + +# coding: utf-8 + +# # 4.3 오버피팅과 정규화 (Overfitting and Regularization) +# 머신러닝 모델 +# 과적합(Overfitting) + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.nn.functional as F +from torchvision import transforms, datasets + + +torch.manual_seed(42) +USE_CUDA = torch.cuda.is_available() +DEVICE = torch.device("cuda" if USE_CUDA else "cpu") + + +EPOCHS = 50 +BATCH_SIZE = 64 + + +# ## 데이터셋에 노이즈 추가하기 +# ![original.png](./assets/original.png) +# ![horizontalflip.png](./assets/horizontalflip.png) + +train_loader = torch.utils.data.DataLoader( + datasets.MNIST('./.data', + train=True, + download=True, + transform=transforms.Compose([ + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + transforms.Normalize((0.1307,), (0.3081,)) + ])), + batch_size=BATCH_SIZE, shuffle=True) +test_loader = torch.utils.data.DataLoader( + datasets.MNIST('./.data', + train=False, + transform=transforms.Compose([ + transforms.ToTensor(), + transforms.Normalize((0.1307,), (0.3081,)) + ])), + batch_size=BATCH_SIZE, shuffle=True) + + +# ## 뉴럴넷으로 Fashion MNIST 학습하기 +# 입력 `x` 는 `[배치크기, 색, 높이, 넓이]`로 이루어져 있습니다. +# `x.size()`를 해보면 `[64, 1, 28, 28]`이라고 표시되는 것을 보실 수 있습니다. +# Fashion MNIST에서 이미지의 크기는 28 x 28, 색은 흑백으로 1 가지 입니다. +# 그러므로 입력 x의 총 특성값 갯수는 28 x 28 x 1, 즉 784개 입니다. +# 우리가 사용할 모델은 3개의 레이어를 가진 뉴럴네트워크 입니다. + +class Net(nn.Module): + def __init__(self, dropout_p=0.2): + super(Net, self).__init__() + self.fc1 = nn.Linear(784, 256) + self.fc2 = nn.Linear(256, 128) + self.fc3 = nn.Linear(128, 10) + self.dropout_p = dropout_p + + def forward(self, x): + x = x.view(-1, 784) + x = F.relu(self.fc1(x)) + x = F.dropout(x, training=self.training, + p=self.dropout_p) + x = F.relu(self.fc2(x)) + x = F.dropout(x, training=self.training, + p=self.dropout_p) + x = self.fc3(x) + return x + + +# ## 모델 준비하기 +# `to()` 함수는 모델의 파라미터들을 지정한 곳으로 보내는 역할을 합니다. +# 일반적으로 CPU 1개만 사용할 경우 필요는 없지만, +# GPU를 사용하고자 하는 경우 `to("cuda")`로 지정하여 GPU로 보내야 합니다. +# 지정하지 않을 경우 계속 CPU에 남아 있게 되며 빠른 훈련의 이점을 누리실 수 없습니다. +# 최적화 알고리즘으로 파이토치에 내장되어 있는 `optim.SGD`를 사용하겠습니다. + +model = Net(dropout_p=0.2).to(DEVICE) +optimizer = optim.SGD(model.parameters(), lr=0.01) + + +# ## 훈련하기 + +def train(model, train_loader, optimizer): + model.train() + for data, target in enumerate(train_loader): + data, target = data.to(DEVICE), target.to(DEVICE) + optimizer.zero_grad() + output = model(data) + loss = F.cross_entropy(output, target) + loss.backward() + optimizer.step() + + +# ## 테스트하기 +# 아무리 훈련이 잘 되었다고 해도 실제 데이터를 만났을때 성능이 낮다면 쓸모 없는 모델일 것입니다. +# 우리가 진정 원하는 것은 훈련 데이터에 최적화한 모델이 아니라 모든 데이터에서 높은 성능을 보이는 모델이기 때문입니다. +# 세상에 존재하는 모든 데이터에 최적화 하는 것을 "일반화"라고 부르고 +# 모델이 얼마나 실제 데이터에 적응하는지를 수치로 나타낸 것을 "일반화 오류"(Generalization Error) 라고 합니다. +# 우리가 만든 모델이 얼마나 일반화를 잘 하는지 알아보기 위해, +# 그리고 언제 훈련을 멈추어야 할지 알기 위해 +# 매 이포크가 끝날때 마다 테스트셋으로 모델의 성능을 측정해보겠습니다. + +def test(model, test_loader): + model.eval() + test_loss = 0 + correct = 0 + with torch.no_grad(): + for data, target in test_loader: + data, target = data.to(DEVICE), target.to(DEVICE) + output = model(data) + test_loss += F.cross_entropy(output, target, + size_average=False).item() + + # 맞춘 갯수 계산 + pred = output.max(1, keepdim=True)[1] + correct += pred.eq(target.view_as(pred)).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) + test_loss, test_accuracy = test(model, test_loader) + + print('[{}] Test Loss: {:.4f}, Accuracy: {:.2f}%'.format( + epoch, test_loss, test_accuracy)) + diff --git a/05-CNN-For-Image-Classification/01-cnn.py b/05-CNN-For-Image-Classification/01-cnn.py new file mode 100644 index 0000000..e5ff617 --- /dev/null +++ b/05-CNN-For-Image-Classification/01-cnn.py @@ -0,0 +1,126 @@ + +# coding: utf-8 + +# # 5.1 CNN으로 패션 아이템 구분하기 +# Convolutional Neural Network (CNN) 을 이용하여 패션아이템 구분 성능을 높여보겠습니다. + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.nn.functional as F +from torchvision import transforms, datasets + + +torch.manual_seed(42) +USE_CUDA = torch.cuda.is_available() +DEVICE = torch.device("cuda" if USE_CUDA else "cpu") + + +EPOCHS = 40 +BATCH_SIZE = 64 + + +# ## 데이터셋 불러오기 + +train_loader = torch.utils.data.DataLoader( + datasets.MNIST('./.data', + train=True, + download=True, + transform=transforms.Compose([ + transforms.ToTensor(), + transforms.Normalize((0.1307,), (0.3081,)) + ])), + batch_size=BATCH_SIZE, shuffle=True) +test_loader = torch.utils.data.DataLoader( + datasets.MNIST('./.data', + train=False, + transform=transforms.Compose([ + transforms.ToTensor(), + transforms.Normalize((0.1307,), (0.3081,)) + ])), + batch_size=BATCH_SIZE, shuffle=True) + + +# ## 뉴럴넷으로 Fashion MNIST 학습하기 + +class Net(nn.Module): + def __init__(self): + super(Net, self).__init__() + self.conv1 = nn.Conv2d(1, 10, kernel_size=5) + self.conv2 = nn.Conv2d(10, 20, kernel_size=5) + self.conv2_drop = nn.Dropout2d() + self.fc1 = nn.Linear(320, 50) + self.fc2 = nn.Linear(50, 10) + + def forward(self, x): + x = F.relu(F.max_pool2d(self.conv1(x), 2)) + x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) + x = x.view(-1, 320) + x = F.relu(self.fc1(x)) + x = F.dropout(x, training=self.training) + x = self.fc2(x) + return F.log_softmax(x, dim=1) + + +# ## 하이퍼파라미터 +# `to()` 함수는 모델의 파라미터들을 지정한 곳으로 보내는 역할을 합니다. 일반적으로 CPU 1개만 사용할 경우 필요는 없지만, GPU를 사용하고자 하는 경우 `to("cuda")`로 지정하여 GPU로 보내야 합니다. 지정하지 않을 경우 계속 CPU에 남아 있게 되며 빠른 훈련의 이점을 누리실 수 없습니다. +# 최적화 알고리즘으로 파이토치에 내장되어 있는 `optim.SGD`를 사용하겠습니다. + +model = Net().to(DEVICE) +optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) + + +# ## 훈련하기 + +def train(model, train_loader, optimizer, epoch): + model.train() + for batch_idx, (data, target) in enumerate(train_loader): + data, target = data.to(DEVICE), target.to(DEVICE) + optimizer.zero_grad() + output = model(data) + loss = F.cross_entropy(output, target) + loss.backward() + optimizer.step() + + if batch_idx % 200 == 0: + print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( + epoch, batch_idx * len(data), len(train_loader.dataset), + 100. * batch_idx / len(train_loader), loss.item())) + + +# ## 테스트하기 +# 아무리 훈련이 잘 되었다고 해도 실제 데이터를 만났을때 성능이 낮다면 쓸모 없는 모델일 것입니다. 우리가 진정 원하는 것은 훈련 데이터에 최적화한 모델이 아니라 모든 데이터에서 높은 성능을 보이는 모델이기 때문입니다. 세상에 존재하는 모든 데이터에 최적화 하는 것을 "일반화"라고 부르고 모델이 얼마나 실제 데이터에 적응하는지를 수치로 나타낸 것을 "일반화 오류"(Generalization Error) 라고 합니다. +# 우리가 만든 모델이 얼마나 일반화를 잘 하는지 알아보기 위해, 그리고 언제 훈련을 멈추어야 할지 알기 위해 매 이포크가 끝날때 마다 테스트셋으로 모델의 성능을 측정해보겠습니다. + +def test(model, test_loader): + model.eval() + test_loss = 0 + correct = 0 + with torch.no_grad(): + for data, target in test_loader: + data, target = data.to(DEVICE), target.to(DEVICE) + output = model(data) + + # sum up batch loss + test_loss += F.cross_entropy(output, target, + size_average=False).item() + + # get the index of the max log-probability + pred = output.max(1, keepdim=True)[1] + correct += pred.eq(target.view_as(pred)).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, epoch) + test_loss, test_accuracy = test(model, test_loader) + + print('[{}] Test Loss: {:.4f}, Accuracy: {:.2f}%'.format( + epoch, test_loss, test_accuracy)) + diff --git a/05-CNN-For-Image-Classification/02-cifar-cnn.py b/05-CNN-For-Image-Classification/02-cifar-cnn.py new file mode 100644 index 0000000..3bc9bf3 --- /dev/null +++ b/05-CNN-For-Image-Classification/02-cifar-cnn.py @@ -0,0 +1,168 @@ + +# coding: utf-8 + +# # 5.2 신경망 깊게 쌓아 컬러 데이터셋에 적용하기 +# Convolutional Neural Network (CNN) 을 쌓아올려 딥한 러닝을 해봅시다. + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.nn.functional as F +from torchvision import transforms, datasets, models + + +torch.manual_seed(42) +USE_CUDA = torch.cuda.is_available() +DEVICE = torch.device("cuda" if USE_CUDA else "cpu") + + +# ## 하이퍼파라미터 + +EPOCHS = 300 +BATCH_SIZE = 128 + + +# ## 데이터셋 불러오기 + +train_loader = torch.utils.data.DataLoader( + datasets.CIFAR10('./.data', + train=True, + download=True, + transform=transforms.Compose([ + transforms.RandomCrop(32, padding=4), + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + transforms.Normalize((0.5, 0.5, 0.5), + (0.5, 0.5, 0.5))])), + batch_size=BATCH_SIZE, shuffle=True) +test_loader = torch.utils.data.DataLoader( + datasets.CIFAR10('./.data', + train=False, + transform=transforms.Compose([ + transforms.ToTensor(), + transforms.Normalize((0.5, 0.5, 0.5), + (0.5, 0.5, 0.5))])), + batch_size=BATCH_SIZE, shuffle=True) + + +# ## ResNet 모델 만들기 + +class BasicBlock(nn.Module): + def __init__(self, in_planes, planes, stride=1): + super(BasicBlock, self).__init__() + self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, + stride=stride, padding=1, bias=False) + self.bn1 = nn.BatchNorm2d(planes) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, + stride=1, padding=1, bias=False) + self.bn2 = nn.BatchNorm2d(planes) + + self.shortcut = nn.Sequential() + if stride != 1 or in_planes != planes: + self.shortcut = nn.Sequential( + nn.Conv2d(in_planes, planes, + kernel_size=1, stride=stride, bias=False), + nn.BatchNorm2d(planes) + ) + + def forward(self, x): + out = F.relu(self.bn1(self.conv1(x))) + out = self.bn2(self.conv2(out)) + out += self.shortcut(x) + out = F.relu(out) + return out + + +class ResNet(nn.Module): + def __init__(self, num_classes=10): + super(ResNet, self).__init__() + self.in_planes = 16 + + self.conv1 = nn.Conv2d(3, 16, kernel_size=3, + stride=1, padding=1, bias=False) + self.bn1 = nn.BatchNorm2d(16) + self.layer1 = self._make_layer(16, 2, stride=1) + self.layer2 = self._make_layer(32, 2, stride=2) + self.layer3 = self._make_layer(64, 2, stride=2) + self.linear = nn.Linear(64, num_classes) + + def _make_layer(self, planes, num_blocks, stride): + strides = [stride] + [1]*(num_blocks-1) + layers = [] + for stride in strides: + layers.append(BasicBlock(self.in_planes, planes, stride)) + self.in_planes = planes + return nn.Sequential(*layers) + + def forward(self, x): + out = F.relu(self.bn1(self.conv1(x))) + out = self.layer1(out) + out = self.layer2(out) + out = self.layer3(out) + out = F.avg_pool2d(out, 8) + out = out.view(out.size(0), -1) + out = self.linear(out) + return out + + +# ## 준비 + +model = ResNet().to(DEVICE) +optimizer = optim.SGD(model.parameters(), lr=0.1, + momentum=0.9, weight_decay=0.0005) +scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1) + + +print(model) + + +# ## 훈련하기 + +def train(model, train_loader, optimizer, epoch): + model.train() + for batch_idx, (data, target) in enumerate(train_loader): + data, target = data.to(DEVICE), target.to(DEVICE) + optimizer.zero_grad() + output = model(data) + loss = F.cross_entropy(output, target) + loss.backward() + optimizer.step() + + +# ## 테스트하기 +# 아무리 훈련이 잘 되었다고 해도 실제 데이터를 만났을때 성능이 낮다면 쓸모 없는 모델일 것입니다. 우리가 진정 원하는 것은 훈련 데이터에 최적화한 모델이 아니라 모든 데이터에서 높은 성능을 보이는 모델이기 때문입니다. 세상에 존재하는 모든 데이터에 최적화 하는 것을 "일반화"라고 부르고 모델이 얼마나 실제 데이터에 적응하는지를 수치로 나타낸 것을 "일반화 오류"(Generalization Error) 라고 합니다. +# 우리가 만든 모델이 얼마나 일반화를 잘 하는지 알아보기 위해, 그리고 언제 훈련을 멈추어야 할지 알기 위해 매 이포크가 끝날때 마다 테스트셋으로 모델의 성능을 측정해보겠습니다. + +def test(model, test_loader): + model.eval() + test_loss = 0 + correct = 0 + with torch.no_grad(): + for data, target in test_loader: + data, target = data.to(DEVICE), target.to(DEVICE) + output = model(data) + + # sum up batch loss + test_loss += F.cross_entropy(output, target, + size_average=False).item() + + # get the index of the max log-probability + pred = output.max(1, keepdim=True)[1] + correct += pred.eq(target.view_as(pred)).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): + scheduler.step() + train(model, train_loader, optimizer, epoch) + test_loss, test_accuracy = test(model, test_loader) + + print('[{}] Test Loss: {:.4f}, Accuracy: {:.2f}%'.format( + epoch, test_loss, test_accuracy)) + diff --git a/06-Autoencoder/01-autoencoder.py b/06-Autoencoder/01-autoencoder.py new file mode 100644 index 0000000..5497a33 --- /dev/null +++ b/06-Autoencoder/01-autoencoder.py @@ -0,0 +1,162 @@ + +# coding: utf-8 + +# # 7.1 오토인코더로 이미지지의 특징을 압축해보기 + +import torch +import torchvision +import torch.nn.functional as F +from torch import nn, optim +from torch.autograd import Variable +from torchvision import transforms, datasets + +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import Axes3D +from matplotlib import cm +import numpy as np +get_ipython().run_line_magic('matplotlib', 'inline') + + +torch.manual_seed(1) # reproducible + + +# Hyper Parameters +EPOCH = 10 +BATCH_SIZE = 64 +USE_CUDA = torch.cuda.is_available() +DEVICE = torch.device("cuda" if USE_CUDA else "cpu") +print("Using Device:", DEVICE) + + +# Fashion MNIST digits dataset +trainset = datasets.FashionMNIST( + root = './.data/', + train = True, + download = True, + transform = transforms.ToTensor() +) +train_loader = torch.utils.data.DataLoader( + dataset = trainset, + batch_size = BATCH_SIZE, + shuffle = True, + num_workers = 2 +) + + +class Autoencoder(nn.Module): + def __init__(self): + super(Autoencoder, self).__init__() + + self.encoder = nn.Sequential( + nn.Linear(28*28, 128), + nn.ReLU(), + nn.Linear(128, 64), + nn.ReLU(), + nn.Linear(64, 12), + nn.ReLU(), + nn.Linear(12, 3), # compress to 3 features which can be visualized in plt + ) + self.decoder = nn.Sequential( + nn.Linear(3, 12), + nn.ReLU(), + nn.Linear(12, 64), + nn.ReLU(), + nn.Linear(64, 128), + nn.ReLU(), + nn.Linear(128, 28*28), + nn.Sigmoid(), # compress to a range (0, 1) + ) + + def forward(self, x): + encoded = self.encoder(x) + decoded = self.decoder(encoded) + return encoded, decoded + + +autoencoder = Autoencoder().to(DEVICE) +optimizer = torch.optim.Adam(autoencoder.parameters(), lr=0.005) +criterion = nn.MSELoss() + + +# original data (first row) for viewing +view_data = trainset.train_data[:5].view(-1, 28*28) +view_data = view_data.type(torch.FloatTensor)/255. + + +def train(autoencoder, train_loader): + autoencoder.train() + for step, (x, label) in enumerate(train_loader): + x = x.view(-1, 28*28).to(DEVICE) + y = x.view(-1, 28*28).to(DEVICE) + label = label.to(DEVICE) + + encoded, decoded = autoencoder(x) + + loss = criterion(decoded, y) + optimizer.zero_grad() + loss.backward() + optimizer.step() + + +for epoch in range(1, EPOCH+1): + train(autoencoder, train_loader) + + # plotting decoded image (second row) + test_x = view_data.to(DEVICE) + _, decoded_data = autoencoder(test_x) + + # 원본과 디코딩 결과 비교해보기 + f, a = plt.subplots(2, 5, figsize=(5, 2)) + print("[Epoch {}]".format(epoch)) + for i in range(5): + img = np.reshape(view_data.data.numpy()[i],(28, 28)) + a[0][i].imshow(img, cmap='gray') + a[0][i].set_xticks(()); a[0][i].set_yticks(()) + + for i in range(5): + img = np.reshape(decoded_data.to("cpu").data.numpy()[i], (28, 28)) + a[1][i].imshow(img, cmap='gray') + a[1][i].set_xticks(()); a[1][i].set_yticks(()) + plt.show() + + +# visualize in 3D plot +view_data = trainset.train_data[:200].view(-1, 28*28) +view_data = view_data.type(torch.FloatTensor)/255. +test_x = view_data.to(DEVICE) +encoded_data, _ = autoencoder(test_x) +encoded_data = encoded_data.to("cpu") + + +CLASSES = { + 0: 'T-shirt/top', + 1: 'Trouser', + 2: 'Pullover', + 3: 'Dress', + 4: 'Coat', + 5: 'Sandal', + 6: 'Shirt', + 7: 'Sneaker', + 8: 'Bag', + 9: 'Ankle boot' +} + +fig = plt.figure(figsize=(10,8)) +ax = Axes3D(fig) + +X = encoded_data.data[:, 0].numpy() +Y = encoded_data.data[:, 1].numpy() +Z = encoded_data.data[:, 2].numpy() + +labels = trainset.train_labels[:200].numpy() + +for x, y, z, s in zip(X, Y, Z, labels): + name = CLASSES[s] + color = cm.rainbow(int(255*s/9)) + ax.text(x, y, z, name, backgroundcolor=color) + +ax.set_xlim(X.min(), X.max()) +ax.set_ylim(Y.min(), Y.max()) +ax.set_zlim(Z.min(), Z.max()) +plt.show() + diff --git a/07-RNN-For-Sequential-Data/01-text-classification.py b/07-RNN-For-Sequential-Data/01-text-classification.py new file mode 100644 index 0000000..d17eed0 --- /dev/null +++ b/07-RNN-For-Sequential-Data/01-text-classification.py @@ -0,0 +1,154 @@ + +# coding: utf-8 + +import os +import sys +import argparse +import torch +import torch.nn as nn +import torch.nn.functional as F +from torchtext import data, datasets + + +# get hyper parameters +BATCH_SIZE = 64 +lr = 0.001 +EPOCHS = 40 +torch.manual_seed(42) +USE_CUDA = torch.cuda.is_available() +DEVICE = torch.device("cuda" if USE_CUDA else "cpu") + + +# class BasicRNN(nn.Module): +# """ +# Basic RNN +# """ +# def __init__(self, n_layers, hidden_dim, n_vocab, embed_dim, n_classes, dropout_p=0.2): +# super(BasicRNN, self).__init__() +# print("Building Basic RNN model...") +# self.n_layers = n_layers +# self.hidden_dim = hidden_dim + +# self.embed = nn.Embedding(n_vocab, embed_dim) +# self.dropout = nn.Dropout(dropout_p) +# self.rnn = nn.RNN(embed_dim, hidden_dim, n_layers, +# dropout=dropout_p, batch_first=True) +# self.out = nn.Linear(self.hidden_dim, n_classes) + +# def forward(self, x): +# embedded = self.embed(x) # [b, i] -> [b, i, e] +# _, hidden = self.rnn(embedded) +# self.dropout(hidden) +# hidden = hidden.squeeze() +# logit = self.out(hidden) # [b, h] -> [b, o] +# return logit + +class BasicLSTM(nn.Module): + def __init__(self, n_layers, hidden_dim, n_vocab, embed_dim, n_classes, dropout_p=0.2): + super(BasicLSTM, self).__init__() + print("Building Basic LSTM model...") + self.n_layers = n_layers + self.hidden_dim = hidden_dim + + self.embed = nn.Embedding(n_vocab, embed_dim) + self.dropout = nn.Dropout(dropout_p) + self.lstm = nn.LSTM(embed_dim, self.hidden_dim, + num_layers=self.n_layers, + dropout=dropout_p, + batch_first=True) + self.out = nn.Linear(self.hidden_dim, n_classes) + + def forward(self, x): + x = self.embed(x) # [b, i] -> [b, i, e] + h_0 = self._init_state(batch_size=x.size(0)) + x, _ = self.lstm(x, h_0) # [i, b, h] + h_t = x[:,-1,:] + self.dropout(h_t) + logit = self.out(h_t) # [b, h] -> [b, o] + return logit + + def _init_state(self, batch_size=1): + weight = next(self.parameters()).data + return ( + weight.new(self.n_layers, batch_size, self.hidden_dim).zero_(), + weight.new(self.n_layers, batch_size, self.hidden_dim).zero_() + ) + + +def train(model, optimizer, train_iter): + model.train() + for b, batch in enumerate(train_iter): + x, y = batch.text.to(DEVICE), batch.label.to(DEVICE) + y.data.sub_(1) # index align + optimizer.zero_grad() + logit = model(x) + loss = F.cross_entropy(logit, y) + loss.backward() + optimizer.step() +# if b % 100 == 0: +# corrects = (logit.max(1)[1].view(y.size()).data == y.data).sum() +# accuracy = 100.0 * corrects / batch.batch_size +# sys.stdout.write( +# '\rBatch[%d] - loss: %.6f acc: %.2f' % +# (b, loss.item(), accuracy)) + + +def evaluate(model, val_iter): + """evaluate model""" + model.eval() + corrects, avg_loss = 0, 0 + for batch in val_iter: + x, y = batch.text.to(DEVICE), batch.label.to(DEVICE) + y.data.sub_(1) # index align + logit = model(x) + loss = F.cross_entropy(logit, y, size_average=False) + avg_loss += loss.item() + corrects += (logit.max(1)[1].view(y.size()).data == y.data).sum() + size = len(val_iter.dataset) + avg_loss = avg_loss / size + accuracy = 100.0 * corrects / size + return avg_loss, accuracy + + +# # IMDB 데이터셋 가져오기 + +# load data +print("\nLoading data...") +TEXT = data.Field(sequential=True, batch_first=True, lower=True) +LABEL = data.Field(sequential=False, batch_first=True) +train_data, test_data = datasets.IMDB.splits(TEXT, LABEL) +TEXT.build_vocab(train_data, min_freq=5) +LABEL.build_vocab(train_data) + +train_iter, test_iter = data.BucketIterator.splits( + (train_data, test_data), batch_size=BATCH_SIZE, + shuffle=True, repeat=False) + +vocab_size = len(TEXT.vocab) +n_classes = len(LABEL.vocab) - 1 + + +print("[TRAIN]: %d \t [TEST]: %d \t [VOCAB] %d \t [CLASSES] %d" + % (len(train_iter),len(test_iter), vocab_size, n_classes)) + + +model = BasicLSTM(1, 256, vocab_size, 128, n_classes, 0.5).to(DEVICE) +optimizer = torch.optim.Adam(model.parameters(), lr=lr) + +print(model) + + +best_val_loss = None +for e in range(1, EPOCHS+1): + train(model, optimizer, train_iter) + val_loss, val_accuracy = evaluate(model, test_iter) + + print("\n[Epoch: %d] val_loss:%5.2f | acc:%5.2f" % (e, val_loss, val_accuracy)) + + # Save the model if the validation loss is the best we've seen so far. +# if not best_val_loss or val_loss < best_val_loss: +# if not os.path.isdir("snapshot"): +# os.makedirs("snapshot") +# torch.save(model.state_dict(), './snapshot/convcnn.pt') +# best_val_loss = val_loss + diff --git a/07-RNN-For-Sequential-Data/02-sequence-to-sequence.py b/07-RNN-For-Sequential-Data/02-sequence-to-sequence.py new file mode 100644 index 0000000..d04d236 --- /dev/null +++ b/07-RNN-For-Sequential-Data/02-sequence-to-sequence.py @@ -0,0 +1,113 @@ + +# coding: utf-8 + +# # Seq2Seq (Encoder-Decoder) Model +# this model is the basic encoder decoder model without attention mechanism. + +import numpy as np +import torch as th +import torch.nn as nn +import torch.nn.functional as F +from torch.autograd import Variable +from torch import optim + + +vocab_size = 256 # ascii size +x_ = list(map(ord, "hello")) # convert to list of ascii codes +y_ = list(map(ord, "hola")) # convert to list of ascii codes +print("hello -> ", x_) +print("hola -> ", y_) + + +x = Variable(th.LongTensor(x_)) +y = Variable(th.LongTensor(y_)) + + +print(x) + + +class Seq2Seq(nn.Module): + def __init__(self, vocab_size, hidden_size): + super(Seq2Seq, self).__init__() + self.n_layers = 1 + self.hidden_size = hidden_size + self.embedding = nn.Embedding(vocab_size, hidden_size) + self.encoder = nn.LSTM(hidden_size, hidden_size) + self.decoder = nn.LSTM(hidden_size, hidden_size) + self.project = nn.Linear(hidden_size, vocab_size) + + def forward(self, inputs, targets): + # Encoder inputs and states + initial_state = self._init_state() + embedding = self.embedding(inputs).unsqueeze(1) + # embedding = [seq_len, batch_size, embedding_size] + + # Encoder + encoder_output, encoder_state = self.encoder(embedding, initial_state) + # encoder_output = [seq_len, batch_size, hidden_size] + # encoder_state = [n_layers, seq_len, hidden_size] + + # Decoder inputs and states + decoder_state = encoder_state + decoder_input = Variable(th.LongTensor([[0]])) + + # Decoder + outputs = [] + for i in range(targets.size()[0]): + decoder_input = self.embedding(decoder_input) + decoder_output, decoder_state = self.decoder(decoder_input, decoder_state) + + # Project to the vocabulary size + projection = self.project(decoder_output.view(1, -1)) # batch x vocab_size + + # Make prediction + prediction = F.softmax(projection) # batch x vocab_size + outputs.append(prediction) + + # update decoder input + _, top_i = prediction.data.topk(1) # 1 x 1 + decoder_input = Variable(top_i) + + outputs = th.stack(outputs).squeeze() + return outputs + + def _init_state(self, batch_size=1): + weight = next(self.parameters()).data + return ( + Variable(weight.new(self.n_layers, batch_size, self.hidden_size).zero_()), + Variable(weight.new(self.n_layers, batch_size, self.hidden_size).zero_()) + ) + + +seq2seq = Seq2Seq(vocab_size, 16) +print(seq2seq) +pred = seq2seq(x, y) +print(pred) + + +criterion = nn.CrossEntropyLoss() +optimizer = optim.Adam(seq2seq.parameters(), lr=1e-3) + + +log = [] +for i in range(1000): + prediction = seq2seq(x, y) + loss = criterion(prediction, y) + optimizer.zero_grad() + loss.backward() + optimizer.step() + loss_val = loss.data[0] + log.append(loss_val) + if i % 100 == 0: + print("%d loss: %s" % (i, loss_val)) + _, top1 = prediction.data.topk(1, 1) + for c in top1.squeeze().numpy().tolist(): + print(chr(c), end=" ") + print() + + +import matplotlib.pyplot as plt +plt.plot(log) +plt.ylabel('cross entropy loss') +plt.show() + diff --git a/08-Hacking-Deep-Learning/01-fgsm-attack.py b/08-Hacking-Deep-Learning/01-fgsm-attack.py new file mode 100644 index 0000000..78f49e0 --- /dev/null +++ b/08-Hacking-Deep-Learning/01-fgsm-attack.py @@ -0,0 +1,85 @@ + +# coding: utf-8 + +import torch +import torchvision.models as models +import torchvision.transforms as transforms + +import numpy as np +from PIL import Image +import json + + +get_ipython().run_line_magic('matplotlib', 'inline') +import matplotlib.pyplot as plt + +torch.manual_seed(1) + + +CLASSES = json.load(open('./imagenet_samples/imagenet_classes.json')) +idx2class = [CLASSES[str(i)] for i in range(1000)] +class2idx = {v:i for i,v in enumerate(idx2class)} + + +vgg16 = models.vgg16(pretrained=True) +vgg16.eval() +print(vgg16) + + +softmax = torch.nn.Softmax() + + +img_transforms = transforms.Compose([transforms.Scale((224, 224), Image.BICUBIC), + transforms.ToTensor(), + transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) +def norm(x): + return 2.*(x/255.-0.5) + +def unnorm(x): + un_x = 255*(x*0.5+0.5) + un_x[un_x > 255] = 255 + un_x[un_x < 0] = 0 + un_x = un_x.astype(np.uint8) + return un_x + + +img = Image.open('imagenet_samples/chihuahua.jpg') +img_tensor = img_transforms(img) + +plt.figure(figsize=(10,5)) +plt.imshow(np.asarray(img)) + + +img_tensor.requires_grad_(True) +out = vgg16(img_tensor.unsqueeze(0)) +probs = softmax(out) +cls_idx = np.argmax(out.data.numpy()) +print(str(cls_idx) + ":" + idx2class[cls_idx] + ":" + str(out.data.numpy()[0][cls_idx]) + ":" + str(probs.data.numpy()[0][cls_idx])) + + +out[0,class2idx['wooden spoon']].backward() + + +img_grad = img_tensor.grad +img_tensor = img_tensor.detach() + +grad_sign = np.sign(img_grad.numpy()).astype(np.uint8) +epsilon = 0.1 +new_img_array = np.asarray(unnorm(img_tensor.numpy()))+epsilon*grad_sign +new_img_array[new_img_array>255] = 255 +new_img_array[new_img_array<0] = 0 +new_img_array = new_img_array.astype(np.uint8) +plt.figure(figsize=(10,5)) +plt.subplot(1,2,1) +plt.imshow(unnorm(img_tensor.numpy()).transpose(1,2,0)) +plt.subplot(1,2,2) +plt.imshow(new_img_array.transpose(1,2,0)) +new_img_array = norm(new_img_array) +new_img_var = torch.FloatTensor(new_img_array) +new_img_var.requires_grad_(True) +new_out = vgg16(new_img_var.unsqueeze(0)) +new_out_np = new_out.data.numpy() +new_probs = softmax(new_out) +new_cls_idx = np.argmax(new_out_np) +print(str(new_cls_idx) + ":" + idx2class[new_cls_idx] + ":" + str(new_probs.data.numpy()[0][new_cls_idx])) + diff --git a/08-Hacking-Deep-Learning/02-iterative-target-attack.py b/08-Hacking-Deep-Learning/02-iterative-target-attack.py new file mode 100644 index 0000000..0828f13 --- /dev/null +++ b/08-Hacking-Deep-Learning/02-iterative-target-attack.py @@ -0,0 +1,86 @@ + +# coding: utf-8 + +import torch +import torchvision.models as models +import torchvision.transforms as transforms + +import numpy as np +from PIL import Image +import json + + +get_ipython().run_line_magic('matplotlib', 'inline') +import matplotlib.pyplot as plt + +torch.manual_seed(1) + + +CLASSES = json.load(open('./imagenet_samples/imagenet_classes.json')) +idx2class = [CLASSES[str(i)] for i in range(1000)] +class2idx = {v:i for i,v in enumerate(idx2class)} + + +vgg16 = models.vgg16(pretrained=True) +vgg16.eval() +print(vgg16) + + +softmax = torch.nn.Softmax() + + +img_transforms = transforms.Compose([transforms.Scale((224, 224), Image.BICUBIC), + transforms.ToTensor(), + transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) +def norm(x): + return 2.*(x/255.-0.5) + +def unnorm(x): + un_x = 255*(x*0.5+0.5) + un_x[un_x > 255] = 255 + un_x[un_x < 0] = 0 + un_x = un_x.astype(np.uint8) + return un_x + + +img = Image.open('imagenet_samples/chihuahua.jpg') +img_tensor = img_transforms(img) + +plt.figure(figsize=(10,5)) +plt.imshow(np.asarray(img)) + + +img_tensor.requires_grad_(True) +out = vgg16(img_tensor.unsqueeze(0)) +probs = softmax(out) +cls_idx = np.argmax(out.data.numpy()) +print(str(cls_idx) + ":" + idx2class[cls_idx] + ":" + str(out.data.numpy()[0][cls_idx]) + ":" + str(probs.data.numpy()[0][cls_idx])) + + +learning_rate = 1 +img = Image.open('imagenet_samples/chihuahua.jpg') +fake_img_tensor = img_transforms(img) +img_var_fake = torch.autograd.Variable(fake_img_tensor.unsqueeze(0), requires_grad=True) +fake_class_idx = class2idx['street sign'] +for i in range(100): + out_fake = vgg16(img_var_fake) + _, out_idx = out_fake.data.max(dim=1) + if out_idx.numpy() == fake_class_idx: + print('Fake generated in ' + str(i) + ' iterations') + break + out_fake[0,fake_class_idx].backward() + img_var_fake_grad = img_var_fake.grad.data + img_var_fake.data += learning_rate*img_var_fake_grad/img_var_fake_grad.norm() + img_var_fake.grad.data.zero_() +probs_fake = softmax(out_fake) +print(str(fake_class_idx) + ":" + idx2class[fake_class_idx] + ":" + str(out_fake.data.numpy()[0][fake_class_idx]) + ":" + str(probs_fake.data.numpy()[0][fake_class_idx])) + + +plt.figure(figsize=(10,5)) +plt.subplot(1,3,1) +plt.imshow(unnorm(img_tensor.detach().numpy()).transpose(1,2,0)) +plt.subplot(1,3,2) +plt.imshow(unnorm(img_var_fake.data.detach().numpy()[0]).transpose(1,2,0)) +plt.subplot(1,3,3) +plt.imshow(unnorm(img_var_fake.data.detach().numpy()[0] - img_tensor.detach().numpy()).transpose(1,2,0)) + diff --git a/10-DQN-Learns-From-Environment/01-cartpole-dqn.py b/10-DQN-Learns-From-Environment/01-cartpole-dqn.py new file mode 100644 index 0000000..326f036 --- /dev/null +++ b/10-DQN-Learns-From-Environment/01-cartpole-dqn.py @@ -0,0 +1,109 @@ + +# coding: utf-8 + +import gym +from gym import wrappers +import random +import math +import torch +import torch.nn as nn +import torch.optim as optim +from torch.autograd import Variable +import torch.nn.functional as F +import matplotlib.pyplot as plt +from collections import deque +import numpy as np + + +env = gym.make('CartPole-v1') + + +# hyper parameters +EPISODES = 50 # number of episodes +EPS_START = 0.9 # e-greedy threshold start value +EPS_END = 0.05 # e-greedy threshold end value +EPS_DECAY = 200 # e-greedy threshold decay +GAMMA = 0.8 # Q-learning discount factor +LR = 0.001 # NN optimizer learning rate +HIDDEN_LAYER = 256 # NN hidden layer size +BATCH_SIZE = 64 # Q-learning batch size + + +class DQNAgent: + def __init__(self): + self.model = nn.Sequential( + nn.Linear(4, HIDDEN_LAYER), + nn.ReLU(), + nn.Linear(HIDDEN_LAYER, 2) + ) + self.memory = deque(maxlen=10000) + self.optimizer = optim.Adam(self.model.parameters(), LR) + self.steps_done = 0 + + def act(self, state): + eps_threshold = EPS_END + (EPS_START - EPS_END) * math.exp(-1. * self.steps_done / EPS_DECAY) + self.steps_done += 1 + if random.random() > eps_threshold: + return self.model(state).data.max(1)[1].view(1, 1) + else: + return torch.LongTensor([[random.randrange(2)]]) + + def memorize(self, state, action, reward, next_state): + self.memory.append((state, + action, + torch.FloatTensor([reward]), + torch.FloatTensor([next_state]))) + + def learn(self): + """Experience Replay""" + if len(self.memory) < BATCH_SIZE: + return + batch = random.sample(self.memory, BATCH_SIZE) + states, actions, rewards, next_states = zip(*batch) + + states = torch.cat(states) + actions = torch.cat(actions) + rewards = torch.cat(rewards) + next_states = torch.cat(next_states) + + current_q = self.model(states).gather(1, actions) + max_next_q = self.model(next_states).detach().max(1)[0] + expected_q = rewards + (GAMMA * max_next_q) + + loss = F.mse_loss(current_q.squeeze(), expected_q) + self.optimizer.zero_grad() + loss.backward() + self.optimizer.step() + + +agent = DQNAgent() + + +env = gym.make('CartPole-v0') +episode_durations = [] + +for e in range(1, EPISODES+1): + state = env.reset() + steps = 0 + while True: + env.render() + state = torch.FloatTensor([state]) + action = agent.act(state) + next_state, reward, done, _ = env.step(action.item()) + + # negative reward when attempt ends + if done: + reward = -1 + + agent.memorize(state, action, reward, next_state) + agent.learn() + + state = next_state + steps += 1 + + if done: + print("{2} Episode {0} finished after {1} steps" + .format(e, steps, '\033[92m' if steps >= 195 else '\033[99m')) + episode_durations.append(steps) + break + diff --git a/11-A2C-Self-Driving/README.md b/11-Self-Driving-Car/README.md similarity index 100% rename from 11-A2C-Self-Driving/README.md rename to 11-Self-Driving-Car/README.md diff --git a/README.md b/README.md index 8648840..03535c3 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ * [팁] OpenAI Gym * [프로젝트 1] [카트폴 게임 마스터하기](10-DQN-Learns-From-Environment/01-cartpole-dqn.ipynb) * 더 보기 -11. [간단한 자율주행 해보기](11-A2C-Self-Driving) - A2C알고리즘을 활용하여 간단한 자율주행차를 만들어봅니다. +11. [간단한 자율주행 해보기](11-Self-Driving-Car) - 앞서 배운 개념들을 활용하여 간단한 자율주행을 해봅니다. * [개념] 자율주행차란? * [팁] 자율주행 시뮬레이터 소개 * [팁] 설치와 환경설정