بستههای نرمافزاری متعددی برای انجام کارهای مربوط به یادگیری ماشین ارائه شده است که شاید از این میان نامدارترین آنها کتابخانه tensorflow باشد. با این حال برای وظایف معمولیتر و صد البته برای شروع یادگیری ماشین کتابخانههای سبکتری نیز وجود دارد. یکی از این کتابخانه که بر پایه scipy، numpy و matplotlib توسعه یافته است، کتابخانه scikit-learn میباشد. در این نوشته به نحوه تشخیص اعداد با استفاده از امکانات فراهم شده توسط این کتابخانه پرداخته خواهد شد.
بسم الله الرحمن الرحیم
یکی از مسائل استاندارد که اکثر افراد برای ورود به مبحث یادگیری ماشین اقدام به حل آن مینمایند، تشخیص اعداد میباشد. خوشبختانه دادههای مسئله تشخیص اعداد بین دادههای استاندار کتابخانه scikit-learn وجود دارد. بعنوان اولین کار برای تشخیص اعداد ابتدا باید دادههای مسئله را به شکل مناسب خواند. قطعه کد زیر این مرحله از کار را نشان میدهد:
digits = datasets.load_digits() images_and_labels = list(zip(digits.images, digits.target))
در سطر اول از میان مجموعه دادههای استاندارد کتابخانه scikit-learn دادههای مربوط به تشخیص اعداد خوانده شده و در digits ذخیره گشته است. شی digits دارای دو مولفه images و target میباشد که اولی تصویر عددها و دومی عدد صحیح متناظر با هر تصویر میباشد. در سطر بعدی این دادهها را برای استفاده هنگام نمایش دادن تصویرشان به شکل لیستی از دوتاییها با عنصر اول تصویر و عنصر دوم عدد متناظر در میآوریم.
در ادامه تعداد کل تصاویر موجود در مجموعه دادهها را بدست آورده و تصاویر را که به شکل آرایهای دو بعدی و ۸x۸ میباشند به شکل بردار ۶۴-تایی در میآوریم. این تبدیل شکل به این علت است که فرمت استاندارد دادههای قابل استفاده در scikit-learn برای ورودی دادن به کلاسهای یادگیری ماشین، شکل برداری میباشد.
n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1))
در ویرایشهای جدید scikit-learn کاری که ما در سطر دوم کد بالا انجام دادهایم از قبل انجام شده است و هر تصویر در هر یک از درایههای مولفه data از digits به شکل یک بردار ۶۴-درایهای آماده است. بعبارتی میتوان به جای سطر دوم کد بالا اینگونه نوشت:
data = digits.data
در ادامه نیاز داریم تا classifier مورد استفاده را تعریف نماییم. برای مثال ما از شبکه عصبی پرسپترون چند لایه استفاده مینماییم:
classifier = MLPClassifier(hidden_layer_sizes=(100,50,))
در روش شبکههای عصبی پرسپترون چند لایه، تعداد نرونها در لایه ورودی و همچنین در لایه خروجی بر اساس بردار ورودی و خروجی تعیین میشود ولی تعداد لایههای پنهان و تعداد نرونها در این لایهها توسط کاربر قابل تنظیم میباشد. در یک سطر کد بالا، شبکه عصبی پرسپترون چند لایه با دو لایه مخفی و پنجاه نرون در هر لایه مخفی، بعنوان classifier تعریف شده است. حال نوبت به آموزش classifier میرسد. برای این کار از تابع fit استفاده خواهد شد که به دو ورودی استاندارد آرایه دادهها و آرایه خروجی صحیح متناظر نیاز دارد. برای مثال ما نصف دادهها را برای آموزش مورد استفاده قرار میدهیم که در قطعه کد زیر قابل مشاهده میباشد:
classifier.fit(data[:n_samples // 2], digits.target[:n_samples // 2])
حالا نوبت به آزمیش شبکه عصبی بر روی باقی دادهها رسیده است. برای تحلیل خروجی شبکه عصبی خروجیهای مورد انتظار و خروجیهای پیشبینی شده را در دو آرایه جداگانه بصورت زیر نگه میداریم:
expected = digits.target[n_samples // 2:] predicted = classifier.predict(data[n_samples // 2:])
بعد از این میتوانیم گزارش classification و همچنین ماتریس درهم ریختگی را با استفاده از قطعه کد زیر مشاهده نماییم:
print("Classification report for classifier %s:\n%s\n" % (classifier, metrics.classification_report(expected, predicted))) print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted))
در نهایت بعنوان یک بازنمایی از کاری که انجام شده است، تصویری حاوی دو سطر از اعداد ایجاد میشود که سطر اول هشت تا از دادههای آموزش و سطر دوم هشت تا از دادههای تست را دربرد دارد. عنوان هشت زیر تصویر سطر اول عدد متناظر با تصویر و عنوان هشت زیر تصویر سطر دوم خروجی classifier برای ورودی میباشد. قطعه کد زیر این کار را برای ما انجام خواهد داد:
for index, (image, label) in enumerate(images_and_labels[:8]): plt.subplot(2, 8, index + 1) plt.axis('off') plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest') plt.title(str(label)) images_and_predictions = list(zip(digits.images[n_samples // 2:], predicted)) for index, (image, prediction) in enumerate(images_and_predictions[:8]): plt.subplot(2, 8, index + 9) plt.axis('off') plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest') plt.title(str(prediction)) plt.show()
شکل زیر خروجی نهایی را نشان میدهد: