{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"LỚP 19CLC5 - NHẬP MÔN AI\n* 19127097 - NGUYỄN NGỌC PHƯƠNG ANH\n* 19127078 - NGUYỄN ĐỖ THANH TRÚC\n* 19127142 - TRẦN THÁI ĐỨC HIẾU","metadata":{}},{"cell_type":"markdown","source":"Unzip file dữ liệu từ kaggle gồm 25000 ảnh chó mèo bằng cách tham gia cuộc thi dogs-vs-cats","metadata":{"id":"GteF2mZk1GGQ"}},{"cell_type":"code","source":"import os\nbase_dir = \"../input/dogs-vs-cats/\"\n\ntrain_link = os.path.join(base_dir, \"train.zip\")\ntest_link = os.path.join(base_dir, \"test1.zip\")\n\n# ../input/dogs-vs-cats-redux-kernels-edition/test.zip\nimport zipfile\nwith zipfile.ZipFile(train_link,\"r\") as z:\n z.extractall()\nwith zipfile.ZipFile(test_link,\"r\") as z:\n z.extractall()\n","metadata":{"execution":{"iopub.status.busy":"2021-08-24T07:02:35.740995Z","iopub.execute_input":"2021-08-24T07:02:35.741438Z","iopub.status.idle":"2021-08-24T07:02:54.645729Z","shell.execute_reply.started":"2021-08-24T07:02:35.741341Z","shell.execute_reply":"2021-08-24T07:02:54.644883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"BẮT ĐẦU CHẠY TỪ ĐÂY: Import các thư viện","metadata":{"id":"hrD6Z9f81XNd"}},{"cell_type":"code","source":"#Bước 1: Import thư viện\nimport numpy as np\nimport tensorflow as tf\nimport pandas as pd\nimport os\nimport cv2\nimport matplotlib.pyplot as plt\nimport tensorflow.keras\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator,load_img\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D\nfrom keras.models import load_model\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D,MaxPooling2D, Dropout,Flatten,Dense,Activation, BatchNormalization\nfrom sklearn.model_selection import train_test_split","metadata":{"id":"VnC9wvdC1fom","execution":{"iopub.status.busy":"2021-08-24T07:02:58.739238Z","iopub.execute_input":"2021-08-24T07:02:58.739597Z","iopub.status.idle":"2021-08-24T07:03:03.866571Z","shell.execute_reply.started":"2021-08-24T07:02:58.739567Z","shell.execute_reply":"2021-08-24T07:03:03.865743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 2: Xác định các thuộc tính hình ảnh - Kích thước, chiều\nImage_Channels=3\nImage_Width=224\nImage_Height=224\nImage_Size=(Image_Width,Image_Height)\n\ntrain_link  = \"../working/train\"\ntest_link  = \"../working/test1\"","metadata":{"execution":{"iopub.status.busy":"2021-08-24T07:03:19.622567Z","iopub.execute_input":"2021-08-24T07:03:19.622917Z","iopub.status.idle":"2021-08-24T07:03:19.62762Z","shell.execute_reply.started":"2021-08-24T07:03:19.622887Z","shell.execute_reply":"2021-08-24T07:03:19.626592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Đánh label cho dữ liệu, 0 là mèo; 1 là chó\n","metadata":{"id":"_3KBSrWq1LkR"}},{"cell_type":"code","source":"# Bước 3: Chuẩn bị bộ dữ liệu\nfilenames=os.listdir(train_link)\n\ncategories=[]\nfor f_name in filenames:\n    category=f_name.split('.')[0]\n    if category=='dog':\n        categories.append(1)\n    else:\n        categories.append(0)\n\ndf=pd.DataFrame({\n    'filename':filenames,\n    'category':categories\n})\n","metadata":{"id":"eNeOky-cSKOD","execution":{"iopub.status.busy":"2021-08-24T07:03:21.522912Z","iopub.execute_input":"2021-08-24T07:03:21.523266Z","iopub.status.idle":"2021-08-24T07:03:21.56998Z","shell.execute_reply.started":"2021-08-24T07:03:21.523214Z","shell.execute_reply":"2021-08-24T07:03:21.569172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Callbacks dừng lại sau 4 vòng với val_accuracy tăng quá ít và lưu lại model tốt nhất","metadata":{"id":"Fc4mcL6c1YN4"}},{"cell_type":"code","source":"#Bước 4: Định nghĩa callbacks và learning rate\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor = 'val_accuracy', \n    mode = 'auto',\n    verbose = 1, \n    patience = 4\n    )\nmodel_checkpoint = tf.keras.callbacks.ModelCheckpoint(\n    filepath = \"checkpoint.h5\",\n    monitor = 'val_accuracy', \n    save_best_only = True, \n    mode = 'auto'\n    )\n\ncallbacks = [early_stopping, model_checkpoint]","metadata":{"id":"0uJ2Gvnc1hNy","execution":{"iopub.status.busy":"2021-08-24T07:03:23.209823Z","iopub.execute_input":"2021-08-24T07:03:23.210136Z","iopub.status.idle":"2021-08-24T07:03:23.215437Z","shell.execute_reply.started":"2021-08-24T07:03:23.210108Z","shell.execute_reply":"2021-08-24T07:03:23.21445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Hàm tách dự liệu ra thành validation set và train set, tỉ lệ 1:4","metadata":{"id":"9JNg8DJ63o-h"}},{"cell_type":"code","source":"# Bước 5: Quản lý dữ liệu - chia tập vali và train\ndf[\"category\"] = df[\"category\"].replace({0:'cat',1:'dog'})\ntrain_df,validate_df = train_test_split(df,test_size=0.25,\n  random_state=42)\n\ntrain_df = train_df.reset_index(drop=True)\nvalidate_df = validate_df.reset_index(drop=True)\n\nbatch_size=32 \n","metadata":{"id":"q7r1jYmZTdUr","execution":{"iopub.status.busy":"2021-08-24T07:03:24.924831Z","iopub.execute_input":"2021-08-24T07:03:24.92515Z","iopub.status.idle":"2021-08-24T07:03:24.950361Z","shell.execute_reply.started":"2021-08-24T07:03:24.925119Z","shell.execute_reply":"2021-08-24T07:03:24.949575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Điều chỉnh độ chính xác, cho phép xoay ảnh, rescale, zoom, etc; resize ảnh về ImageSize","metadata":{"id":"targvs7o36og"}},{"cell_type":"code","source":"#Bước 6: Generate tập dữ liệu và điều chỉnh\ntrain_datagen = ImageDataGenerator(rescale=1.0/255.0, width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True)\nval_datagen = ImageDataGenerator(rescale=1.0/255.0)\n\ntrain_generator = train_datagen.flow_from_dataframe(train_df,train_link,x_col='filename',y_col='category',class_mode='binary', batch_size=batch_size, target_size=Image_Size)\nvalidation_generator = val_datagen.flow_from_dataframe(validate_df,train_link,x_col='filename',y_col='category',class_mode='binary', batch_size=batch_size, target_size=Image_Size)\n","metadata":{"executionInfo":{"elapsed":6840,"status":"ok","timestamp":1629684176917,"user":{"displayName":"Anh Nguyen","photoUrl":"","userId":"00496765616667538127"},"user_tz":-420},"id":"OB8HgK5irQNH","outputId":"aa6a4967-e821-4f91-cec8-f5c72a7ae615","execution":{"iopub.status.busy":"2021-08-24T07:03:28.52316Z","iopub.execute_input":"2021-08-24T07:03:28.523564Z","iopub.status.idle":"2021-08-24T07:03:28.810114Z","shell.execute_reply.started":"2021-08-24T07:03:28.523532Z","shell.execute_reply":"2021-08-24T07:03:28.808603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 7: Build model khi CHƯA CÓ MODEL (không load model)\n\n\nmodel = Sequential()\n\nmodel.add(Conv2D(64, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block1_conv1', input_shape=(224, 224, 3)))\nmodel.add(Conv2D(64, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block1_conv2'))\nmodel.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), name='block1_maxpool'))\n\nmodel.add(Conv2D(128, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block2_conv1'))\nmodel.add(Conv2D(128, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block2_conv2'))\nmodel.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), name='block2_maxpool'))\n\nmodel.add(Conv2D(256, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block3_conv1'))\nmodel.add(Conv2D(256, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block3_conv2'))\nmodel.add(Conv2D(256, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block3_conv3'))\nmodel.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), name='block3_maxpool'))\n\nmodel.add(Conv2D(512, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block4_conv1'))\nmodel.add(Conv2D(512, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block4_conv2'))\nmodel.add(Conv2D(512, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block4_conv3'))\nmodel.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), name='block4_maxpool'))\n\nmodel.add(Conv2D(512, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block5_conv1'))\nmodel.add(Conv2D(512, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block5_conv2'))\nmodel.add(Conv2D(512, (3,3), activation=\"relu\", padding=\"same\", kernel_initializer='he_uniform', name='block5_conv3'))\nmodel.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), name='block5_maxpool'))\n\nmodel.add(Flatten())\nmodel.add(Dense(4096, activation='relu'))\nmodel.add(Dense(4096, activation='relu'))\nmodel.add(Dense(1, activation='sigmoid'))\n","metadata":{"id":"st2SW22xpEfn","execution":{"iopub.status.busy":"2021-08-23T11:45:52.111033Z","iopub.execute_input":"2021-08-23T11:45:52.111635Z","iopub.status.idle":"2021-08-23T11:45:52.287308Z","shell.execute_reply.started":"2021-08-23T11:45:52.111596Z","shell.execute_reply":"2021-08-23T11:45:52.286398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 8: compile và đánh giá - KHÔNG CHẠY KHI DÙNG MODEL LOAD LẠI\nopt=tf.keras.optimizers.SGD(learning_rate=0.001,momentum=0.9) \n\nmodel.compile(optimizer=opt,\n              loss='binary_crossentropy',\n              metrics=['accuracy'])\n\nmodel.summary()","metadata":{"id":"jLwvV0vXwQR3","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 9: Fit model (training) - CHẠY KHI LOAD MODEL để kiểm tra accuracy hiện tại rồi tắt đi\nhistory = model.fit_generator(generator=train_generator, \n                              steps_per_epoch=len(train_generator), \n                              validation_data=validation_generator, \n                              validation_steps=len(validation_generator), \n                              epochs=1, \n                              verbose=1,\n                              callbacks=callbacks)","metadata":{"id":"w8OG2nYT4PmW","outputId":"4de53b8e-cf30-4acc-9244-6717a585863f","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 10: Load lại model:\nmodel = load_model(\"../input/latest-model/latest_model.h5\")","metadata":{"execution":{"iopub.status.busy":"2021-08-24T07:03:34.704552Z","iopub.execute_input":"2021-08-24T07:03:34.70487Z","iopub.status.idle":"2021-08-24T07:03:48.487411Z","shell.execute_reply.started":"2021-08-24T07:03:34.704841Z","shell.execute_reply":"2021-08-24T07:03:48.486571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 10.5: Lưu mô hình \nmodel.save(\"latest_model1.h5\")","metadata":{"id":"ozHy68JKTv1T","execution":{"iopub.status.busy":"2021-08-23T14:12:30.49128Z","iopub.execute_input":"2021-08-23T14:12:30.491615Z","iopub.status.idle":"2021-08-23T14:12:33.433134Z","shell.execute_reply.started":"2021-08-23T14:12:30.491583Z","shell.execute_reply":"2021-08-23T14:12:33.43202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 11: Chuẩn bị dữ liệu thử nghiệm\ntest_link=\"./test1\"\ntest_filenames = os.listdir(test_link)","metadata":{"executionInfo":{"elapsed":4875,"status":"ok","timestamp":1629624487429,"user":{"displayName":"Anh Nguyen","photoUrl":"","userId":"00496765616667538127"},"user_tz":-420},"id":"VItASyfkuGCx","outputId":"2077463c-4be6-4bb8-f10a-b958e3974da1","execution":{"iopub.status.busy":"2021-08-24T07:04:49.966803Z","iopub.execute_input":"2021-08-24T07:04:49.967141Z","iopub.status.idle":"2021-08-24T07:04:49.979498Z","shell.execute_reply.started":"2021-08-24T07:04:49.967111Z","shell.execute_reply":"2021-08-24T07:04:49.978522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 12: Dự đoán kết quả trên 1 số ảnh\n\ndog_counter = 0 \ncat_counter  = 0\n\nfor file in test_filenames:\n    img = image.load_img(test_link + \"/\" + file, target_size=(224,224))\n    x = cv2.imread(test_link + \"/\" + file)\n    x = cv2.resize(x, Image_Size)\n   \n    classes = model.predict(np.expand_dims(x, axis=0))[0]\n        \n    if classes == 0:\n      plt.xlabel(\"cat\")\n      plt.imshow(img)\n      plt.show()\n      cat_counter += 1\n    else:\n      plt.xlabel(\"dog\")\n      plt.imshow(img)\n      plt.show()\n      dog_counter += 1\n        \n    if(cat_counter==10): break\n\n      \nprint(\"Total Dogs :\",dog_counter)\nprint(\"Total Cats :\",cat_counter)","metadata":{"execution":{"iopub.status.busy":"2021-08-24T07:04:52.351957Z","iopub.execute_input":"2021-08-24T07:04:52.352285Z","iopub.status.idle":"2021-08-24T07:04:58.474948Z","shell.execute_reply.started":"2021-08-24T07:04:52.352257Z","shell.execute_reply":"2021-08-24T07:04:58.474066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 13: Test 1 ảnh truyền vào - CHẠY NẾU MUỐN TEST 1 ẢNH = TAY\ndef predict_(link):\n    image = cv2.imread(link)\n    image = cv2.resize(image, (224,224))\n    preds = model.predict(np.expand_dims(image, axis=0))[0]\n    plt.imshow(image)\n    plt.show()\n    if preds==0:\n            print(\"Predicted Label:Cat\")\n    else:\n            print(\"Predicted Label: Dog\")\n        \n        \npredict_(\"../input/testcase/con_meo_cua_truc.jpg\")","metadata":{"executionInfo":{"elapsed":7652,"status":"ok","timestamp":1629613479882,"user":{"displayName":"Anh Nguyen","photoUrl":"","userId":"00496765616667538127"},"user_tz":-420},"id":"Ax3S_KHZT3ai","outputId":"f215cbae-e116-4ac9-cfb3-cdcbd17a11cb","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Bước 14: Đánh giá tỉ lệ chính xác - SAU KHI TRAIN N EPOCHS (KHÔNG DÙNG NẾU LOAD MODEL)\nimport sys\n\n# Plot diagnostic learning curves\ndef summarize_diagnostics(history):\n\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.title('model accuracy')\n    plt.ylabel('accuracy')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'val'], loc='upper left')\n    plt.show()\n\n    plt.plot(history.history['loss'])\n    plt.plot(history.history['val_loss'])\n    plt.title('model loss')\n    plt.ylabel('loss')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'val'], loc='upper left')\n    plt.show()\n\n# Learning curves\nsummarize_diagnostics(history)","metadata":{"execution":{"iopub.status.busy":"2021-08-24T06:31:39.221024Z","iopub.execute_input":"2021-08-24T06:31:39.221378Z","iopub.status.idle":"2021-08-24T06:31:39.483814Z","shell.execute_reply.started":"2021-08-24T06:31:39.221349Z","shell.execute_reply":"2021-08-24T06:31:39.482864Z"},"trusted":true},"execution_count":null,"outputs":[]}]}