برنامه نویسی

ردیابی آزمایشی و تنظیم فراپارامتر با TensorBoard در PyTorch 🔥

تصویر روی جلد

معرفی

ردیابی آزمایش‌ها و تنظیم فراپارامترها با TensorBoard در PyTorch

ردیابی آزمایشی شامل ثبت و نظارت بر داده های آزمایش یادگیری ماشینی است و TensorBoard ابزار مفیدی برای تجسم و تجزیه و تحلیل این داده ها است. این به محققان کمک می کند تا رفتار آزمایش را درک کنند، مدل ها را مقایسه کنند و تصمیمات آگاهانه بگیرند.

تنظیم فراپارامتر فرآیند یافتن بهترین مقادیر برای تنظیمات پیکربندی است که بر یادگیری مدل تأثیر می گذارد. به عنوان مثال می توان به نرخ یادگیری، اندازه دسته ای و تعداد لایه های پنهان اشاره کرد. تنظیم مناسب عملکرد و تعمیم مدل را بهبود می بخشد.

استراتژی های تنظیم فراپارامتر شامل جستجوی دستی، جستجوی شبکه ای، جستجوی تصادفی، بهینه سازی بیزی و تکنیک های خودکار است. این روش ها به طور سیستماتیک مقادیر فراپارامترهای مختلف را بررسی و ارزیابی می کنند.

می توانید عملکرد مدل را در طول تنظیم با استفاده از معیارهای ارزیابی مانند دقت یا میانگین مربعات خطا ارزیابی کنید. تنظیم موثر فراپارامتر منجر به بهبود نتایج مدل در داده‌های دیده نشده می‌شود.

در این وبلاگ شاهد تنظیم هایپرپارامتر با استفاده از آن خواهیم بود جستجوی شبکه ای با مجموعه داده FashionMNIST و یک مدل VGG سفارشی. منتظر وبلاگ های آینده در سایر الگوریتم های تنظیم باشید.

شروع کنیم!

در کولب باز کنید


Dependencies را نصب و وارد کنید

با باز کردن یک نوت بوک جدید پایتون در Jupyter یا Google Colab شروع کنید. برای نصب و وارد کردن وابستگی ها، این دستورات را در بلوک کد بنویسید.

%pip install -q torchinfo torchmetrics tensorboard

import torch
import torchvision
import os
from torchvision.transforms import Resize, Compose, ToTensor
import matplotlib.pyplot as plt
from torchinfo import summary
import torchmetrics
from tqdm.auto import tqdm
from torch.utils.tensorboard import SummaryWriter

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


Dataset و DataLoader را بارگذاری کنید

BATCH_SIZE = 64

if not os.path.exists("data"): os.mkdir("data")

train_transform = Compose([Resize((64,64)),
                           ToTensor()
                           ])
test_transform = Compose([Resize((64,64)),
                          ToTensor()
                          ])

training_dataset = torchvision.datasets.FashionMNIST(root = "data",
                                                     download = True,
                                                     train = True,
                                                     transform = train_transform)

test_dataset = torchvision.datasets.FashionMNIST(root = "data",
                                                 download = True,
                                                 train = False,
                                                 transform = test_transform)

train_dataloader = torch.utils.data.DataLoader(training_dataset,
                                          batch_size=BATCH_SIZE,
                                          shuffle=True,
                                          )

test_dataloader = torch.utils.data.DataLoader(test_dataset,
                                              batch_size = BATCH_SIZE,
                                              shuffle = False,
                                              )
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • در اینجا، ما یک اندازه دسته ای 64 را شروع می کنیم. به طور کلی، شما می خواهید حداکثر اندازه دسته ای را انتخاب کنید که GPU شما می تواند بدون ارائه cuda out of memory خطا
  • ما تبدیل ها را برای تبدیل تصاویر خود به Tensor تعریف می کنیم.
  • ما مجموعه داده‌های آموزشی و مجموعه داده‌های آزمایشی را از مجموعه داده‌های داخلی FashionMNIST در مجموعه داده‌های Torchvision آغاز می‌کنیم. را تنظیم کردیم root پوشه به عنوان data پوشه، download مانند True زیرا می خواهیم مجموعه داده و train مانند True برای داده های آموزشی و False برای داده های تست
  • در مرحله بعد، دیتالودرهای آموزشی و آزمایشی را تعریف می کنیم.

با استفاده از این دستور می توانیم ببینیم که چه تعداد تصویر در مجموعه داده های آموزشی و آزمایشی خود داریم.

print(f"Number of Images in test dataset is {len(test_dataset)}")
print(f"Number of Images in training dataset is {len(training_dataset)}")
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

[!output]تعداد تصاویر در مجموعه داده آزمایشی 10000 است
تعداد تصاویر در مجموعه داده آموزشی 60000 است


