Trực quan hóa mô hình, dữ liệu và quá trình huấn luyện bằng TensorBoard

Chúng ta sẽ tìm hiểu cách sử dụng PyTorch kết hợp với TensorBoard để trực quan hóa kết quả hoạt động của mạng nơ-ron. Trong bài hướng dẫn này, chúng ta sẽ làm việc với bộ dữ liệu Fashion-MNIST và thực hiện các bước sau:

  • Đọc dữ liệu và áp dụng các phép biến đổi phù hợp.
  • Thiết lập TensorBoard.
  • Ghi thông tin vào TensorBoard.
  • Kiểm tra cấu trúc mô hình bằng TensorBoard.
  • Tạo phiên bản tương tác của quá trình huấn luyện với ít mã nguồn hơn.

Đầu tiên, chúng ta cần thiết lập môi trường và đọc dữ liệu:

# Nhập thư viện cần thiết
import matplotlib.pyplot as plt
import numpy as np

import torch
import torchvision
from torchvision import datasets, transforms
from torch import nn, optim

# Biến đổi dữ liệu
data_transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

# Đọc tập dữ liệu
train_data = datasets.FashionMNIST('./data', download=True, train=True, transform=data_transform)
test_data = datasets.FashionMNIST('./data', download=True, train=False, transform=data_transform)

# Tải dữ liệu
train_loader = torch.utils.data.DataLoader(train_data, batch_size=4, shuffle=True, num_workers=2)
test_loader = torch.utils.data.DataLoader(test_data, batch_size=4, shuffle=False, num_workers=2)

# Các lớp trong bộ dữ liệu
categories = ['Áo thun', 'Quần', 'Áo len', 'Váy', 'Áo khoác', 'Dép', 'Áo sơ mi', 'Giày thể thao', 'Túi xách', 'Giày bốt cổ ngắn']

# Hàm hiển thị ảnh đơn lẻ
def show_image(img, single_channel=False):
    if single_channel:
        img = img.mean(dim=0)
    img = img / 2 + 0.5
    np_img = img.numpy()
    if single_channel:
        plt.imshow(np_img, cmap='Greys')
    else:
        plt.imshow(np.transpose(np_img, (1, 2, 0)))

Tiếp theo, chúng ta định nghĩa kiến trúc của mô hình:

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv_layer_1 = nn.Conv2d(1, 6, 5)
        self.pool_layer = nn.MaxPool2d(2, 2)
        self.conv_layer_2 = nn.Conv2d(6, 16, 5)
        self.fc_layer_1 = nn.Linear(16 * 4 * 4, 120)
        self.fc_layer_2 = nn.Linear(120, 84)
        self.fc_layer_3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool_layer(torch.relu(self.conv_layer_1(x)))
        x = self.pool_layer(torch.relu(self.conv_layer_2(x)))
        x = x.view(-1, 16 * 4 * 4)
        x = torch.relu(self.fc_layer_1(x))
        x = torch.relu(self.fc_layer_2(x))
        x = self.fc_layer_3(x)
        return x

model = Model()

Sau đó, chúng ta xác định hàm mất mát và tối ưu hóa:

loss_function = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

Thiết lập TensorBoard:

from torch.utils.tensorboard import SummaryWriter

# Khởi tạo ghi chép cho TensorBoard
logger = SummaryWriter('runs/fashion_mnist_experiment')

Ghi một lưới ảnh vào TensorBoard:

# Lấy một số mẫu ngẫu nhiên từ dữ liệu huấn luyện
data_iterator = iter(train_loader)
samples, labels = data_iterator.next()

# Tạo lưới ảnh
image_grid = torchvision.utils.make_grid(samples)

# Hiển thị ảnh
show_image(image_grid, single_channel=True)

# Ghi ảnh vào TensorBoard
logger.add_image('Four Fashion-MNIST Images', image_grid)

Kiểm tra cấu trúc mô hình:

logger.add_graph(model, samples)
logger.close()

Thêm tính năng chiếu dữ liệu:

# Chọn ngẫu nhiên các điểm dữ liệu và nhãn
def select_random(data, targets, count=100):
    assert len(data) == len(targets)
    permutation = torch.randperm(len(data))
    return data[permutation][:count], targets[permutation][:count]

# Lấy các ảnh và nhãn ngẫu nhiên
random_images, random_labels = select_random(train_data.data, train_data.targets)

# Lấy tên các lớp tương ứng
category_names = [categories[label] for label in random_labels]

# Chuẩn bị dữ liệu đầu vào
features = random_images.view(-1, 28 * 28)

# Thêm dữ liệu chiếu vào TensorBoard
logger.add_embedding(features, metadata=category_names, label_img=random_images.unsqueeze(1))
logger.close()

Theo dõi quá trình huấn luyện:

# Hàm hỗ trợ
def probabilities_to_predictions(network, images):
    outputs = network(images)
    _, predictions = torch.max(outputs, 1)
    probs = [torch.softmax(el, dim=0)[i].item() for i, el in zip(predictions, outputs)]
    return predictions.numpy().squeeze(), probs

def visualize_predictions(network, images, labels):
    preds, probs = probabilities_to_predictions(network, images)
    figure = plt.figure(figsize=(12, 48))
    for index in range(4):
        subplot = figure.add_subplot(1, 4, index + 1, xticks=[], yticks=[])
        show_image(images[index], single_channel=True)
        subplot.set_title("{0}, {1:.1f}%\n(label: {2})".format(
            categories[preds[index]],
            probs[index] * 100,
            categories[labels[index]]),
            color=('green' if preds[index] == labels[index] else 'red'))
    return figure

total_loss = 0.0
for epoch in range(1):
    for step, (inputs, labels) in enumerate(train_loader, 0):
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = loss_function(outputs, labels)
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
        if step % 1000 == 999:
            logger.add_scalar('Training Loss', total_loss / 1000, epoch * len(train_loader) + step)
            logger.add_figure('Predictions vs Actuals', visualize_predictions(model, inputs, labels), global_step=epoch * len(train_loader) + step)
            total_loss = 0.0
print('Huấn luyện hoàn tất')

Cuối cùng, đánh giá hiệu suất mô hình:

# Dự đoán xác suất và nhãn
predictions_probabilities = []
predicted_labels = []

with torch.no_grad():
    for data in test_loader:
        images, labels = data
        outputs = model(images)
        predictions_probabilities.extend([torch.softmax(el, dim=0) for el in outputs])
        predicted_labels.append(labels)

test_probs = torch.cat([torch.stack(batch) for batch in predictions_probabilities])
test_labels = torch.cat(predicted_labels)

# Vẽ đường cong Precision-Recall
def plot_pr_curve(class_index, test_probs, test_labels, global_step=0):
    truth_values = test_labels == class_index
    probabilities = test_probs[:, class_index]
    logger.add_pr_curve(categories[class_index], truth_values, probabilities, global_step=global_step)
    logger.close()

for idx in range(len(categories)):
    plot_pr_curve(idx, test_probs, test_labels)

Thẻ: PyTorch TensorBoard Fashion-MNIST

Đăng vào ngày 4 tháng 7 lúc 20:58