Вы находитесь на странице: 1из 6

26.08.2021 dlcourse_ai/PyTorch.

ipynb at master · sim0nsays/dlcourse_ai · GitHub

sim0nsays / dlcourse_ai

Code Issues 4 Pull requests 7 Actions Projects Wiki Security Insights


master
dlcourse_ai / assignments / assignment2 / PyTorch.ipynb Go to file

Simon Kozlov
Stronger values Latest commit
1d76129
on 26 Jun 2019
History


1
contributor

596 lines (596 sloc)



63.7 KB Raw Blame

https://github.com/sim0nsays/dlcourse_ai/blob/master/assignments/assignment2/PyTorch.ipynb 1/6
26.08.2021 dlcourse_ai/PyTorch.ipynb at master · sim0nsays/dlcourse_ai · GitHub

Задание 2.2 - Введение в PyTorch


Для этого задания потребуется установить версию PyTorch 1.0

https://pytorch.org/get-started/locally/ (https://pytorch.org/get-started/locally/)

В этом задании мы познакомимся с основными компонентами PyTorch и натренируем несколько небольших моделей.

GPU нам пока не понадобится.

Основные ссылки:

https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html (https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)

https://pytorch.org/docs/stable/nn.html (https://pytorch.org/docs/stable/nn.html)

https://pytorch.org/docs/stable/torchvision/index.html (https://pytorch.org/docs/stable/torchvision/index.html)

In [ ]: import torch

import torch.nn as nn

import torch.optim as optim

import torchvision.datasets as dset

from torch.utils.data.sampler import SubsetRandomSampler, Sampler

from torchvision import transforms

import matplotlib.pyplot as plt

%matplotlib inline

import numpy as np

Как всегда, начинаем с загрузки данных


PyTorch поддерживает загрузку SVHN из коробки.

In [ ]: # First, lets load the dataset

