پایتورچ (PyTorch) یکی از کتابخانههای محبوب و قدرتمند در زمینه یادگیری عمیق است که توسط فیسبوک توسعه پیدا کرده است. این کتابخانه به دلیل سادگی در استفاده، انعطافپذیری بالا و قابلیتهای پیشرفته، به سرعت در میان محققان و توسعهدهندگان محبوبیت پیدا کرده است. در این مقاله، به بررسی نحوه استفاده از PyTorch برای ساخت و آموزش شبکههای عصبی میپردازیم. هدف این مقاله ارائه یک راهنمای جامع و کاربردی برای افرادی است که میخواهند با استفاده از PyTorch شبکههای عصبی خود را پیادهسازی و آموزش دهند.
نصب و راهاندازی PyTorch
برای شروع کار با PyTorch، ابتدا باید این کتابخانه را نصب کنید. PyTorch از طریق pip و conda قابل نصب است. برای نصب با استفاده از pip، میتوانید از دستور زیر استفاده کنید
pip install torch torchvision torchaudio
و برای نصب با استفاده از conda میتوانید از دستور زیر استفاده کنید :
conda install pytorch torchvision torchaudio -c pytorch
پس از نصب PyTorch، میتوانید با وارد کردن کتابخانه در محیط پایتون خود، از آن استفاده کنید:
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
ساختار پایه شبکههای عصبی در PyTorch
شبکههای عصبی در PyTorch به صورت کلاسهایی تعریف میشوند که از کلاس پایه nn.Module
الهام میگیرد.
این کلاسها، لایههای شبکه و عملیات پیشرو (forward) تعریف میشوند. در ادامه به یک مثال ساده از یک شبکه عصبی چند لایه (MLP) میپردازیم :
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(784, 128)
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 10)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
در مثال بالا، یک شبکه عصبی با سه لایه تماممتصل (fully connected) تعریف کردیم. لایه اول 784 ورودی و 128 خروجی دارد، لایه دوم 128 ورودی و 64 خروجی دارد و لایه سوم 64 ورودی و 10 خروجی دارد. در تابع forward
، از تابع فعالسازی ReLU برای لایههای اول و دوم استفاده کردهایم.
آمادهسازی دادهها
برای آموزش یک شبکه عصبی، ابتدا باید دادهها را آماده کنیم. PyTorch ابزارهای متعددی برای بارگذاری و پردازش دادهها ارائه میدهد. یکی از این ابزارها DataLoader
است که برای بارگذاری دادهها به صورت دستهای (batch) استفاده میشود. در ادامه مثالی از بارگذاری دادههای مجموعه MNIST را آورده ایم:
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
در این مثال، دادههای مجموعه MNIST را با استفاده از torchvision.datasets.MNIST
بارگذاری کردهایم و با استفاده از transforms
به تنسور تبدیل و نرمالسازی شده است. سپس این دادهها با استفاده از DataLoader
به صورت دستهای بارگذاری شده است.
تعریف تابع هزینه و بهینهساز
پس از تعریف شبکه عصبی و آمادهسازی دادهها، باید تابع هزینه (loss function) و بهینهساز (optimizer) را تعریف کنیم. PyTorch توابع هزینه و بهینهسازهای متعددی ارائه میدهد. در ادامه مثالی از تعریف تابع هزینه CrossEntropyLoss و بهینهساز Adam آورده ایم :
criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(net.parameters(), lr=0.001)
آموزش شبکه عصبی
برای آموزش شبکه عصبی، باید دادههای آموزشی را به شبکه وارد کرده و تابع هزینه را محاسبه کنیم. سپس با استفاده از بهینهساز، وزنهای شبکه را بهروزرسانی کنیم. در ادامه به مثالی از حلقه آموزش میپردازیم :
for epoch in range(10): # تعداد دورههای آموزشی
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad() # صفر کردن گرادیانها
outputs = net(inputs) # پیشبینی شبکه
loss = criterion(outputs, labels) # محاسبه هزینه
loss.backward() # محاسبه گرادیانها
optimizer.step() # بهروزرسانی وزنها
running_loss += loss.item()
if i % 100 == 99: # چاپ هر 100 دسته
print(f'[Epoch {epoch + 1}, Batch {i + 1}] loss: {running_loss / 100:.3f}')
running_loss = 0.0
print('Finished Training')
ارزیابی شبکه عصبی
پس از آموزش شبکه عصبی، باید عملکرد آن را بر روی دادههای تست ارزیابی کنید. در ادامه مثالی از ارزیابی شبکه آورده ایم:
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')
شبکههای عصبی پیچیدهتر
در این بخش، به بررسی شبکههای عصبی پیچیدهتر مانند شبکههای عصبی کانولوشنی (CNN) و شبکههای عصبی بازگشتی (RNN) میپردازیم.
شبکههای عصبی کانولوشنی (CNN)
شبکههای عصبی کانولوشنی برای پردازش دادههای تصویری بسیار مناسب هستند. این شبکهها از لایههای کانولوشنی برای استخراج ویژگیهای محلی از تصاویر استفاده میکنند. در ادامه، به نحوه ساخت یک شبکه عصبی کانولوشنی ساده با PyTorch میپردازیم:
import torch.nn.functional as F
# تعریف کلاس شبکه عصبی کانولوشنی
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3)
self.fc1 = nn.Linear(64*6*6, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.relu(self.conv2(x))
x = F.max_pool2d(x, 2)
x = x.view(-1, 64*6*6)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
# ایجاد یک نمونه از شبکه عصبی کانولوشنی
model = SimpleCNN()
print(model)
شبکههای عصبی بازگشتی (RNN)
شبکههای عصبی بازگشتی برای پردازش دادههای ترتیبی مانند متن و سیگنالهای زمانی مناسب هستند. این شبکهها از لایههای بازگشتی برای حفظ اطلاعات ترتیبی استفاده میکنند. در ادامه، نحوه ساخت یک شبکه عصبی بازگشتی ساده با PyTorch آورده ایم:
# تعریف کلاس شبکه عصبی بازگشتی
class SimpleRNN(nn.Module):
def __init__(self):
super(SimpleRNN, self).__init__()
self.rnn = nn.RNN(input_size=10, hidden_size=20, num_layers=2, batch_first=True)
self.fc = nn.Linear(20, 1)
def forward(self, x):
h0 = torch.zeros(2, x.size(0), 20)
out, _ = self.rnn(x, h0)
out = self.fc(out[:, -1, :])
return out
# ایجاد یک نمونه از شبکه عصبی بازگشتی
model = SimpleRNN()
print(model)
کار با Dataset و DataLoader
یکی از ویژگیهای مهم PyTorch، امکانات گستردهای است که برای کار با دادهها فراهم میکند. PyTorch دارای کلاسهای Dataset
و DataLoader
است که به کاربران این امکان را میدهد که به راحتی دادهها را بارگذاری و پردازش کنند.
تعریف Dataset سفارشی
برای تعریف یک Dataset سفارشی، باید کلاس خود را از کلاس Dataset
PyTorch ارثبری کنیم و متدهای __len__
و __getitem__
را پیادهسازی کنیم. در ادامه، یک مثال از تعریف Dataset سفارشی آورده ایم:
from torch.utils.data import Dataset
class CustomDataset(Dataset):
def __init__(self, data, labels):
self.data = data
self.labels = labels
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
return self.data[idx], self.labels[idx]
# ایجاد یک نمونه از Dataset سفارشی
data = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
labels = torch.tensor([[0.0], [1.0], [1.0], [0.0]])
dataset = CustomDataset(data, labels)
print(len(dataset))
print(dataset[0])
استفاده از DataLoader
پس از تعریف Dataset، میتوانیم از کلاس DataLoader
برای بارگذاری دادهها استفاده کنیم. DataLoader امکاناتی مانند batching، shuffling و parallel loading را فراهم میکند. در ادامه، نحوه استفاده از DataLoader آورده ایم:
from torch.utils.data import DataLoader
# ایجاد DataLoader
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
# پیمایش دادهها با استفاده از DataLoader
for batch in dataloader:
data, labels = batch
print(data, labels)
نتیجهگیری
در این مقاله، به بررسی نحوه استفاده از PyTorch برای ساخت و آموزش شبکههای عصبی پرداختیم. از نصب و راهاندازی PyTorch شروع کردیم و سپس به تعریف شبکه عصبی، آمادهسازی دادهها، تعریف تابع هزینه و بهینهساز، آموزش شبکه و ارزیابی آن پرداختیم. PyTorch با ارائه ابزارهای قدرتمند و انعطافپذیر، فرآیند ساخت و آموزش شبکههای عصبی را ساده و کارآمد میکند. امیدواریم این مقاله برای شما مفید بوده باشد و بتوانید با استفاده از PyTorch شبکههای عصبی خود را پیادهسازی و آموزش دهید.