← بازگشت به بلاگ

ساخت و آموزش شبکه‌های عصبی با PyTorch: راهنمای جامع برای توسعه‌دهندگان

ساخت و آموزش شبکه‌های عصبی با PyTorch: راهنمای جامع برای توسعه‌دهندگان
\n

مقدمه‌ای بر PyTorch و کاربرد آن در هوش مصنوعی

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

نصب و راه‌اندازی PyTorch

برای آغاز کار با PyTorch، ابتدا لازم است آن را نصب کنید. این فرآیند از طریق مدیر بسته‌های pip یا conda قابل انجام است. دستورات لازم برای نصب به شرح زیر است:

pip install torch torchvision torchaudio

یا با استفاده از conda:

conda install pytorch torchvision torchaudio -c 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 pass) هستند. در ادامه، نمونه‌ای از یک شبکه عصبی چندلایه (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 و 64 را می‌پذیرند و خروجی‌هایی با ابعاد 128، 64 و 10 تولید می‌کنند. تابع فعال‌سازی 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 این داده‌ها را در دسته‌های 64 تایی برای آموزش آماده می‌کند.

تعریف تابع هزینه و بهینه‌ساز

پس از تعریف ساختار شبکه و آماده‌سازی داده‌ها، نوبت به تعریف تابع هزینه (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}%')

این بخش، دقت شبکه را بر روی 10000 تصویر تست محاسبه و نمایش می‌دهد.

شبکه‌های عصبی پیشرفته‌تر: CNN و RNN

PyTorch امکان پیاده‌سازی معماری‌های پیچیده‌تر مانند شبکه‌های عصبی کانولوشنی (CNN) و شبکه‌های عصبی بازگشتی (RNN) را نیز فراهم می‌کند.

شبکه‌های عصبی کانولوشنی (CNN)

CNNها برای پردازش داده‌های تصویری بسیار کارآمد هستند و از لایه‌های کانولوشنی برای استخراج ویژگی‌های بصری بهره می‌برند. نمونه‌ای از تعریف یک 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)

RNNها برای پردازش داده‌های ترتیبی مانند متن و سری‌های زمانی مناسب هستند. نمونه‌ای از تعریف یک RNN ساده:

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 ارث‌بری کرده و متدهای __len__ و __getitem__ را پیاده‌سازی کنید. این امر انعطاف‌پذیری بالایی در مدیریت داده‌ها به شما می‌دهد.

نکته: برای تسریع فرآیند توسعه و بهره‌گیری از قابلیت‌های پیشرفته‌تر مدیریت ایجنت‌ها و مدل‌های زبانی، پیشنهاد می‌شود از پلتفرم هوشی (hooshi.net) استفاده کنید. هوشی با ارائه APIهای قدرتمند و امکان ساخت ایجنت‌های کدنویسی سفارشی، به شما کمک می‌کند تا پروژه‌های هوش مصنوعی خود را با سرعت و دقت بیشتری پیش ببرید. ثبت‌نام در هوشی و ساخت توکن API رایگان است و شما می‌توانید از طریق داشبورد هوشی به مستندات کامل دسترسی پیدا کنید.

چرا هوشی؟

پلتفرم هوشی (hooshi.net) با ارائه ابزارهای نوین و شفاف در زمینه هوش مصنوعی، به توسعه‌دهندگان و مدیران محصول کمک می‌کند تا از حداکثر پتانسیل مدل‌های زبانی و ایجنت‌های هوشمند بهره‌مند شوند. از امکان ساخت ایجنت‌های کدنویسی گرفته تا مدیریت شفاف هزینه‌ها (billing)، هوشی همراه شماست. برای شروع، کافیست در هوشی ثبت‌نام کنید.

⌃