Naver boostcamp -ai tech/week 02
TensorBoard
끵뀐꿩긘
2022. 10. 1. 15:12
https://tutorials.pytorch.kr/recipes/recipes/tensorboard_with_pytorch.html
PyTorch로 TensorBoard 사용하기
TensorBoard는 머신러닝 실험을 위한 시각화 툴킷(toolkit)입니다. TensorBoard를 사용하면 손실 및 정확도와 같은 측정 항목을 추적 및 시각화하는 것, 모델 그래프를 시각화하는 것, 히스토그램을 보는
tutorials.pytorch.kr
설치
$ pip install torch torchvision
$ pip install tensorboard
PyTorch로 TensorBoard 사용하기
import torch
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter() # SummaryWriter객체 생성
writer는 기본적으로 ./runs/ 디렉토리에 출력된다
스칼라 기록하기
x = torch.arange(-5, 5, 0.1).view(-1, 1)
y = -5 * x + 0.1 * torch.randn(x.size())
model = torch.nn.Linear(1, 1) # 선형 모델
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr = 0.1)
def train_model(iter):
for epoch in range(iter):
y1 = model(x)
loss = criterion(y1, y)
writer.add_scalar("Loss/train", loss, epoch) # add_scalar로 loss와 epoch를 기록
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_model(10)
writer.flush() # 실제 disk에 파일을 쓴다
writer.close() # 필요가 없어지면 writer를 닫는다
%load_ext tensorboard # 텐서보드 코랩에서 띄우는 매직명령어
%tensorboard --logdir=runs # 텐서보드 실행
https://tutorials.pytorch.kr/intermediate/tensorboard_tutorial.html
TensorBoard로 모델, 데이터, 학습 시각화하기
PyTorch로 딥러닝하기: 60분만에 끝장내기 에서는 데이터를 불러오고, nn.Module 의 서브클래스(subclass)로 정의한 모델에 데이터를 공급(feed)하고, 학습 데이터로 모델을 학습하고 테스트 데이터로 테
tutorials.pytorch.kr
# 기본 설정
# imports
import matplotlib.pyplot as plt
import numpy as np
import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# transforms
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))])
# datasets
trainset = torchvision.datasets.FashionMNIST('./data',
download=True,
train=True,
transform=transform)
testset = torchvision.datasets.FashionMNIST('./data',
download=True,
train=False,
transform=transform)
# dataloaders
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
shuffle=True, num_workers=2)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
shuffle=False, num_workers=2)
# 분류 결과를 위한 상수
classes = ('T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle Boot')
# 이미지를 보여주기 위한 헬퍼(helper) 함수
# (아래 `plot_classes_preds` 함수에서 사용)
def matplotlib_imshow(img, one_channel=False):
if one_channel:
img = img.mean(dim=0)
img = img / 2 + 0.5 # unnormalize
npimg = img.numpy()
if one_channel:
plt.imshow(npimg, cmap="Greys")
else:
plt.imshow(np.transpose(npimg, (1, 2, 0)))
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 4 * 4, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 4 * 4)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
TensorBoard 설정
from torch.utils.tensorboard import SummaryWriter
# 기본 `log_dir` 은 "runs"이며, 여기서는 더 구체적으로 지정하였습니다
writer = SummaryWriter('runs/fashion_mnist_experiment_1') # writer 객체 생성
tensorboard --logdir=runs # 텐서보드 실행
TensorBoard에 기록하기
- 이미지 기록하기
# 임의의 학습 이미지를 가져옵니다
dataiter = iter(trainloader)
images, labels = dataiter.next()
# 이미지 그리드를 만듭니다.
img_grid = torchvision.utils.make_grid(images)
# 이미지를 보여줍니다.
matplotlib_imshow(img_grid, one_channel=True)
# tensorboard에 기록합니다.
writer.add_image('four_fashion_mnist_images', img_grid)
TensorBoard를 사용하여 모델 살펴보기
텐서보드에 graph를 넣어서 모델을 시각화할 수 있다
writer.add_graph(net, images)
writer.close()
TensorBoard로 모델 학습 추적
기본설정
def images_to_probs(net, images):
'''
학습된 신경망과 이미지 목록으로부터 예측 결과 및 확률을 생성합니다
'''
output = net(images)
# convert output probabilities to predicted class
_, preds_tensor = torch.max(output, 1) # max 값, max_idx를 반환하므로 max_idx만 가져옴
preds = np.squeeze(preds_tensor.numpy())
return preds, [F.softmax(el, dim=0)[i].item() for i, el in zip(preds, output)] # 클래스와 확률 반환
def plot_classes_preds(net, images, labels):
'''
학습된 신경망과 배치로부터 가져온 이미지 / 라벨을 사용하여 matplotlib
Figure를 생성합니다. 이는 신경망의 예측 결과 / 확률과 함께 정답을 보여주며,
예측 결과가 맞았는지 여부에 따라 색을 다르게 표시합니다. "images_to_probs"
함수를 사용합니다.
'''
preds, probs = images_to_probs(net, images)
# 배치에서 이미지를 가져와 예측 결과 / 정답과 함께 표시(plot)합니다
fig = plt.figure(figsize=(12, 48))
for idx in np.arange(4):
ax = fig.add_subplot(1, 4, idx+1, xticks=[], yticks=[])
matplotlib_imshow(images[idx], one_channel=True)
ax.set_title("{0}, {1:.1f}%\n(label: {2})".format(
classes[preds[idx]],
probs[idx] * 100.0,
classes[labels[idx]]),
color=("green" if preds[idx]==labels[idx].item() else "red"))
return fig
모델 훈련 + loss값 기록 & 그때의 배치 이미지 확률 실제 레이블 표현
running_loss = 0.0
for epoch in range(1): # 데이터셋을 여러번 반복
for i, data in enumerate(trainloader, 0):
# [inputs, labels]의 목록인 data로부터 입력을 받은 후;
inputs, labels = data
# 변화도(Gradient) 매개변수를 0으로 만들고
optimizer.zero_grad()
# 순전파 + 역전파 + 최적화를 한 후
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 1000 == 999: # 매 1000 미니배치마다...
# ...학습 중 손실(running loss)을 기록하고
writer.add_scalar('training loss',
running_loss / 1000,
epoch * len(trainloader) + i)
# ...무작위 미니배치(mini-batch)에 대한 모델의 예측 결과를 보여주도록
# Matplotlib Figure를 기록합니다 = add.figure
writer.add_figure('predictions vs. actuals',
plot_classes_preds(net, inputs, labels),
global_step=epoch * len(trainloader) + i)
running_loss = 0.0
print('Finished Training')
TensorBoard로 학습된 모델 평가하기
# 1. 예측 확률을 test_size x num_classes 텐서로 가져옵니다
# 2. 예측 결과를 test_size 텐서로 가져옵니다
# 실행하는데 10초 이하 소요
class_probs = []
class_label = []
with torch.no_grad(): # eval 모드이므로 가중치 업데이트 x
for data in testloader:
images, labels = data
output = net(images)
class_probs_batch = [F.softmax(el, dim=0) for el in output] # 클래스별 확률
class_probs.append(class_probs_batch) # 확률
class_label.append(labels) # 정답값
test_probs = torch.cat([torch.stack(batch) for batch in class_probs])
test_label = torch.cat(class_label)
# 헬퍼 함수
def add_pr_curve_tensorboard(class_index, test_probs, test_label, global_step=0):
'''
0부터 9까지의 "class_index"를 가져온 후 해당 정밀도-재현율(precision-recall)
곡선을 그립니다
'''
tensorboard_truth = test_label == class_index
tensorboard_probs = test_probs[:, class_index]
writer.add_pr_curve(classes[class_index],
tensorboard_truth,
tensorboard_probs,
global_step=global_step)
writer.close()
# 모든 정밀도-재현율(precision-recall; pr) 곡선을 그립니다
for i in range(len(classes)):
add_pr_curve_tensorboard(i, test_probs, test_label)
각 class에 대해서 pr_curve를 그려준다
W and B도 나중에 도전해봐야겠다