ماشین لرنینگ #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 filesfiles.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 npimport pandas as pdimport matplotlib.pyplot as pltfrom tqdm import tqdmfrom keras.preprocessing import imagefrom sklearn.preprocessing import label_binarizefrom sklearn.model_selection import train_test_splitfrom keras.models import Sequentialfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2Dfrom tensorflow.keras.optimizers import Adamخب numpy و pandas و matplot که خیلی معروفن.tqdm یه کتابخونه اس که میذاره توی خروجی یه progress-bar نشون بدیم. حالا اومدیم معماری شبکه یا مدلمون رو ترتیبی قرار میدیم. خیلی ساده است. یه مدل ترتیبی یه ترتیب خطی از لایه ها داره. یه استک از لایه ها و وقتایی استفاده میشه که هر لایه فقط یه ورودی و فقط یه خروجی داره. در پلتفرم کرس، پایه ای ترین واحد سازنده یه شبکه عصبی، لایه ها هستند. که مجموعه ای از نورونها هستند و یه ورودی و یه خروجی دارن و یه تابع هم دارن. این لایه ها انواع مختلف دارن که توضیحشون نمیدم فقط مدل شبکه رو میگم.مرحله بعد از import ها، لود کردن دیتا و لیبل هاست.labels_all = pd.read_csv(&quotdog_dataset/labels.csv&quot)print(labels_all.shape)labels_all.head()اینجا 10222 تا سطر و 2 تا ستون id و breed حالا بیایم value انواع breed رو ببینیمbreeds_all = labels_all[&quotbreed&quot]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 zerosX_data = np.zeros((len(labels), 224, 224, 3), dtype='float32')# One hot encodingY_data = label_binarize(labels['breed'], classes = CLASS_NAMES)# Reading and converting image to numpy array and normalizing datasetfor 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 & sizeprint('\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 برای همین کاره. برای پری پراسس دیتا و اینا. 357 تا عکس داریم با سایز 224 در 224 و در چنل 3 یعنی RGB. ,وان هات هم 357 تا عکس داریم و 3 تا کلاس برای طبقه بندیحالا رسیدیم به ساخت مدل. 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 = &quotrelu&quot, kernel_regularizer = 'l2'))model.add(Dense(64, activation = &quotrelu&quot, kernel_regularizer = 'l2'))model.add(Dense(len(CLASS_NAMES), activation = &quotsoftmax&quot))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 setsX_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 setsX_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 modelepochs = 100batch_size = 128history = 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), '%')میبینیم که دقت خیلی بالایی داریم. یعنی 80 درصد از پیش بینی های مدل صحیح بودهبیایم یه نمونه تصویری هم مقایسه کنیم. # Plotting image to compareplt.imshow(X_test[1,:,:,:])plt.show()# Finding max value from predition list and comaparing original value vs predictedprint(&quotOriginally : &quot,labels['breed'][np.argmax(Y_test[1])])print(&quotPredicted : &quot,labels['breed'][np.argmax(Y_pred[1])])درست پیش بینی کرده اینجاس کدا.تمام.