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

۴۷۵ بازدید
آخرین به‌روزرسانی: ۱۸ اردیبهشت ۱۴۰۲
زمان مطالعه: ۴ دقیقه
شناسایی دست خط با رگرسیون لجستیک در پایتون — راهنمای کاربردی

در این مطلب، روش شناسایی دست خط با رگرسیون لجستیک در پایتون مورد بررسی قرار گرفته است. «رگرسیون لجستیک» (Logistic Regression) یکی از روش‌های آماری متداول است که امکان پیش‌بینی یک خروجی دودویی را از یک مجموعه از متغیرهای مستقل فراهم می‌کند. خصوصیات مختلف رگرسیون لجستیک و پیاده‌سازی «پایتون» (Python Programming Language) آن، پیش از این در مطالب دیگری به طور کامل تشریح شد. در این مطلب، به چگونگی پیاده‌سازی الگوریتم رگرسیون لجستیک در پایتون و با استفاده از کتابخانه PyTorch پرداخته شده است. اکنون، چگونگی دسته‌بندی ارقام دست‌نویس در مجموعه داده MNIST با استفاده از الگوریتم رگرسیون لجستیک در کتابخانه Pythorch‌ پایتون آموزش داده شده است. در واقع، در اینجا یک مسئله شناسایی دست خط بررسی و تحلیل شده است.

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

در این راستا، ابتدا نیاز به نصب Pytorch است. ساده‌ترین راه برای انجام این کار، استفاده از pip یا «کوندا» (Conda) است. کاربران باید برای نصب نسخه مفسر پایتون و مدیر بسته‌ای که قصد استفاده از آن را دارند، به وب‌سایت پای‌تورچ [+] مراجعه کنند.

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

1import torch 
2import torch.nn as nn 
3import torchvision.datasets as dsets 
4import torchvision.transforms as transforms 
5from torch.autograd import Variable 

در اینجا، ماژول torch.nn حاوی کد لازم برای مدل است، torchvision.datasets حاوی مجموعه داده MNIST است. این ماژول، حاوی کتابخانه ارقام دست‌نویس است که در اینجا مورد استفاده قرار گرفته است. ماژول torchvision.transforms حاوی متدهای متعددی برای تبدیل اشیا به اشیای دیگر است. در اینجا، از این ماژول برای تبدیل تصاویر به تانسورهای PyTorch استفاده شده است. همچنین، ماژول orch.autograd حاوی کلاس Variable است که هنگام تعریف «تانسورها» (Tensors) مورد استفاده قرار می‌گیرد. در ادامه، باید مجموعه داده در حافظه دانلود و بارگذاری شود.

1# MNIST Dataset (Images and Labels) 
2train_dataset = dsets.MNIST(root ='./data',  
3                            train = True,  
4                            transform = transforms.ToTensor(), 
5                            download = True) 
6  
7test_dataset = dsets.MNIST(root ='./data',  
8                           train = False,  
9                           transform = transforms.ToTensor()) 
10  
11# Dataset Loader (Input Pipline) 
12train_loader = torch.utils.data.DataLoader(dataset = train_dataset,  
13                                           batch_size = batch_size,  
14                                           shuffle = True) 
15  
16test_loader = torch.utils.data.DataLoader(dataset = test_dataset,  
17                                          batch_size = batch_size,  
18                                          shuffle = False) 

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

1# Hyper Parameters  
2input_size = 784
3num_classes = 10
4num_epochs = 5
5batch_size = 100
6learning_rate = 0.001

در این مجموعه داده، اندازه تصویر 28*28 است. بنابراین، اندازه خروجی ۷۸۴ است. همچنین، ۱۰ رقم در اینجا نمایش داده شده است و در نتیجه، می‌توان ۱۰ خروجی متفاوت داشت. بنابراین، num_classes روی ۱۰ تنظیم می‌شود. همچنین، باید برای ۱۰ بار، روی کل مجموعه داده آموزش داد. در نهایت، در دسته‌های کوچک ۱۰۰ تصویری آموزش داده می‌شود. بنابراین، بدین شکل از سرریز حافظه جلوگیری می‌شود.

سپس، باید مدل را به صورت زیر تعریف کرد. در اینجا، باید مدل به عنوان زیرکلاسی از ماژول torch.nn.Module آموزش داده شود و سپس، حرکت رو به جلو تعریف شود (Forward Pass). در کد نوشته شده، softmax به طور داخلی در طول هر مسیر رو به جلو محاسبه می‌شود و بنابراین، نیازی به تعیین آن درون تابع ()forward نیست.

1class LogisticRegression(nn.Module): 
2    def __init__(self, input_size, num_classes): 
3        super(LogisticRegression, self).__init__() 
4        self.linear = nn.Linear(input_size, num_classes) 
5  
6    def forward(self, x): 
7        out = self.linear(x) 
8        return out 

اکنون، کلاس تعریف شده و یک شی به طور مشابه نمونه‌سازی می‌شود.

1model = LogisticRegression(input_size, num_classes) 

سپس، تابع زیان و بهینه‌سازی تنظیم می‌شود. در اینجا، باید از «زیان کراس آنتروپی» (Cross Entropy Loss) و برای بهینه‌ساز، باید از الگوریتم «گرادیان کاهشی تصادفی» (Stochastic Gradient Descent) با نرخ یادگیری ۰.۰۰۱ به صورتی که در هایپرپاارمتر بالا تعریف شده است، استفاده کرد.

1criterion = nn.CrossEntropyLoss() 
2optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate) 

