برنامه نویس پایتون، عاشق کتاب، فیلم، روزنوشته و ... محمدحسین
ماشین لرنینگ #2 : پیش بینی نژاد سگ
از این یکی پروژه خوشم میاد. توی این یکی پروژه میخوایم بیایم با استفاده از TensorFlow و Keras که پکیج های اصلی و بسیار مهم پایتون برای یادگیری ماشین هستن، یه شبکه convolutional بسازیم. ما عکسای سگ های مختلف رو بهش میدیم و این شبکه مون میاد نژادش رو تشخیص میده. کلا این شبکه کانوولوشنال معمولا برای طبقه بندی استفاده میشه.حالا طبقه بندی میتونه بین دو دسته باشه یا چندتا. این قضیه خیلی مهمه و خیلی از مسائل ماشین لرنینگ این مدلین. این چیزی که ما الان داریم multi-class classification problem هستش.
کارهایی که هم باید بکنیم ایناس: اول اینکه یه دیتاست لازم داریم که مجموعه ای از تصاویر سگها باشه، نژادشون رو هم نوشته باشه. سایت kaggle یه دیتا ست معروف داره. که باید از طریق کد توی colab دانلود کنیم و همونجا ازش استفاده کنیم. اول دیتا یعنی تصاویر و لیبل هاش رو میکنیم و تبدیلشون میکنیم. بعد شبکه رو میسازیم. بعد دیتا رو مدل یا همون شبکه امون میدیم. البته فقط قسمت train رو. بعدش قسمت test رو میدیم و دقت پیش بینی شبکه یه نمره ای میدیم و اگه خوب بودیم ، برای پیش بینی از این مدل استفاده میکنیم.
حالا برای شروع باید بریم توی حساب colabمون و برای استفاده از دیتاست سگهای kaggle این دو تا حسابمون رو به هم وصل کنیم. البته kaggle فیلتره . اولش میریم توی حساب kaggleمون. حساب ساختنش هم کاری نداره. همینطوری با حساب گوگل هم میشه واردش شد. بعد میریم از گوشه بالا سمت راست، روی اون اردکه کلیک میکنیم. بعد میریم قسمت account و از قسمت API روی اون باتن create new API token میزنیم و یه فایل json دانلود میشه. حالا میایم این دو تا خط رو اجرا میکنیم تا بذاره اون token مون رو بذاریم روی پروژه کولب.
from google.colab import files
files.upload()
خروجیش این شکلی میشه که یه پنجره باز میشه تا فایلتون رو انتخاب کنیم و بعد آپلود هم فوری میشناسدتون و پایینش مینویسه :
حالا مرحله بعد اینه که بیایم Kaggle API رو نصب کنیم توی colab . دستورش همون pip معمولیه :
!pip install -q kaggle
حالا بعدش میایم اون فایل json رو میریزیم توی یه فولدر توی پروژه . پس اول میایم یه فولدر میسازیم. بعدش هم اون فایله رو آپلود میکنیم توی فولدرمون . البته باید پرمیشن هم ست کنیم که دیگه کولب بهمون وارنینگ نده.
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json
پس تا اینجا اومدیم kaggle API رو نصب کردیم. حالا باید بیایم یه فولدر بسازیم تا دیتاست سگها رو توش بریزیم بعد هم با دستور cd فولدرمون رو میکنیم فولدر جاری. چیزی بازه:
!mkdir dog_dataset
%cd dog_dataset
حالا باید بریم kaggle رو بگردیم و دیتاستمون رو پیدا کنیم:
!kaggle datasets list -s dogbreedidfromcomp
خب وقتی پیداش کرد خروجی رو نشون میده :
خب حالا که پیداش کردیم باید دانلود کنیم و بریزیم توی همون فولدرمون که ساختیم. اسم کاملش catherinehorng/dogbreedidfromcomp
!kaggle datasets download catherinehorng/dogbreedidfromcomp
%cd ..
حالا مرحله بعدی چیه؟ بیایم unzip کنیم، بعدشم فایلایی که استفاده ندارن رو پاک کنیم. مثله فایل زیپ اصلی و اینا
!unzip dog_dataset/dogbreedidfromcomp.zip -d dog_dataset
!rm dog_dataset/dogbreedidfromcomp.zip
!rm dog_dataset/sample_submission.csv
خب حالا تازه برنامه نویسی شروع میشه و میریم سراغ import ها
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tqdm import tqdm
from keras.preprocessing import image
from sklearn.preprocessing import label_binarize
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from tensorflow.keras.optimizers import Adam
خب numpy و pandas و matplot که خیلی معروفن.tqdm یه کتابخونه اس که میذاره توی خروجی یه progress-bar نشون بدیم. حالا اومدیم معماری شبکه یا مدلمون رو ترتیبی قرار میدیم. خیلی ساده است. یه مدل ترتیبی یه ترتیب خطی از لایه ها داره. یه استک از لایه ها و وقتایی استفاده میشه که هر لایه فقط یه ورودی و فقط یه خروجی داره.
در پلتفرم کرس، پایه ای ترین واحد سازنده یه شبکه عصبی، لایه ها هستند. که مجموعه ای از نورونها هستند و یه ورودی و یه خروجی دارن و یه تابع هم دارن. این لایه ها انواع مختلف دارن که توضیحشون نمیدم فقط مدل شبکه رو میگم.
مرحله بعد از import ها، لود کردن دیتا و لیبل هاست.
labels_all = pd.read_csv("dog_dataset/labels.csv")
print(labels_all.shape)
labels_all.head()
حالا بیایم value انواع breed رو ببینیم
breeds_all = labels_all["breed"]
breed_counts = breeds_all.value_counts()
breed_counts.head()
حالا برای اینکه یه کم خلاصه تر بشه، میایم فقط سه تا نژاد رو انتخاب می کنیم.
CLASS_NAMES = ['scottish_deerhound','maltese_dog','bernese_mountain_dog']
labels = labels_all[(labels_all['breed'].isin(CLASS_NAMES))]
labels = labels.reset_index()
labels.head()
خب ، چون که میخوایم عکسها رو طبقه بندی کنیم، باید بیایم اون خروجی که مطلوبمون هست رو one hot encode کنیم. وان هات رو اینجا توضیح داده. کلا سرچ هم بکنیم زیاد هست.
# Creating numpy matrix with zeros
X_data = np.zeros((len(labels), 224, 224, 3), dtype='float32')
# One hot encoding
Y_data = label_binarize(labels['breed'], classes = CLASS_NAMES)
# Reading and converting image to numpy array and normalizing dataset
for i in tqdm(range(len(labels))):
img = image.load_img('dog_dataset/train/%s.jpg' % labels['id'][i], target_size=(224, 224))
img = image.img_to_array(img)
x = np.expand_dims(img.copy(), axis=0)
X_data[i] = x / 255.0
# Printing train image and one hot encode shape & size
print('\nTrain Images shape: ',X_data.shape,' size: {:,}'.format(X_data.size))
print('One-hot encoded output shape: ',Y_data.shape,' size: {:,}'.format(Y_data.size))
اول میایم برای اینکه میخوایم عکسا رو نرمالایز کنیم، میخونیمشون بعدم تبدیلشون میکنیم به یه آرایه numpy .این از آرایه x_data . یه آرایه y_data هم داریم که با استفاده از متد label_binirized مقداردهیش میکنیم. توی اون حلقه هم عکسا رو میخونیم، بعد آرایه اش می کنیم. بعد هم تقسیم بر 255 میکنیم که نرمالایز بشه. اون کتابخونه tqdm برای همین کاره. برای پری پراسس دیتا و اینا.
حالا رسیدیم به ساخت مدل.
model = Sequential()
model.add(Conv2D(filters = 64, kernel_size = (5,5), activation ='relu', input_shape = (224,224,3)))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Conv2D(filters = 32, kernel_size = (3,3), activation ='relu', kernel_regularizer = 'l2'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Conv2D(filters = 16, kernel_size = (7,7), activation ='relu', kernel_regularizer = 'l2'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Conv2D(filters = 8, kernel_size = (5,5), activation ='relu', kernel_regularizer = 'l2'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(128, activation = "relu", kernel_regularizer = 'l2'))
model.add(Dense(64, activation = "relu", kernel_regularizer = 'l2'))
model.add(Dense(len(CLASS_NAMES), activation = "softmax"))
model.compile(loss = 'categorical_crossentropy', optimizer = Adam(0.0001),metrics=['accuracy'])
model.summary()
اول گفتم که مدلمون ترتیبیه. لایه Conv2D یه لایه کانوولوشنال دو بعدیه که معمولا برای طبقه بندی تصاویر استفاده میشه. ینی وقتی بخوان دقت رو بالا ببرن توی طبقه بندی تصاویر از این استفاده میکنن. لایه pooling معمولا بعد از یه لایه کانوولوشن قرار میگیره و کارش اینه که بیاد اندازه نقشه های ویژگی رو کم کنه. max pooling کارش اینه که بیاد از هر منطقه (region) مثلا ماکزیمم مقدار رو انتخاب کنه. مدلای دیگه هم داره.
لایه بعدی flatten هست. میاد داده ها رو فلت میکنه. یعنی میاد برای انتقال به لایه بعد یک بعدیشون میکنه. لایه های آخر هم dence یا همون fully connected هست. این لایه ها میان نتیجه شبکه رو در قالب یه بردار با اندازه مشخص ارائه می دن. از این بردار می توان برای دسته بندی استفاده کرد و یا اینکه از آن جهت ادامه پردازش های بعدی بهره برد.
البته من همه پارامتراش رو بررسی نکردم. کلا همه تابعای فعالسازی به جز لایه آخر relu بود. آخرین لایه هم softmax بود که چون میخواستیم احتمال متعلق بودن هر عکس رو به یه نژاد بگیم از این استفاده کردیم. تابع اتلافمون هم categorical_crossentropy میگیریم که معمولا برای مسائل طبقه بندی استفاده میشه. از یه optimizerهم استفاده میکنیم به اسم adam. سرچ بزنین مفصل راجع بهش مطلب هست. خودم حوصله نداشتم. حالا بعدا اگه احتیاج داشتم میخونم.
حالا اجرا که بزنیم ویژگی های شبکه به طور خلاصه میگه.
حالا مرحله بعدی تقسیم بندی دیتا به train و validation و test هست.
# Splitting the data set into training and testing data sets
X_train_and_val, X_test, Y_train_and_val, Y_test = train_test_split(X_data, Y_data, test_size = 0.1)
# Splitting the training data set into training and validation data sets
X_train, X_val, Y_train, Y_val = train_test_split(X_train_and_val, Y_train_and_val, test_size = 0.2)
حالا میخوایم مدل رو fit کنیم. یعنی تعداد تکرار و تعداد اینکه هر بار روی چه تعداد داده کار کنه. اجرای مدل طول میکشه.
# Training the model
epochs = 100
batch_size = 128
history = model.fit(X_train, Y_train, batch_size = batch_size, epochs = epochs,
validation_data = (X_val, Y_val))
آخرین سطر خروجی ، نتیجه نهایی ماس.
حالا بیایم ویژوالایز کنیم.
plt.figure(figsize=(12, 5))
plt.plot(history.history['accuracy'], color='r')
plt.plot(history.history['val_accuracy'], color='b')
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend(['train', 'val'])
plt.show()
حالا باید بیایم مدل رو روی داده های تست امتحان کنیم.ینی عملیات پیش بینی رو انجام بدیم.
Y_pred = model.predict(X_test)
score = model.evaluate(X_test, Y_test)
print('Accuracy over the test set: \n ', round((score[1]*100), 2), '%')
بیایم یه نمونه تصویری هم مقایسه کنیم.
# Plotting image to compare
plt.imshow(X_test[1,:,:,:])
plt.show()
# Finding max value from predition list and comaparing original value vs predicted
print("Originally : ",labels['breed'][np.argmax(Y_test[1])])
print("Predicted : ",labels['breed'][np.argmax(Y_pred[1])])
اینجاس کدا.
تمام.
مطلبی دیگر از این انتشارات
آزمایش حدس گلدباخ با پایتون 1
مطلبی دیگر از این انتشارات
چطوری خدای پایتون بشم؟ خوان اول
مطلبی دیگر از این انتشارات
آموزش تست نویسی در PHP و Laravel با PHPUnit