ماشین لرنینگ #2 : پیش بینی نژاد سگ

از این یکی پروژه خوشم میاد. توی این یکی پروژه میخوایم بیایم با استفاده از TensorFlow و Keras که پکیج های اصلی و بسیار مهم پایتون برای یادگیری ماشین هستن، یه شبکه convolutional بسازیم. ما عکسای سگ های مختلف رو بهش میدیم و این شبکه مون میاد نژادش رو تشخیص میده. کلا این شبکه کانوولوشنال معمولا برای طبقه بندی استفاده میشه.حالا طبقه بندی میتونه بین دو دسته باشه یا چندتا. این قضیه خیلی مهمه و خیلی از مسائل ماشین لرنینگ این مدلین. این چیزی که ما الان داریم multi-class classification problem هستش.

کارهایی که هم باید بکنیم ایناس: اول اینکه یه دیتاست لازم داریم که مجموعه ای از تصاویر سگها باشه، نژادشون رو هم نوشته باشه. سایت kaggle یه دیتا ست معروف داره. که باید از طریق کد توی colab دانلود کنیم و همونجا ازش استفاده کنیم. اول دیتا یعنی تصاویر و لیبل هاش رو میکنیم و تبدیلشون میکنیم. بعد شبکه رو میسازیم. بعد دیتا رو مدل یا همون شبکه امون میدیم. البته فقط قسمت train رو. بعدش قسمت test رو میدیم و دقت پیش بینی شبکه یه نمره ای میدیم و اگه خوب بودیم ، برای پیش بینی از این مدل استفاده میکنیم.

حالا برای شروع باید بریم توی حساب colabمون و برای استفاده از دیتاست سگهای kaggle این دو تا حسابمون رو به هم وصل کنیم. البته kaggle فیلتره . اولش میریم توی حساب kaggleمون. حساب ساختنش هم کاری نداره. همینطوری با حساب گوگل هم میشه واردش شد. بعد میریم از گوشه بالا سمت راست، روی اون اردکه کلیک میکنیم. بعد میریم قسمت account و از قسمت API روی اون باتن create new API token میزنیم و یه فایل json دانلود میشه. حالا میایم این دو تا خط رو اجرا میکنیم تا بذاره اون token مون رو بذاریم روی پروژه کولب.

1from google.colab import files
1files.upload()

خروجیش این شکلی میشه که یه پنجره باز میشه تا فایلتون رو انتخاب کنیم و بعد آپلود هم فوری میشناسدتون و پایینش مینویسه :

حالا مرحله بعد اینه که بیایم Kaggle API رو نصب کنیم توی colab . دستورش همون pip معمولیه :

1!pip install -q kaggle

حالا بعدش میایم اون فایل json رو میریزیم توی یه فولدر توی پروژه . پس اول میایم یه فولدر میسازیم. بعدش هم اون فایله رو آپلود میکنیم توی فولدرمون . البته باید پرمیشن هم ست کنیم که دیگه کولب بهمون وارنینگ نده.

1!mkdir -p ~/.kaggle
12!cp kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json

پس تا اینجا اومدیم kaggle API رو نصب کردیم. حالا باید بیایم یه فولدر بسازیم تا دیتاست سگها رو توش بریزیم بعد هم با دستور cd فولدرمون رو میکنیم فولدر جاری. چیزی بازه:

1!mkdir dog_dataset
1%cd dog_dataset

حالا باید بریم kaggle رو بگردیم و دیتاستمون رو پیدا کنیم:

1!kaggle datasets list -s dogbreedidfromcomp

خب وقتی پیداش کرد خروجی رو نشون میده :

سایزش هم زیاده خدایی
سایزش هم زیاده خدایی

خب حالا که پیداش کردیم باید دانلود کنیم و بریزیم توی همون فولدرمون که ساختیم. اسم کاملش catherinehorng/dogbreedidfromcomp

1!kaggle datasets download catherinehorng/dogbreedidfromcomp
1%cd ..

حالا مرحله بعدی چیه؟ بیایم unzip کنیم، بعدشم فایلایی که استفاده ندارن رو پاک کنیم. مثله فایل زیپ اصلی و اینا

1!unzip dog_dataset/dogbreedidfromcomp.zip -d dog_dataset
1!rm dog_dataset/dogbreedidfromcomp.zip
1!rm dog_dataset/sample_submission.csv

خب حالا تازه برنامه نویسی شروع میشه و میریم سراغ import ها

1import numpy as np
1import pandas as pd
1import matplotlib.pyplot as plt
1from tqdm import tqdm
1from keras.preprocessing import image
1from sklearn.preprocessing import label_binarize
1from sklearn.model_selection import train_test_split
1from keras.models import Sequential
1from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
1from tensorflow.keras.optimizers import Adam

خب numpy و pandas و matplot که خیلی معروفن.tqdm یه کتابخونه اس که میذاره توی خروجی یه progress-bar نشون بدیم. حالا اومدیم معماری شبکه یا مدلمون رو ترتیبی قرار میدیم. خیلی ساده است. یه مدل ترتیبی یه ترتیب خطی از لایه ها داره. یه استک از لایه ها و وقتایی استفاده میشه که هر لایه فقط یه ورودی و فقط یه خروجی داره.

در پلتفرم کرس، پایه ای ترین واحد سازنده یه شبکه عصبی، لایه ها هستند. که مجموعه ای از نورونها هستند و یه ورودی و یه خروجی دارن و یه تابع هم دارن. این لایه ها انواع مختلف دارن که توضیحشون نمیدم فقط مدل شبکه رو میگم.

مرحله بعد از import ها، لود کردن دیتا و لیبل هاست.

1labels_all = pd.read_csv("dog_dataset/labels.csv")
1print(labels_all.shape)
1labels_all.head()
اینجا 10222 تا سطر و 2 تا ستون id و breed
اینجا 10222 تا سطر و 2 تا ستون id و breed

حالا بیایم value انواع breed رو ببینیم

1breeds_all = labels_all["breed"]
1breed_counts = breeds_all.value_counts()
1breed_counts.head()

حالا برای اینکه یه کم خلاصه تر بشه، میایم فقط سه تا نژاد رو انتخاب می کنیم.

برای شما
1CLASS_NAMES = ['scottish_deerhound','maltese_dog','bernese_mountain_dog']
1labels = labels_all[(labels_all['breed'].isin(CLASS_NAMES))]
1labels = labels.reset_index()
1labels.head()

خب ، چون که میخوایم عکسها رو طبقه بندی کنیم، باید بیایم اون خروجی که مطلوبمون هست رو one hot encode کنیم. وان هات رو اینجا توضیح داده. کلا سرچ هم بکنیم زیاد هست.

1# Creating numpy matrix with zeros
1X_data = np.zeros((len(labels), 224, 224, 3), dtype='float32')
1# One hot encoding
1Y_data = label_binarize(labels['breed'], classes = CLASS_NAMES)
1# Reading and converting image to numpy array and normalizing dataset
1for i in tqdm(range(len(labels))):
1       img = image.load_img('dog_dataset/train/%s.jpg' % labels['id'][i], target_size=(224, 224))
1       img = image.img_to_array(img)
1       x = np.expand_dims(img.copy(), axis=0)
1       X_data[i] = x / 255.0
1# Printing train image and one hot encode shape & size
1print('\nTrain Images shape: ',X_data.shape,' size: {:,}'.format(X_data.size))
1print('One-hot encoded output shape: ',Y_data.shape,' size: {:,}'.format(Y_data.size))

اول میایم برای اینکه میخوایم عکسا رو نرمالایز کنیم، میخونیمشون بعدم تبدیلشون میکنیم به یه آرایه numpy .این از آرایه x_data . یه آرایه y_data هم داریم که با استفاده از متد label_binirized مقداردهیش میکنیم. توی اون حلقه هم عکسا رو میخونیم، بعد آرایه اش می کنیم. بعد هم تقسیم بر 255 میکنیم که نرمالایز بشه. اون کتابخونه tqdm برای همین کاره. برای پری پراسس دیتا و اینا.

357 تا عکس داریم با سایز 224 در 224 و در چنل 3 یعنی RGB. ,وان هات هم 357 تا عکس داریم و 3 تا کلاس برای طبقه بندی
357 تا عکس داریم با سایز 224 در 224 و در چنل 3 یعنی RGB. ,وان هات هم 357 تا عکس داریم و 3 تا کلاس برای طبقه بندی

حالا رسیدیم به ساخت مدل.

1model = Sequential()
1model.add(Conv2D(filters = 64, kernel_size = (5,5), activation ='relu', input_shape = (224,224,3)))
12model.add(MaxPool2D(pool_size=(2,2)))
1model.add(Conv2D(filters = 32, kernel_size = (3,3), activation ='relu', kernel_regularizer = 'l2'))
12model.add(MaxPool2D(pool_size=(2,2)))
1model.add(Conv2D(filters = 16, kernel_size = (7,7), activation ='relu', kernel_regularizer = 'l2'))
12model.add(MaxPool2D(pool_size=(2,2)))
1model.add(Conv2D(filters = 8, kernel_size = (5,5), activation ='relu', kernel_regularizer = 'l2'))
12model.add(MaxPool2D(pool_size=(2,2)))
1model.add(Flatten())
1model.add(Dense(128, activation = "relu", kernel_regularizer = 'l2'))
1model.add(Dense(64, activation = "relu", kernel_regularizer = 'l2'))
1model.add(Dense(len(CLASS_NAMES), activation = "softmax"))
1model.compile(loss = 'categorical_crossentropy', optimizer = Adam(0.0001),metrics=['accuracy'])
1model.summary()

اول گفتم که مدلمون ترتیبیه. لایه Conv2D یه لایه کانوولوشنال دو بعدیه که معمولا برای طبقه بندی تصاویر استفاده میشه. ینی وقتی بخوان دقت رو بالا ببرن توی طبقه بندی تصاویر از این استفاده میکنن. لایه pooling معمولا بعد از یه لایه کانوولوشن قرار میگیره و کارش اینه که بیاد اندازه نقشه های ویژگی رو کم کنه. max pooling کارش اینه که بیاد از هر منطقه (region) مثلا ماکزیمم مقدار رو انتخاب کنه. مدلای دیگه هم داره.