یک مدل TinyVGG ایجاد کنید

من ردیابی آزمایشی را با استفاده از این مدل سفارشی نشان می‌دهم. اما شما می توانید از هر مدل دلخواه خود استفاده کنید.

class TinyVGG(nn.Module):
    """
    A small VGG-like network for image classification.

    Args:
        in_channels (int): The number of input channels.
        n_classes (int): The number of output classes.
        hidden_units (int): The number of hidden units in each convolutional block.
        n_conv_blocks (int): The number of convolutional blocks.
        dropout (float): The dropout rate.
    """

    def __init__(self, in_channels, n_classes, hidden_units, n_conv_blocks, dropout):
        super().__init__()
        self.in_channels = in_channels
        self.out_features = n_classes
        self.dropout = dropout
        self.hidden_units = hidden_units

        # Input block
        self.input_block = nn.Sequential(
            nn.Conv2d(in_channels=in_channels, out_channels=hidden_units, kernel_size=3, padding=0, stride=1),
            nn.Dropout(dropout),
            nn.ReLU(),
        )

        # Convolutional blocks
        self.conv_blocks = nn.ModuleList([
            nn.Sequential(
                nn.Conv2d(in_channels=hidden_units, out_channels=hidden_units, kernel_size=3, padding=0, stride=1),
                nn.Dropout(dropout),
                nn.ReLU(),
                nn.MaxPool2d(kernel_size=2, stride=2),
            ) for _ in range(n_conv_blocks)
        ])

        # Classifier
        self.classifier = nn.Sequential(
            nn.Flatten(),
            nn.LazyLinear(out_features=256),
            nn.Dropout(dropout),
            nn.Linear(in_features=256, out_features=64),
            nn.Linear(in_features=64, out_features=n_classes),
        )

    def forward(self, x):
        """
        Forward pass of the network.

        Args:
            x (torch.Tensor): The input tensor.

        Returns:
            torch.Tensor: The output tensor.
        """

        x = self.input_block(x)
        for conv_block in self.conv_blocks:
            x = conv_block(x)
        x = self.classifier(x)
        return x
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


توابع آموزش و آزمون را تعریف کنید


def train_step(dataloader, model, optimizer, criterion, device, train_acc_metric):
    """
    Perform a single training step.

    Args:
        dataloader (torch.utils.data.DataLoader): The dataloader for the training data.
        model (torch.nn.Module): The model to train.
        optimizer (torch.optim.Optimizer): The optimizer for the model.
        criterion (torch.nn.Module): The loss function for the model.
        device (torch.device): The device to train the model on.
        train_acc_metric (torchmetrics.Accuracy): The accuracy metric for the model.

    Returns:
        The accuracy of the model on the training data.
    """

    for (X, y) in tqdm.tqdm(dataloader):
        # Move the data to the device.
        X = X.to(device)
        y = y.to(device)

        # Forward pass.
        y_preds = model(X)

        # Calculate the loss.
        loss = criterion(y_preds, y)

        # Calculate the accuracy.
        train_acc_metric.update(y_preds, y)

        # Backpropagate the loss.
        loss.backward()

        # Update the parameters.
        optimizer.step()

        # Zero the gradients.
        optimizer.zero_grad()

    return train_acc_metric.compute()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

def test_step(dataloader, model, device, test_acc_metric):
    """
    Perform a single test step.

    Args:
        dataloader (torch.utils.data.DataLoader): The dataloader for the test data.
        model (torch.nn.Module): The model to test.
        device (torch.device): The device to test the model on.
        test_acc_metric (torchmetrics.Accuracy): The accuracy metric for the model.

    Returns:
        The accuracy of the model on the test data.
    """

    for (X, y) in tqdm.tqdm(dataloader):
        # Move the data to the device.
        X = X.to(device)
        y = y.to(device)

        # Forward pass.
        y_preds = model(X)

        # Calculate the accuracy.
        test_acc_metric.update(y_preds, y)

    return test_acc_metric.compute()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


خلاصه نویس TensorBoard

def create_writer(
    experiment_name: str, model_name: str, conv_layers, dropout, hidden_units
) -> SummaryWriter:
    """
    Create a SummaryWriter object for logging the training and test results.

    Args:
        experiment_name (str): The name of the experiment.
        model_name (str): The name of the model.
        conv_layers (int): The number of convolutional layers in the model.
        dropout (float): The dropout rate used in the model.
        hidden_units (int): The number of hidden units in the model.

    Returns:
        SummaryWriter: The SummaryWriter object.
    """

    timestamp = str(datetime.now().strftime("%d-%m-%Y_%H-%M-%S"))
    log_dir = os.path.join(
        "runs",
        timestamp,
        experiment_name,
        model_name,
        f"{conv_layers}",
        f"{dropout}",
        f"{hidden_units}",
    ).replace("\\", "https://dev.to/")
    return SummaryWriter(log_dir=log_dir)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


