شناسایی دست خط با رگرسیون لجستیک در پایتون — راهنمای کاربردی

در این مطلب، روش شناسایی دست خط با رگرسیون لجستیک در پایتون مورد بررسی قرار گرفته است. «رگرسیون لجستیک» (Logistic Regression) یکی از روشهای آماری متداول است که امکان پیشبینی یک خروجی دودویی را از یک مجموعه از متغیرهای مستقل فراهم میکند. خصوصیات مختلف رگرسیون لجستیک و پیادهسازی «پایتون» (Python Programming Language) آن، پیش از این در مطالب دیگری به طور کامل تشریح شد. در این مطلب، به چگونگی پیادهسازی الگوریتم رگرسیون لجستیک در پایتون و با استفاده از کتابخانه PyTorch پرداخته شده است. اکنون، چگونگی دستهبندی ارقام دستنویس در مجموعه داده MNIST با استفاده از الگوریتم رگرسیون لجستیک در کتابخانه Pythorch پایتون آموزش داده شده است. در واقع، در اینجا یک مسئله شناسایی دست خط بررسی و تحلیل شده است.
شناسایی دست خط با رگرسیون لجستیک در پایتون
در این راستا، ابتدا نیاز به نصب Pytorch است. سادهترین راه برای انجام این کار، استفاده از pip یا «کوندا» (Conda) است. کاربران باید برای نصب نسخه مفسر پایتون و مدیر بستهای که قصد استفاده از آن را دارند، به وبسایت پایتورچ [+] مراجعه کنند. پس از نصب پایتورچ، بررسی روی کد انجام میشود. سه خط کدی که در ادامه آورده شده است، برای وارد کردن توابع و اشیای کتابخانهای مورد نیاز استفاده میشود.
import torch import torch.nn as nn import torchvision.datasets as dsets import torchvision.transforms as transforms from torch.autograd import Variable
در اینجا، ماژول torch.nn حاوی کد لازم برای مدل است، torchvision.datasets حاوی مجموعه داده MNIST است. این ماژول، حاوی کتابخانه ارقام دستنویس است که در اینجا مورد استفاده قرار گرفته است. ماژول torchvision.transforms حاوی متدهای متعددی برای تبدیل اشیا به اشیای دیگر است. در اینجا، از این ماژول برای تبدیل تصاویر به تانسورهای PyTorch استفاده شده است. همچنین، ماژول orch.autograd حاوی کلاس Variable است که هنگام تعریف «تانسورها» (Tensors) مورد استفاده قرار میگیرد. در ادامه، باید مجموعه داده در حافظه دانلود و بارگذاری شود.
# 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
در این مجموعه داده، اندازه تصویر 28*28 است. بنابراین، اندازه خروجی ۷۸۴ است. همچنین، ۱۰ رقم در اینجا نمایش داده شده است و در نتیجه، میتوان ۱۰ خروجی متفاوت داشت. بنابراین، num_classes روی ۱۰ تنظیم میشود. همچنین، باید برای ۱۰ بار، روی کل مجموعه داده آموزش داد. در نهایت، در دستههای کوچک ۱۰۰ تصویری آموزش داده میشود. بنابراین، بدین شکل از سرریز حافظه جلوگیری میشود. سپس، باید مدل را به صورت زیر تعریف کرد. در اینجا، باید مدل به عنوان زیرکلاسی از ماژول torch.nn.Module آموزش داده شود و سپس، حرکت رو به جلو تعریف شود (Forward Pass). در کد نوشته شده، softmax به طور داخلی در طول هر مسیر رو به جلو محاسبه میشود و بنابراین، نیازی به تعیین آن درون تابع ()forward نیست.
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)
سپس، تابع زیان و بهینهسازی تنظیم میشود. در اینجا، باید از «زیان کراس آنتروپی» (Cross Entropy Loss) و برای بهینهساز، باید از الگوریتم «گرادیان کاهشی تصادفی» (Stochastic Gradient Descent) با نرخ یادگیری ۰.۰۰۱ به صورتی که در هایپرپاارمتر بالا تعریف شده است، استفاده کرد.
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])) 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))
فرض میشود که همه مراحل به طور درستی انجام شدهاند؛ بنابراین، صحت ۸۲٪ حاصل میشود که از صحت مدلهای لبه علم امروزی که از نوع خاصی از معماریهای «شبکه عصبی مصنوعی» (Artificial Neural Networks) استفاده میکنند، به دور است. کد کامل این پروژه در ادامه آمده است.
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))
اگر نوشته بالا برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی پایتون
- آموزش تکمیلی برنامهنویسی پایتون
- مجموعه آموزشهای دادهکاوی و یادگیری ماشین
- زبان برنامهنویسی پایتون (Python) — از صفر تا صد
- یادگیری علم داده (Data Science) با پایتون — از صفر تا صد
- آموزش پایتون (Python) — مجموعه مقالات جامع وبلاگ فرادرس
^^
سلام
ممنون از مطلبتون
ديتاست mnist رو بايد از کجا دانلود کرد؟ و کدوم ديتاستش رو بايد دان کرد؟
با سلام؛
از همراهی شما با مجله فرادرس سپاس گزاریم. همانطور که در متن نیز ذکر شده، این مجموعه داده از طریق کتابخانه PyTorCh و با استفاده از torchvision.datasets در دسترس است. برای دانلود این کتابخانه بدون نیاز به نصب PyTorch، مطالعه مطلب زیر پیشنهاد میشود.
مجموعه داده های عمومی برای داده کاوی و هوش مصنوعی — راهنمای کاربردی