data_train = dset.SVHN('./data/', split='train',

transform=transforms.Compose([

transforms.ToTensor(),

transforms.Normalize(mean=[0.43,0.44,0.47],

std=[0.20,0.20,0.20])

])

data_test = dset.SVHN('./data/', split='test',

transform=transforms.Compose([

transforms.ToTensor(),

transforms.Normalize(mean=[0.43,0.44,0.47],

std=[0.20,0.20,0.20])

]))

Теперь мы разделим данные на training и validation с использованием классов SubsetRandomSampler и DataLoader.

DataLoader подгружает данные, предоставляемые классом Dataset, во время тренировки и группирует их в батчи.
Он дает возможность
указать Sampler, который выбирает, какие примеры из датасета использовать для тренировки. Мы используем это, чтобы разделить данные
на training и validation.

Подробнее: https://pytorch.org/tutorials/beginner/data_loading_tutorial.html (https://pytorch.org/tutorials/beginner/data_loading_tutorial.html)

In [ ]: batch_size = 64

data_size = data_train.data.shape[0]

validation_split = .2

split = int(np.floor(validation_split * data_size))

indices = list(range(data_size))

np.random.shuffle(indices)

train_indices, val_indices = indices[split:], indices[:split]

train_sampler = SubsetRandomSampler(train_indices)

val_sampler = SubsetRandomSampler(val_indices)

train_loader = torch.utils.data.DataLoader(data_train, batch_size=batch_size,

sampler=train_sampler)

val_loader = torch.utils.data.DataLoader(data_train, batch_size=batch_size,

sampler=val_sampler)

В нашей задаче мы получаем на вход изображения, но работаем с ними как с одномерными массивами. Чтобы превратить многомерный
массив в одномерный, мы воспользуемся очень простым вспомогательным модулем Flattener.

In [ ]: sample, label = data_train[0]

print("SVHN data sample shape: ", sample.shape)

# As you can see, the data is shaped like an image

https://github.com/sim0nsays/dlcourse_ai/blob/master/assignments/assignment2/PyTorch.ipynb 2/6
26.08.2021 dlcourse_ai/PyTorch.ipynb at master · sim0nsays/dlcourse_ai · GitHub

# We'll use a special helper module to shape it into a tensor

class Flattener(nn.Module):

def forward(self, x):

batch_size, *_ = x.shape

return x.view(batch_size, -1)

И наконец, мы создаем основные объекты PyTorch:

nn_model - собственно, модель с нейросетью


loss - функцию ошибки, в нашем случае CrossEntropyLoss
optimizer - алгоритм оптимизации, в нашем случае просто SGD

In [ ]: nn_model = nn.Sequential(

Flattener(),

nn.Linear(3*32*32, 100),

nn.ReLU(inplace=True),

nn.Linear(100, 10),

nn_model.type(torch.FloatTensor)

# We will minimize cross-entropy between the ground truth and

# network predictions using an SGD optimizer

loss = nn.CrossEntropyLoss().type(torch.FloatTensor)

optimizer = optim.SGD(nn_model.parameters(), lr=1e-2, weight_decay=1e-1)

Тренируем!
Ниже приведена функция train_model, реализующая основной цикл тренировки PyTorch.

Каждую эпоху эта функция вызывает функцию compute_accuracy, которая вычисляет точность на validation, эту последнюю функцию
предлагается реализовать вам.

In [ ]: # This is how to implement the same main train loop in PyTorch. Pretty easy, right?

def train_model(model, train_loader, val_loader, loss, optimizer, num_epochs):

loss_history = []

train_history = []

val_history = []

for epoch in range(num_epochs):

model.train() # Enter train mode

loss_accum = 0

correct_samples = 0

total_samples = 0

for i_step, (x, y) in enumerate(train_loader):

prediction = model(x)

loss_value = loss(prediction, y)

optimizer.zero_grad()

loss_value.backward()

optimizer.step()

_, indices = torch.max(prediction, 1)

correct_samples += torch.sum(indices == y)

total_samples += y.shape[0]

loss_accum += loss_value

ave_loss = loss_accum / (i_step + 1)

train_accuracy = float(correct_samples) / total_samples

val_accuracy = compute_accuracy(model, val_loader)

loss_history.append(float(ave_loss))

train_history.append(train_accuracy)

val_history.append(val_accuracy)

print("Average loss: %f, Train accuracy: %f, Val accuracy: %f" % (ave_loss, train_accuracy, val_accur
acy))

return loss_history, train_history, val_history

def compute_accuracy(model, loader):

"""

Computes accuracy on the dataset wrapped in a loader

Returns: accuracy as a float value between 0 and 1

"""

model.eval() # Evaluation mode

# TODO: Implement the inference of the model on all of the batches from loader,

# and compute the overall accuracy.

# Hint: PyTorch has the argmax function!

raise Exception("Not implemented")

return 0

https://github.com/sim0nsays/dlcourse_ai/blob/master/assignments/assignment2/PyTorch.ipynb 3/6
26.08.2021 dlcourse_ai/PyTorch.ipynb at master · sim0nsays/dlcourse_ai · GitHub

loss_history, train_history, val_history = train_model(nn_model, train_loader, val_loader, loss, optimizer,


3)

После основного цикла


Посмотрим на другие возможности и оптимизации, которые предоставляет PyTorch.

Добавьте еще один скрытый слой размера 100 нейронов к модели

In [ ]: # Since it's so easy to add layers, let's add some!

# TODO: Implement a model with 2 hidden layers of the size 100

nn_model = nn.Sequential(

nn_model.type(torch.FloatTensor)

optimizer = optim.SGD(nn_model.parameters(), lr=1e-2, weight_decay=1e-1)

loss_history, train_history, val_history = train_model(nn_model, train_loader, val_loader, loss, optimizer,


5)

Добавьте слой с Batch Normalization

In [ ]: # We heard batch normalization is powerful, let's use it!


# TODO: Add batch normalization after each of the hidden layers of the network, before or after non-linearity

# Hint: check out torch.nn.BatchNorm1d

nn_model = nn.Sequential(

optimizer = optim.SGD(nn_model.parameters(), lr=1e-3, weight_decay=1e-1)

loss_history, train_history, val_history = train_model(nn_model, train_loader, val_loader, loss, optimizer,


5)

Добавьте уменьшение скорости обучения по ходу тренировки.

In [ ]: # Learning rate annealing

# Reduce your learning rate 2x every 2 epochs

# Hint: look up learning rate schedulers in PyTorch. You might need to extend train_model function a little b
it too!

nn_model = nn.Sequential(

loss_history, train_history, val_history = train_model()

Визуализируем ошибки модели


Попробуем посмотреть, на каких изображениях наша модель ошибается.
Для этого мы получим все предсказания модели на validation set и
сравним их с истинными метками (ground truth).

Первая часть - реализовать код на PyTorch, который вычисляет все предсказания модели на validation set.

Чтобы это сделать мы приводим код SubsetSampler, который просто проходит по всем заданным индексам последовательно и составляет из
них батчи.

Реализуйте функцию evaluate_model, которая прогоняет модель через все сэмплы validation set и запоминает предсказания модели и
истинные метки.

In [ ]: class SubsetSampler(Sampler):

r"""Samples elements with given indices sequentially

Arguments:

indices (ndarray): indices of the samples to take


"""

def __init__(self, indices):

self.indices = indices

def __iter__(self):

return (self.indices[i] for i in range(len(self.indices)))

def __len__(self):

return len(self.indices)

def evaluate_model(model, dataset, indices):

"""

Computes predictions and ground truth labels for the indices of the dataset

Returns:

predictions: np array of ints - model predictions

grount truth: np array of ints actual labels of the dataset


https://github.com/sim0nsays/dlcourse_ai/blob/master/assignments/assignment2/PyTorch.ipynb 4/6
26.08.2021 dlcourse_ai/PyTorch.ipynb at master · sim0nsays/dlcourse_ai · GitHub
grount_truth: np array of ints - actual labels of the dataset

"""

model.eval() # Evaluation mode

# TODO: Evaluate model on the list of indices and capture predictions

# and ground truth labels

# Hint: SubsetSampler above could be useful!

raise Exception("Not implemented")

return predictions, ground_truth

# Evaluate model on validation

predictions, gt = evaluate_model(nn_model, data_train, val_indices)

assert len(predictions) == len(val_indices)

assert len(gt) == len(val_indices)

assert gt[100] == data_train[val_indices[100]][1]

assert np.any(np.not_equal(gt, predictions))

Confusion matrix
Первая часть визуализации - вывести confusion matrix (https://en.wikipedia.org/wiki/Confusion_matrix
(https://en.wikipedia.org/wiki/Confusion_matrix) ).

Confusion matrix - это матрица, где каждой строке соответствуют классы предсказанный, а столбцу - классы истинных меток (ground truth).
Число с координатами i,j - это количество сэмплов класса j, которые модель считает классом i.

Для того, чтобы облегчить вам задачу, ниже реализована функция visualize_confusion_matrix которая визуализирует такую матрицу.

Вам осталось реализовать функцию build_confusion_matrix, которая ее вычислит.

Результатом должна быть матрица 10x10.

In [ ]: def visualize_confusion_matrix(confusion_matrix):

"""

Visualizes confusion matrix

confusion_matrix: np array of ints, x axis - predicted class, y axis - actual class

[i][j] should have the count of samples that were predicted to be class i,

but have j in the ground truth

"""

# Adapted from

# https://stackoverflow.com/questions/2897826/confusion-matrix-with-number-of-classified-misclassified-in
stances-on-it-python

assert confusion_matrix.shape[0] == confusion_matrix.shape[1]

size = confusion_matrix.shape[0]

fig = plt.figure(figsize=(10,10))

plt.title("Confusion matrix")

plt.ylabel("predicted")

plt.xlabel("ground truth")

res = plt.imshow(confusion_matrix, cmap='GnBu', interpolation='nearest')

cb = fig.colorbar(res)

plt.xticks(np.arange(size))

plt.yticks(np.arange(size))

for i, row in enumerate(confusion_matrix):

for j, count in enumerate(row):

plt.text(j, i, count, fontsize=14, horizontalalignment='center', verticalalignment='center')

def build_confusion_matrix(predictions, ground_truth):

"""

Builds confusion matrix from predictions and ground truth

predictions: np array of ints, model predictions for all validation samples

ground_truth: np array of ints, ground truth for all validation samples

Returns:
https://github.com/sim0nsays/dlcourse_ai/blob/master/assignments/assignment2/PyTorch.ipynb 5/6
26.08.2021 dlcourse_ai/PyTorch.ipynb at master · sim0nsays/dlcourse_ai · GitHub
Returns:

np array of ints, (10,10), counts of samples for predicted/ground_truth classes

"""

confusion_matrix = np.zeros((10,10), np.int)

# TODO: Implement filling the prediction matrix

return np.array([[40, 2, 3], [10, 50,0], [0, 2, 80]])

confusion_matrix = build_confusion_matrix(predictions, gt)

visualize_confusion_matrix(confusion_matrix)

Наконец, посмотрим на изображения, соответствующие некоторым элементам этой матрицы.

Как и раньше, вам дана функция visualize_images, которой нужно воспрользоваться при реализации функции
visualize_predicted_actual. Эта функция должна вывести несколько примеров, соответствующих заданному элементу матрицы.

Визуализируйте наиболее частые ошибки и попробуйте понять, почему модель их совершает.

In [ ]: data_train_images = dset.SVHN('./data/', split='train')

def visualize_images(indices, data, title='', max_num=10):

"""

Visualizes several images from the dataset

indices: array of indices to visualize

data: torch Dataset with the images

title: string, title of the plot

max_num: int, max number of images to display

"""

to_show = min(len(indices), max_num)

fig = plt.figure(figsize=(10,1.5))

fig.suptitle(title)

for i, index in enumerate(indices[:to_show]):

plt.subplot(1,to_show, i+1)

plt.axis('off')

sample = data[index][0]

plt.imshow(sample)

def visualize_predicted_actual(predicted_class, gt_class, predictions, groud_truth, val_indices, data):

"""

Visualizes images of a ground truth class which were predicted as the other class

predicted: int 0-9, index of the predicted class

gt_class: int 0-9, index of the ground truth class

predictions: np array of ints, model predictions for all validation samples

ground_truth: np array of ints, ground truth for all validation samples

val_indices: np array of ints, indices of validation samples

"""

# TODO: Implement visualization using visualize_images above

# predictions and ground_truth are provided for validation set only, defined by val_indices

# Hint: numpy index arrays might be helpful

# https://docs.scipy.org/doc/numpy/user/basics.indexing.html#index-arrays

# Please make the title meaningful!

raise Exception("Not implemented")

visualize_predicted_actual(6, 8, predictions, gt, np.array(val_indices), data_train_images)

visualize_predicted_actual(1, 7, predictions, gt, np.array(val_indices), data_train_images)

https://github.com/sim0nsays/dlcourse_ai/blob/master/assignments/assignment2/PyTorch.ipynb 6/6

Вам также может понравиться