اکنون، باید آموزش دادن آغاز شود. در اینجا باید وظایف زیر انجام شوند.

  • بازنشانی همه گرادیان‌ها به صفر
  • ایجاد یک پاس رو به جلو
  • محاسبه زیان
  • انجام پس‌انتشار
  • به روز رسانی همه وزن‌ها
1# Training the Model 
2for epoch in range(num_epochs): 
3    for i, (images, labels) in enumerate(train_loader): 
4        images = Variable(images.view(-1, 28 * 28)) 
5        labels = Variable(labels) 
6  
7        # Forward + Backward + Optimize 
8        optimizer.zero_grad() 
9        outputs = model(images) 
10        loss = criterion(outputs, labels) 
11        loss.backward() 
12        optimizer.step() 
13  
14        if (i + 1) % 100 == 0: 
15            print('Epoch: [% d/% d], Step: [% d/% d], Loss: %.4f'
16                  % (epoch + 1, num_epochs, i + 1, 
17                     len(train_dataset) // batch_size, loss.data[0])) 
18
19Finally, we shall be testing out model by using the following code.
20# Test the Model 
21correct = 0
22total = 0
23for images, labels in test_loader: 
24    images = Variable(images.view(-1, 28 * 28)) 
25    outputs = model(images) 
26    _, predicted = torch.max(outputs.data, 1) 
27    total += labels.size(0) 
28    correct += (predicted == labels).sum() 
29  
30print('Accuracy of the model on the 10000 test images: % d %%' % ( 
31            100 * correct / total)) 

فرض می‌شود که همه مراحل به طور درستی انجام شده‌اند؛ بنابراین، صحت ۸۲٪ حاصل می‌شود که از صحت مدل‌های لبه علم امروزی که از نوع خاصی از معماری‌های «شبکه عصبی مصنوعی» (Artificial Neural Networks) استفاده می‌کنند، به دور است.

کد کامل این پروژه در ادامه آمده است.

1import torch 
2import torch.nn as nn 
3import torchvision.datasets as dsets 
4import torchvision.transforms as transforms 
5from torch.autograd import Variable 
6  
7  
8# MNIST Dataset (Images and Labels) 
9train_dataset = dsets.MNIST(root ='./data', 
10                            train = True, 
11                            transform = transforms.ToTensor(), 
12                            download = True) 
13  
14test_dataset = dsets.MNIST(root ='./data', 
15                           train = False, 
16                           transform = transforms.ToTensor()) 
17  
18# Dataset Loader (Input Pipline) 
19train_loader = torch.utils.data.DataLoader(dataset = train_dataset, 
20                                           batch_size = batch_size, 
21                                           shuffle = True) 
22  
23test_loader = torch.utils.data.DataLoader(dataset = test_dataset, 
24                                          batch_size = batch_size, 
25                                          shuffle = False) 
26  
27# Hyper Parameters 
28input_size = 784
29num_classes = 10
30num_epochs = 5
31batch_size = 100
32learning_rate = 0.001
33  
34# Model 
35class LogisticRegression(nn.Module): 
36    def __init__(self, input_size, num_classes): 
37        super(LogisticRegression, self).__init__() 
38        self.linear = nn.Linear(input_size, num_classes) 
39  
40    def forward(self, x): 
41        out = self.linear(x) 
42        return out 
43  
44  
45model = LogisticRegression(input_size, num_classes) 
46  
47# Loss and Optimizer 
48# Softmax is internally computed. 
49# Set parameters to be updated. 
50criterion = nn.CrossEntropyLoss() 
51optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate) 
52  
53# Training the Model 
54for epoch in range(num_epochs): 
55    for i, (images, labels) in enumerate(train_loader): 
56        images = Variable(images.view(-1, 28 * 28)) 
57        labels = Variable(labels) 
58  
59        # Forward + Backward + Optimize 
60        optimizer.zero_grad() 
61        outputs = model(images) 
62        loss = criterion(outputs, labels) 
63        loss.backward() 
64        optimizer.step() 
65  
66        if (i + 1) % 100 == 0: 
67            print('Epoch: [% d/% d], Step: [% d/% d], Loss: %.4f'
68                  % (epoch + 1, num_epochs, i + 1, 
69                     len(train_dataset) // batch_size, loss.data[0])) 
70  
71# Test the Model 
72correct = 0
73total = 0
74for images, labels in test_loader: 
75    images = Variable(images.view(-1, 28 * 28)) 
76    outputs = model(images) 
77    _, predicted = torch.max(outputs.data, 1) 
78    total += labels.size(0) 
79    correct += (predicted == labels).sum() 
80  
81print('Accuracy of the model on the 10000 test images: % d %%' % ( 
82            100 * correct / total)) 

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۳ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
GeeksforGeeks
۳ دیدگاه برای «شناسایی دست خط با رگرسیون لجستیک در پایتون — راهنمای کاربردی»

سلام
اگر عدد فارسی رو بخوام شناسایی کنه، چطوری کتابخانه رو درست کنم؟ یا از کجا بیارم که از اون دیتاست استفاده کنم

سلام
ممنون از مطلبتون
ديتاست mnist رو بايد از کجا دانلود کرد؟ و کدوم ديتاستش رو بايد دان کرد؟

با سلام؛

از همراهی شما با مجله فرادرس سپاس گزاریم. همانطور که در متن نیز ذکر شده، این مجموعه داده از طریق کتابخانه PyTorCh و با استفاده از torchvision.datasets در دسترس است. برای دانلود این کتابخانه بدون نیاز به نصب PyTorch، مطالعه مطلب زیر پیشنهاد می‌شود.
مجموعه داده های عمومی برای داده کاوی و هوش مصنوعی — راهنمای کاربردی

نظر شما چیست؟

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