لایه بعدی flatten هست. میاد داده ها رو فلت میکنه. یعنی میاد برای انتقال به لایه بعد یک بعدیشون میکنه. لایه های آخر هم dence یا همون fully connected هست. این لایه ها میان نتیجه شبکه رو در قالب یه بردار با اندازه مشخص ارائه می دن. از این بردار می توان برای دسته بندی استفاده کرد و یا اینکه از آن جهت ادامه پردازش های بعدی بهره برد.

البته من همه پارامتراش رو بررسی نکردم. کلا همه تابعای فعالسازی به جز لایه آخر relu بود. آخرین لایه هم softmax بود که چون میخواستیم احتمال متعلق بودن هر عکس رو به یه نژاد بگیم از این استفاده کردیم. تابع اتلافمون هم categorical_crossentropy میگیریم که معمولا برای مسائل طبقه بندی استفاده میشه. از یه optimizerهم استفاده میکنیم به اسم adam. سرچ بزنین مفصل راجع بهش مطلب هست. خودم حوصله نداشتم. حالا بعدا اگه احتیاج داشتم میخونم.

حالا اجرا که بزنیم ویژگی های شبکه به طور خلاصه میگه.

حالا مرحله بعدی تقسیم بندی دیتا به train و validation و test هست.

1# Splitting the data set into training and testing data sets
1X_train_and_val, X_test, Y_train_and_val, Y_test = train_test_split(X_data, Y_data, test_size = 0.1)
1# Splitting the training data set into training and validation data sets
1X_train, X_val, Y_train, Y_val = train_test_split(X_train_and_val, Y_train_and_val, test_size = 0.2)

حالا میخوایم مدل رو fit کنیم. یعنی تعداد تکرار و تعداد اینکه هر بار روی چه تعداد داده کار کنه. اجرای مدل طول میکشه.

1# Training the model
1epochs = 100
1batch_size = 128
1history = model.fit(X_train, Y_train, batch_size = batch_size, epochs = epochs,
1validation_data = (X_val, Y_val))

آخرین سطر خروجی ، نتیجه نهایی ماس.

حالا بیایم ویژوالایز کنیم.

1plt.figure(figsize=(12, 5))
1plt.plot(history.history['accuracy'], color='r')
1plt.plot(history.history['val_accuracy'], color='b')
1plt.title('Model Accuracy')
1plt.ylabel('Accuracy')
1plt.xlabel('Epochs')
1plt.legend(['train', 'val'])
1plt.show()
دقت به مرور بالا رفته
دقت به مرور بالا رفته

حالا باید بیایم مدل رو روی داده های تست امتحان کنیم.ینی عملیات پیش بینی رو انجام بدیم.

1Y_pred = model.predict(X_test)
1score = model.evaluate(X_test, Y_test)
1print('Accuracy over the test set: \n ', round((score[1]*100), 2), '%')
میبینیم که دقت خیلی بالایی داریم. یعنی 80 درصد از پیش بینی های مدل صحیح بوده
میبینیم که دقت خیلی بالایی داریم. یعنی 80 درصد از پیش بینی های مدل صحیح بوده

بیایم یه نمونه تصویری هم مقایسه کنیم.

1# Plotting image to compare
1plt.imshow(X_test[1,:,:,:])
1plt.show()
1# Finding max value from predition list and comaparing original value vs predicted
1print("Originally : ",labels['breed'][np.argmax(Y_test[1])])
1print("Predicted : ",labels['breed'][np.argmax(Y_pred[1])])
درست پیش بینی کرده
درست پیش بینی کرده

اینجاس کدا.

تمام.

نویسنده مطلب: فائزه ثقفی

منبع مطلب

به فکر سرمایه‌گذاری هستی؟

با هر سطحی از دانش در سریع‌ترین زمان با آموزش گام به گام، سرمایه گذاری را تجربه کن. همین الان میتونی با لینک زیر ثبت نام کنی و ۱۰ درصد تخفیف در کارمزد معاملاتی داشته باشی

ثبت نام و دریافت جایزه
ممکن است شما بپسندید
نظرات
  1. جمیز ولیامز- احمد روسباندوند می گوید

    ایرادات زیادی داره
    1- نمودار loss رو بذارید. حس میکنم اورفیت شده. معمولا وقتی بین ترین و تست در نمودار اکوریسی فاصله میفته نشان دهنده اورفیت بودن هست و نمودار loss که نذاشتید اینجا، میتونه تاییدش کنه.
    2- هنوز میشه دقتش رو برد بالا من همینو با دقت 95 درصد با یه مدل دیگه انجام دادم
    3- هنوز loss بالاست. بهتر هست بیاد زیر 0.5
    4- تعداد پارامتر های مدلتون کم هست. هنوز بهتره یکم به پیچیدگی مدل اضافه کرد تا دقت بالاتر بره.

    5- با این حال خوشم اومد از نوشته اتون. دست مریضات.

نظر شما درباره این مطلب

آدرس ایمیل شما منتشر نخواهد شد.