تنظیم بیش از حد پارامتر

همانطور که می بینید، چندین ابرپارامتر وجود دارد – نرخ یادگیری، تعداد دوره ها، نوع بهینه ساز، تعداد لایه های پیچیدگی، حذف و تعداد واحدهای پنهان. ابتدا می‌توانیم نرخ یادگیری و تعداد دوره‌ها را اصلاح کنیم و سعی کنیم بهترین تعداد لایه‌های کانولوشن، حذف و واحدهای پنهان را پیدا کنیم. وقتی آن ها را داشتیم، می توانیم تعداد دوره ها و میزان یادگیری را تنظیم کنیم.

# Fixed Hyper Parameters/
EPOCHS = 10
LEARNING_RATE = 0.0007
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

"""
This code performs hyperparameter tuning for a TinyVGG model.

The hyperparameters that are tuned are the number of convolutional layers, the dropout rate, and the number of hidden units.

The results of the hyperparameter tuning are logged to a TensorBoard file.
"""

experiment_number = 0

# hyperparameters to tune
hparams_config = {
    "n_conv_layers": [1, 2, 3],
    "dropout": [0.0, 0.25, 0.5],
    "hidden_units": [128, 256, 512],
}

for n_conv_layers in hparams_config["n_conv_layers"]:
    for dropout in hparams_config["dropout"]:
        for hidden_units in hparams_config["hidden_units"]:
            experiment_number += 1
            print(
                f"\nTuning Hyper Parameters || Conv Layers: {n_conv_layers} || Dropout: {dropout} || Hidden Units: {hidden_units} \n"
            )

            # create the model
            model = TinyVGG(
                in_channels=1,
                n_classes=len(training_dataset.classes),
                hidden_units=hidden_units,
                n_conv_blocks=n_conv_layers,
                dropout=dropout,
            ).to(device)

            # create the optimizer and loss function
            optimizer = torch.optim.Adam(params=model.parameters(), lr=LEARNING_RATE)
            criterion = torch.nn.CrossEntropyLoss()

            # create the accuracy metrics
            train_acc_metric = torchmetrics.Accuracy(
                task="multiclass", num_classes=len(training_dataset.classes)
            ).to(device)
            test_acc_metric = torchmetrics.Accuracy(
                task="multiclass", num_classes=len(training_dataset.classes)
            ).to(device)

            # create the TensorBoard writer
            writer = create_writer(
                experiment_name=f"{experiment_number}",
                model_name="tiny_vgg",
                conv_layers=n_conv_layers,
                dropout=dropout,
                hidden_units=hidden_units,
            )
            model.train()
            # train the model
            for epoch in range(EPOCHS):
                train_step(
                    train_dataloader,
                    model,
                    optimizer,
                    criterion,
                    device,
                    train_acc_metric,
                )
                test_step(test_dataloader, model, device, test_acc_metric)
                writer.add_scalar(
                    tag="Training Accuracy",
                    scalar_value=train_acc_metric.compute(),
                    global_step=epoch,
                )
                writer.add_scalar(
                    tag="Test Accuracy",
                    scalar_value=test_acc_metric.compute(),
                    global_step=epoch,
                )

            # add the hyperparameters and metrics to TensorBoard
            writer.add_hparams(
                {
                    "conv_layers": n_conv_layers,
                    "dropout": dropout,
                    "hidden_units": hidden_units,
                },
                {
                    "train_acc": train_acc_metric.compute(),
                    "test_acc": test_acc_metric.compute(),
                },
            )
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بسته به سخت افزار شما مدتی طول می کشد تا اجرا شود.


نتایج را در TensorBoard بررسی کنید

اگر از Google Colab یا Jupyter Notebook استفاده می کنید، با این دستور می توانید داشبورد TensorBoard را مشاهده کنید.

%load_ext tensorboard
%tensorboard --logdir=runs
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نمای مختصات موازی

نمای Hyper Parameters

از این، اکنون می توانید بهترین هایپرپارامترها را پیدا کنید.

خودشه. به این ترتیب می توانید از TensorBoard برای تنظیم هایپرپارامترها استفاده کنید. در اینجا، ما از جستجوی شبکه برای سادگی استفاده کردیم، اما می‌توانید از روش مشابهی برای سایر الگوریتم‌های تنظیم استفاده کنید و از TensorBoard برای مشاهده نحوه عملکرد این الگوریتم‌ها در زمان واقعی استفاده کنید.

در کولب باز کنید


می خواهید وصل شوید؟

🌍وب سایت من

🐦توییتر من

👨لینکدین من

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا