
شناسایی دست خط با رگرسیون لجستیک در پایتون
شناسایی دست خط با رگرسیون لجستیک در پایتون
در این مطلب، روش شناسایی دست خط با رگرسیون لجستیک در پایتون مورد بررسی قرار گرفته است. «رگرسیون لجستیک» (Logistic Regression) یکی از روشهای آماری متداول است که امکان پیشبینی یک خروجی دودویی را از یک مجموعه از متغیرهای مستقل فراهم میکند. خصوصیات مختلف رگرسیون لجستیک و پیادهسازی «پایتون» (Python Programming Language) آن، پیش از این در مطالب دیگری به طور کامل تشریح شد. در این مطلب، به چگونگی پیادهسازی الگوریتم رگرسیون لجستیک در پایتون و با استفاده از کتابخانه PyTorch پرداخته شده است. اکنون، چگونگی دستهبندی ارقام دستنویس در مجموعه داده MNIST با استفاده از الگوریتم رگرسیون لجستیک در کتابخانه Pythorch پایتون آموزش داده شده است. در واقع، در اینجا یک مسئله شناسایی دست خط بررسی و تحلیل شده است.
شناسایی دست خط با رگرسیون لجستیک در پایتون
در این راستا، ابتدا نیاز به نصب Pytorch است. سادهترین راه برای انجام این کار، استفاده از pip یا «کوندا» (Conda) است. کاربران باید برای نصب نسخه مفسر پایتون و مدیر بستهای که قصد استفاده از آن را دارند، به وبسایت پایتورچ مراجعه کنند. پس از نصب پایتورچ، بررسی روی کد انجام میشود. سه خط کدی که در ادامه آورده شده است، برای وارد کردن توابع و اشیای کتابخانهای مورد نیاز استفاده میشود.
[php]import torch
import torch.nn as nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.autograd import Variable
[/php]در اینجا، ماژول torch.nn حاوی کد لازم برای مدل است، torchvision.datasets حاوی مجموعه داده MNIST است. این ماژول، حاوی کتابخانه ارقام دستنویس است که در اینجا مورد استفاده قرار گرفته است. ماژول torchvision.transforms حاوی متدهای متعددی برای تبدیل اشیا به اشیای دیگر است. در اینجا، از این ماژول برای تبدیل تصاویر به تانسورهای PyTorch استفاده شده است. همچنین، ماژول orch.autograd حاوی کلاس Variable است که هنگام تعریف «تانسورها» (Tensors) مورد استفاده قرار میگیرد. در ادامه، باید مجموعه داده در حافظه دانلود و بارگذاری شود.
[php]# MNIST Dataset (Images and Labels)
train_dataset = dsets.MNIST(root =’./data’,
train = True,
transform = transforms.ToTensor(),
download = True)
test_dataset = dsets.MNIST(root =’./data’,
train = False,
transform = transforms.ToTensor())
# Dataset Loader (Input Pipline)
train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size,
shuffle = True)
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
batch_size = batch_size,
shuffle = False)
[/php]اکنون، باید هایپرپارامترها را تعریف کرد.
[php] # Hyper Parametersinput_size = 784
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001
[/php]در این مجموعه داده، اندازه تصویر 28*28 است. بنابراین، اندازه خروجی ۷۸۴ است. همچنین، ۱۰ رقم در اینجا نمایش داده شده است و در نتیجه، میتوان ۱۰ خروجی متفاوت داشت. بنابراین، num_classes روی ۱۰ تنظیم میشود. همچنین، باید برای ۱۰ بار، روی کل مجموعه داده آموزش داد. در نهایت، در دستههای کوچک ۱۰۰ تصویری آموزش داده میشود. بنابراین، بدین شکل از سرریز حافظه جلوگیری میشود. سپس، باید مدل را به صورت زیر تعریف کرد. در اینجا، باید مدل به عنوان زیرکلاسی از ماژول torch.nn.Module آموزش داده شود و سپس، حرکت رو به جلو تعریف شود (Forward Pass). در کد نوشته شده، softmax به طور داخلی در طول هر مسیر رو به جلو محاسبه میشود و بنابراین، نیازی به تعیین آن درون تابع ()forward نیست.
[php]class LogisticRegression(nn.Module):
def __init__(self, input_size, num_classes):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, num_classes)
def forward(self, x):
out = self.linear(x)
return out
[/php]اکنون، کلاس تعریف شده و یک شی به طور مشابه نمونهسازی میشود.
[php] model = LogisticRegression(input_size, num_classes) [/php]سپس، تابع زیان و بهینهسازی تنظیم میشود. در اینجا، باید از «زیان کراس آنتروپی» (Cross Entropy Loss) و برای بهینهساز، باید از الگوریتم «گرادیان کاهشی تصادفی» (Stochastic Gradient Descent) با نرخ یادگیری ۰.۰۰۱ به صورتی که در هایپرپاارمتر بالا تعریف شده است، استفاده کرد.
[php] criterion = nn.CrossEntropyLoss()optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)
[/php]اکنون، باید آموزش دادن آغاز شود. در اینجا باید وظایف زیر انجام شوند.
- بازنشانی همه گرادیانها به صفر
- ایجاد یک پاس رو به جلو
- محاسبه زیان
- انجام پسانتشار
- به روز رسانی همه وزنها
# Training the Model
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, 28 * 28))
labels = Variable(labels)
# Forward + Backward + Optimize
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print(‘Epoch: [% d/% d], Step: [% d/% d], Loss: %.4f’
% (epoch + 1, num_epochs, i + 1,
len(train_dataset) // batch_size, loss.data[0]))
Finally, we shall be testing out model by using the following code.
# Test the Model
correct = 0
total = 0
for images, labels in test_loader:
images = Variable(images.view(-1, 28 * 28))
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print(‘Accuracy of the model on the 10000 test images: % d %%’ % (
100 * correct / total))
[/php]فرض میشود که همه مراحل به طور درستی انجام شدهاند؛ بنابراین، صحت ۸۲٪ حاصل میشود که از صحت مدلهای لبه علم امروزی که از نوع خاصی از معماریهای «شبکه عصبی مصنوعی» (Artificial Neural Networks) استفاده میکنند، به دور است. کد کامل این پروژه در ادامه آمده است.
[php]import torch
import torch.nn as nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.autograd import Variable
# MNIST Dataset (Images and Labels)
train_dataset = dsets.MNIST(root =’./data’,
train = True,
transform = transforms.ToTensor(),
download = True)
test_dataset = dsets.MNIST(root =’./data’,
train = False,
transform = transforms.ToTensor())
# Dataset Loader (Input Pipline)
train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size,
shuffle = True)
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
batch_size = batch_size,
shuffle = False)
# Hyper Parameters
input_size = 784
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001
# Model
class LogisticRegression(nn.Module):
def __init__(self, input_size, num_classes):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, num_classes);
def forward(self, x):
out = self.linear(x)
return out
model = LogisticRegression(input_size, num_classes)
# Loss and Optimizer
# Softmax is internally computed.
# Set parameters to be updated.
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)
# Training the Model
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, 28 * 28))
labels = Variable(labels)
# Forward + Backward + Optimize
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print(‘Epoch: [% d/% d], Step: [% d/% d], Loss: %.4f’
% (epoch + 1, num_epochs, i + 1,
len(train_dataset) // batch_size, loss.data[0]))
# Test the Model
correct = 0
total = 0
for images, labels in test_loader:
images = Variable(images.view(-1, 28 * 28))
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print(‘Accuracy of the model on the 10000 test images: % d %%’ % (
100 * correct / total))
[/php]گردآوری توسط: تحقیقستان



