{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.10","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"},{"sourceId":28903,"sourceType":"datasetVersion","datasetId":22535},{"sourceId":30378,"sourceType":"datasetVersion","datasetId":23777},{"sourceId":1569529,"sourceType":"datasetVersion","datasetId":927555}],"dockerImageVersionId":30097,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<p style=\"font-size: 20px; font-style: normal; color: #36609A; font-weight: bold\"><strong>Phân loại chó và mèo</strong></p>\nxây dựng một mô hình CNN cơ bản và phân loại chó và mèo từ hình ảnh, dựa trên việc học đặc trưng trong các lớp ẩn và bản đồ kích hoạt trong CNN.\n\nDòng công việc như thế nào?\n<ul>\n    <li>Trước tiên, tôi sẽ khám phá bộ dữ liệu và cố gắng thực hiện EDA (phân tích dữ liệu khám phá) của dữ liệu.</li>\n    <li>Sau đó, tiền xử lý dữ liệu theo yêu cầu, điều này bao gồm tăng cường hình ảnh, co giãn và những điều cần thiết khác.</li>\n    <li>Thử xây dựng một mô hình CNN cơ bản và cố gắng dự đoán loài như một vấn đề phân loại nhị phân.</li>\n    <li>Sau đó, thử nghiệm dự đoán với việc chuyển giao học sâu bằng ResNet50 và trọng số imagenet.</li>\n    <li>Cuối cùng, so sánh kết quả giữa CNN cơ bản và ResNet50 với dữ liệu mẫu.</li>\n</ul>\n\n\n","metadata":{}},{"cell_type":"markdown","source":"**Công Việc Ban Đầu**","metadata":{}},{"cell_type":"markdown","source":"**Thêm Thư Viện**","metadata":{}},{"cell_type":"code","source":"class color:\n    BOLD = '\\033[1m'\n    BOLD_COLOR = '\\033[1m' + '\\033[93m'\n    END = '\\033[0m'\n\n\n\n# loading libraries\nprint(color.BOLD + '\\nImporting requreid libraries....\\n'+ color.END)\n\nimport warnings \nwarnings.filterwarnings('ignore')\n\n# basic librareis\nimport zipfile\nimport glob\nimport os\nimport pandas as pd\nimport numpy as np\nfrom PIL import Image\n\n\n# plotting and visualizations\nimport matplotlib \nimport matplotlib.pyplot as plt \n%matplotlib inline\nimport seaborn as sns \nimport missingno as msno\n\n# preprocessing\nfrom keras.preprocessing.image import (ImageDataGenerator, \n                                       img_to_array, \n                                       array_to_img, \n                                       load_img)\n\nfrom sklearn.model_selection import train_test_split\n\n# metrics\nfrom sklearn.metrics import (confusion_matrix, \n                             classification_report, \n                             accuracy_score, \n                             f1_score, \n                             roc_auc_score)\n# modeling\nimport tensorflow as tf\nfrom keras.models import Model,Sequential\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Dense,Flatten\n\nfrom keras.applications import resnet50\nfrom keras.applications.resnet50 import preprocess_input\nfrom keras import optimizers\nfrom keras import regularizers\nfrom keras.callbacks import EarlyStopping,LearningRateScheduler\n\n\nfrom keras import backend as K\nK.clear_session()\n\n# model plotting\nfrom IPython.display import SVG\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.utils import plot_model\n\n# mesc\nfrom sklearn.utils import shuffle\n\n\n\n\n\nprint(color.BOLD_COLOR + 'Done!!!'+ color.END)\n","metadata":{"id":"ZDKIXSLKKZQA","outputId":"37b1912c-460a-412d-cfca-9a165cb95bb5","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:52:34.388148Z","iopub.execute_input":"2024-01-13T20:52:34.388606Z","iopub.status.idle":"2024-01-13T20:52:40.526854Z","shell.execute_reply.started":"2024-01-13T20:52:34.388514Z","shell.execute_reply":"2024-01-13T20:52:40.525855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Trích Xuất Nhãn Từ Tên Các Hình Ảnh**","metadata":{}},{"cell_type":"code","source":"# extraction of train and test data from zipfiles to data folder\nprint('\\n'+color.BOLD_COLOR + 'Extracting the data from dataset.....'+ color.END +'\\n')\nzip_files = glob.glob('/kaggle/input/dogs-vs-cats/*.zip')\n\nprint('{} files found in the input directory'.format(color.BOLD + str(len(zip_files)) + color.END) +'\\n')\nfor file in zip_files:\n    with zipfile.ZipFile(file, 'r') as Z:\n        Z.extractall('data')\n    print ('{} is extracted'.format(color.BOLD + file.split('/')[-1] + color.END) + '\\n')\n      \nprint( color.BOLD_COLOR +'Extraction is completed'+ color.END +'\\n')\n    \n  ","metadata":{"id":"VX8NiXN4Kw16","outputId":"81f2612e-2982-45ac-d046-6fec3c9a7289","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:54:02.074958Z","iopub.execute_input":"2024-01-13T20:54:02.075370Z","iopub.status.idle":"2024-01-13T20:54:26.409629Z","shell.execute_reply.started":"2024-01-13T20:54:02.075338Z","shell.execute_reply":"2024-01-13T20:54:26.408534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Total number of images in train and test datasets\n\ntrain_dir = '/kaggle/working/data/train/'\ntest_dir  = '/kaggle/working/data/test1/'\nprint(color.BOLD +\"Total Images in Train, and Test Data...\" +color.END)\nprint('\\n' + color.BOLD_COLOR + 'No. of Train Images: '+ color.END + color.BOLD + str(len(os.listdir(train_dir))) + color.END)\nprint( color.BOLD_COLOR + 'No. of Test Images: ' + color.END + color.BOLD + str(len(os.listdir(test_dir))) + color.END + '\\n')        ","metadata":{"id":"jeiIIza1K3-x","outputId":"caf36cf7-6fd5-49be-8557-a4eb3b2e944f","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:54:26.445199Z","iopub.execute_input":"2024-01-13T20:54:26.445604Z","iopub.status.idle":"2024-01-13T20:54:26.477116Z","shell.execute_reply.started":"2024-01-13T20:54:26.445562Z","shell.execute_reply":"2024-01-13T20:54:26.475989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# category and filepath extraction helper functions\n\ndef category(path): \n    return [file.split('.')[0] for file in os.listdir(path)]\n\ndef filename(path):\n    return [file for file in os.listdir(path)]\n\n# image names and labels\nx_train_imgname = filename(train_dir) \nx_test_imgname = filename(test_dir)\ny_train_label = category(train_dir)\n\n#creation of total dataframe and submission dataframe\nprint( '\\n'+color.BOLD + 'Image data is storing into dataframes...'+ color.END + '\\n')\ntrain_image_df = pd.DataFrame({ 'filename': x_train_imgname, 'category': y_train_label})\nsubmission_image_df = pd.DataFrame({'filename': x_test_imgname})\n\nprint(color.BOLD +'Training image names and labels are read to '+ color.END + color.BOLD_COLOR +'train_image_df' + color.END + '\\n')\nprint(color.BOLD +'Testing image names are read to '+ color.END + color.BOLD_COLOR + 'submission_image_df'+ color.END + '\\n')\n\n","metadata":{"id":"ZkS8Las2KyHK","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:54:39.980537Z","iopub.execute_input":"2024-01-13T20:54:39.980894Z","iopub.status.idle":"2024-01-13T20:54:40.053196Z","shell.execute_reply.started":"2024-01-13T20:54:39.980864Z","shell.execute_reply":"2024-01-13T20:54:40.052164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Trực quan hóa Dữ liệu**","metadata":{}},{"cell_type":"markdown","source":"**trích xuất đường dẫn và trực quan hóa hình ảnh huấn luyện**","metadata":{}},{"cell_type":"code","source":"print(color.BOLD +'\\n'+'Helper funtions for image path,id, category data extractions and Image visualizations' +'\\n'+color.END)\n# helper functions \n\ndef img_path(directory):\n    ''' \n    This function extracts image ids, category,and image paths from directory.\n    input:\n    directiory: Path to location of images\n    Return:\n    ID_no: list of image ids\n    Paths: list of image paths\n    cate: list of category\n    '''\n    paths = []\n    cate = []\n    ID_no = []\n    for file in os.listdir(directory):\n        path = os.path.join(directory, file)\n        paths.append(path)\n        cate.append(file.split('.')[0])\n        ID_no.append(file.split('.')[1])\n    return ID_no, paths, cate\n\n\n\n\ndef showImages(data,num_row  = 3,num_col =  3, name = 'any', subtitle = 'off'):\n    \"\"\" This function creates a grid of images from  dataset.\n    Shuffled images will be displayed.\n    \n    Input: \n    num_row: default: 3, no. of rows in a grid\n    num_col: default:3, no. of columns in grid\n    data: Dataframe of paths \n    name:  default 'any', takes: cat, dog, any or something else would give both\n    subtitle: display id number for each image, defalult: 'off', takes: 'on' and 'off'\n    Return: None\n    \n    \"\"\"\n    \n    # little data sorting\n    cat_df,dog_df = data[data['Category'] == 'cat'], data[data['Category'] == 'dog']\n\n    \n    if name == 'dog':\n        X, Y  = dog_df['img_paths'], dog_df['ID_no']\n    elif name == 'cat':\n        X, Y  = cat_df['img_paths'], cat_df['ID_no']     \n    else:\n        X, Y  = data['img_paths'], data['ID_no']     # could use try and except but lets stick to minimal code\n\n    (X_rand, Y_rand) = shuffle(X, Y)\n    \n    # showing images on matplotlib \n    \n    fig, ax = plt.subplots(num_row,num_col,figsize = (12,12), dpi = 100)\n    fig.patch.set_facecolor('#f5f6f6')\n    axes = ax.ravel()\n    \n    for idx,ax  in enumerate(axes):\n        x = load_img(X_rand.iloc[idx],target_size= (125, 125))\n        ax.imshow(x)\n        if subtitle == 'on':\n            ax.set_title(\"{}\".format(Y_rand.iloc[idx]))\n        else:\n            ax.set_title('')\n        ax.axis('off')\n        plt.subplots_adjust(wspace =0)\n        del x\n    #fig.tight_layout()\n    \n    fig.text(0.1,0.93, ' Chó hay Mèo ? : {}s from Training Data'.format(name.capitalize()),{'fontfamily':'serif','size':18,'weight':'bold'})\n    \n    return None\n","metadata":{"id":"taVy1YO0UrXj","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:57:17.780700Z","iopub.execute_input":"2024-01-13T20:57:17.781079Z","iopub.status.idle":"2024-01-13T20:57:17.797328Z","shell.execute_reply.started":"2024-01-13T20:57:17.781035Z","shell.execute_reply":"2024-01-13T20:57:17.796214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Implementing above function over train data set\nID_no, img_paths, train_images = img_path(train_dir)\n\nprint('\\n'+color.BOLD_COLOR + 'Dataframe is creating for training image visualization in a grid...' + color.END+'\\n' )\n#creating new dataframe for data visulaization\n\nvisual_df = pd.DataFrame({'ID_no':ID_no,'Category':train_images, 'img_paths': img_paths})\n\nprint(color.BOLD );print(visual_df.head(5))\n\nprint('\\n'+color.BOLD_COLOR +'Done!'+color.END + '\\n')","metadata":{"id":"wJWxS9aqaoo7","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:55:46.000045Z","iopub.execute_input":"2024-01-13T20:55:46.000458Z","iopub.status.idle":"2024-01-13T20:55:46.128336Z","shell.execute_reply.started":"2024-01-13T20:55:46.000424Z","shell.execute_reply":"2024-01-13T20:55:46.127360Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Xem các hình ảnh từ hình ảnh huấn luyện**","metadata":{}},{"cell_type":"code","source":"showImages(visual_df,5,5, name = 'chó', subtitle = 'off')","metadata":{"id":"y2OoIdtTaoPX","outputId":"15a528b6-fec1-4fcf-8cee-3108f3e92ad3","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:57:48.003713Z","iopub.execute_input":"2024-01-13T20:57:48.004163Z","iopub.status.idle":"2024-01-13T20:57:49.684760Z","shell.execute_reply.started":"2024-01-13T20:57:48.004123Z","shell.execute_reply":"2024-01-13T20:57:49.683552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"showImages(visual_df,5,5, name = 'mèo', subtitle = 'off')","metadata":{"id":"3IEE-WG-A4-g","outputId":"02bbb2de-055a-45c8-f447-b6519a11570f","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:57:55.318988Z","iopub.execute_input":"2024-01-13T20:57:55.319385Z","iopub.status.idle":"2024-01-13T20:57:57.253463Z","shell.execute_reply.started":"2024-01-13T20:57:55.319349Z","shell.execute_reply":"2024-01-13T20:57:57.252283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"showImages(visual_df,5,5, name = 'Cả chó và mèo', subtitle = 'off')","metadata":{"id":"yo7z0IwmWtHx","outputId":"65df8ea8-8a82-4788-a9cd-835ae1755229","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:58:09.069936Z","iopub.execute_input":"2024-01-13T20:58:09.070343Z","iopub.status.idle":"2024-01-13T20:58:10.765452Z","shell.execute_reply.started":"2024-01-13T20:58:09.070309Z","shell.execute_reply":"2024-01-13T20:58:10.764411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Chia dữ liệu thành tập huấn luyện và tập kiểm tra, sau đó trực quan hóa phân phối dữ liệu**","metadata":{"id":"up4ajfD3Qbky"}},{"cell_type":"code","source":"# Data split into train data and validation data\ntrain_valid_df, test_df = train_test_split(train_image_df, test_size = 0.04)\ntrain_df, valid_df = train_test_split(train_valid_df, test_size = 0.2)\n\ntrain_images = train_df.shape[0]\nvalid_images = valid_df.shape[0]\nholdon_images = test_df.shape[0]\ntest_images = submission_image_df.shape[0]\n\nprint('\\n'+color.BOLD_COLOR + 'Number of Training Images: ' + color.END + color.BOLD+ str(train_images)+ color.END)\nprint('\\n'+color.BOLD_COLOR +  'Number of Validating Images: ' + color.END + color.BOLD+ str(valid_images)+ color.END)\nprint( '\\n'+color.BOLD_COLOR +  'Number of Holdon Images: ' + color.END +  color.BOLD+ str(holdon_images)+ color.END)\nprint('\\n'+color.BOLD_COLOR + 'Number of Testing Images: ' + color.END +  color.BOLD+str(test_images)+ color.END)\n","metadata":{"id":"FKcypyT2QYYP","outputId":"93b7bb55-989c-4cbf-fe1c-23a9f5c77b68","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T20:58:41.966768Z","iopub.execute_input":"2024-01-13T20:58:41.967136Z","iopub.status.idle":"2024-01-13T20:58:41.985322Z","shell.execute_reply.started":"2024-01-13T20:58:41.967105Z","shell.execute_reply":"2024-01-13T20:58:41.984281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize =(8,8), dpi = 100)\nfig.patch.set_facecolor('#f5f6f6')\ngs = fig.add_gridspec(10,10)\n\nax0 = fig.add_subplot(gs[2:5,1:5])\nax1 = fig.add_subplot(gs[2:5,6:10])\nax2 = fig.add_subplot(gs[6:9,3:7])\n\n\naxes = [ax0,ax1,ax2]\ndata  = [train_df['category'] ,  valid_df['category'], test_df['category']]\nlabels = ['Training Data','Validation Data','Testing Data']\n\nfor ax in axes:\n    ax.set_facecolor('#f5f6f6')\n    ax.axes.get_yaxis().set_visible(False)\n    \n    for loc in ['left','right','top','bottom']:\n        ax.spines[loc].set_visible(False)\n    \nfor ax,df, label in zip(axes,data,labels):\n    sns.countplot(df, ax = ax, palette = [colors[2],colors[3]], alpha =1)\n    ax.set_xlabel(xlabel = ' ')\n    for pa in ax.patches: \n        ax.text(pa.get_x(), pa.get_height(),'{}'.format(pa.get_height()), **{'fontfamily':'serif', 'size':10, 'weight':'bold'}, alpha = 1)\n\n    ax.text(0,0,label,**{'fontfamily':'serif', 'size':10, 'weight':'bold'})\n\nfig.text(0.1,0.82, 'Phân phối hình ảnh',{'fontfamily':'serif','size':18,'weight':'bold'})\nfig.text(0.1,0.77, '''Tất cả các phân phối hình ảnh đều khá cân bằng, vì vậy hy vọng chúng ta có thể đạt được độ chính xác công bằng''',{'fontfamily':'serif','size':12,})\n\nfig.text(0.75,0.15,'© Made by dứa',{'fontfamily':'serif', 'size':10,  'color':'black'})\nfig.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:46:18.440156Z","iopub.execute_input":"2024-01-13T21:46:18.440578Z","iopub.status.idle":"2024-01-13T21:46:18.758691Z","shell.execute_reply.started":"2024-01-13T21:46:18.440536Z","shell.execute_reply":"2024-01-13T21:46:18.757668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Phân loại bằng CNN cơ bản**","metadata":{"id":"A8gmnjNu6m9J"}},{"cell_type":"markdown","source":"**chuẩn bị dữ liệu huấn luyện, kiểm tra và kiểm tra cho CNN cơ bản mà không có bất kỳ tăng cường dữ liệu nào.**","metadata":{}},{"cell_type":"code","source":"img_size = 224\nbatch_size = 128\n\nprint(color.BOLD_COLOR + '\\nPreparing train and validation images for training...' + color.END)\n# dataframe iterators without data agumnetation\n\ntrain_map = ImageDataGenerator()\nvalid_map = ImageDataGenerator()\ntest_map =  ImageDataGenerator()\n\nprint(color.BOLD)\n        \n#Creatinga a dataframe iterators for fitting\nvani_train_data = train_map.flow_from_dataframe(\n            train_df,train_dir,\n            x_col = 'filename',\n            y_col = 'category',\n            target_size = (img_size, img_size),\n            batch_size = batch_size,\n            class_mode = 'categorical')\n\nvani_valid_data = valid_map.flow_from_dataframe(\n             valid_df, train_dir,\n             x_col = 'filename',\n             y_col = 'category',\n             target_size = (img_size, img_size),\n             batch_size = batch_size,\n             class_mode = 'categorical')\n\n\nvani_test_data = test_map.flow_from_dataframe(\n             test_df, train_dir,\n             x_col = 'filename',\n             y_col = None,\n             target_size = (img_size, img_size),\n             batch_size = batch_size,\n             class_mode = None,\n             shuffle = False)\n\nprint(color.BOLD_COLOR + '\\nDone!')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:02:28.232610Z","iopub.execute_input":"2024-01-13T21:02:28.232991Z","iopub.status.idle":"2024-01-13T21:02:28.846082Z","shell.execute_reply.started":"2024-01-13T21:02:28.232960Z","shell.execute_reply":"2024-01-13T21:02:28.845156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**CNN model**","metadata":{}},{"cell_type":"code","source":"#Building model computational graph\nvani_model = Sequential()\nvani_model.add(Conv2D(16, (3,3), activation = 'relu', padding = 'same', input_shape = (224,224,3)))\nvani_model.add(Conv2D(16, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2), strides=(2,2)))\n\nvani_model.add(Conv2D(32, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(32, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2), strides=(2,2)))\n\nvani_model.add(Conv2D(64, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(64, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2),strides=(2,2)))\n\nvani_model.add(Conv2D(128, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(128, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2),strides=(2,2)))\n\nvani_model.add(Dropout(0.3))\n\nvani_model.add(Conv2D(256, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(Conv2D(256, (3,3), activation = 'relu', padding = 'same'))\nvani_model.add(MaxPooling2D(pool_size = (2,2),strides=(2,2)))\n\nvani_model.add(Dropout(0.3))\n\nvani_model.add(Flatten())\n\nvani_model.add(Dense(512, activation = 'relu'))\n\nvani_model.add(Dropout(0.5))\n\nvani_model.add(Dense(2, activation = 'softmax'))\n\nprint(color.BOLD_COLOR + '\\nVanilla Model layers and output shapes with params...\\n'+color.END)\n\nprint(color.BOLD)\nvani_model.summary()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:02:46.649887Z","iopub.execute_input":"2024-01-13T21:02:46.650269Z","iopub.status.idle":"2024-01-13T21:02:49.125091Z","shell.execute_reply.started":"2024-01-13T21:02:46.650236Z","shell.execute_reply":"2024-01-13T21:02:49.124127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**sơ đồ nguyên tắc của mô hình CNN cơ bản**","metadata":{}},{"cell_type":"code","source":"plot_model(vani_model, show_shapes = True,expand_nested = True,dpi = 80)\n#SVG(model_to_dot(vani_model).create(prog='dot', format='svg'))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:03:22.041120Z","iopub.execute_input":"2024-01-13T21:03:22.041524Z","iopub.status.idle":"2024-01-13T21:03:22.662129Z","shell.execute_reply.started":"2024-01-13T21:03:22.041492Z","shell.execute_reply":"2024-01-13T21:03:22.660991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**train and validate CNN model**","metadata":{}},{"cell_type":"code","source":"#compiling model with loss, opt, metrics\nloss = 'categorical_crossentropy'\nopt = tf.keras.optimizers.Adam(learning_rate= 0.0001,beta_1=0.9, beta_2=0.999,epsilon=1e-07)\nmetrics = ['accuracy']\n\nvani_model.compile(loss = loss, optimizer = opt, metrics = metrics)\n\nprint(color.BOLD_COLOR + 'Training on Vanilla CNN has started ....\\n'+ color.END)\nprint(color.BOLD)\n# fitting the model for training dataset\nvani_history = vani_model.fit(vani_train_data, epochs = 15,\n                          validation_data = vani_valid_data,\n                          validation_steps= valid_images//batch_size,\n                          steps_per_epoch= train_images//batch_size)\n\nprint(color.END)\nprint(color.BOLD_COLOR + '\\nDone!\\n'+ color.END)\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:03:52.433397Z","iopub.execute_input":"2024-01-13T21:03:52.433830Z","iopub.status.idle":"2024-01-13T21:44:07.511172Z","shell.execute_reply.started":"2024-01-13T21:03:52.433778Z","shell.execute_reply":"2024-01-13T21:44:07.509971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**biểu đồ thay đổi của mô hình CNN cơ bản trong độ mất mát và độ chính xác theo số epoch**","metadata":{}},{"cell_type":"code","source":"fig,ax  = plt.subplots(2,1, figsize =(8,8), dpi = 100)\nfig.patch.set_facecolor('#f5f6f6')\n\naxes  = ax.ravel()\n\nfor ax in axes:\n    ax.set_facecolor('#f5f6f6')\n    for loc in ['right','top',]:\n        ax.spines[loc].set_visible(False)\n        \nhist1 = vani_history.history\nEpochs =  range(len(hist1['loss']))\n\n## loss plot\nsns.lineplot(x = Epochs, y = hist1['val_loss'],  ax = axes[0], linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist1['loss'], ax  = axes[0], linewidth =4,  color = colors[4])\n\n\naxes[0].text(Epochs[-1]+0.25,hist1['val_loss'][-1],'Validation Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[0].text(Epochs[-1]+0.25,hist1['loss'][-1] ,'Training Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\n# accuracy plot\nsns.lineplot(x = Epochs, y = hist1['val_accuracy'],ax = axes[1],linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist1['accuracy'],ax = axes[1],linewidth =4,  color = colors[4])\naxes[1].text(Epochs[-1]+0.25,hist1['val_accuracy'][-1],'Validation Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[1].text(Epochs[-1]+0.25,hist1['accuracy'][-1] ,'Training Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\nfig.text(0,1.06, ' Vanilla Loss and Accuracy ',{'fontfamily':'serif', 'size':18, 'weight':'bold'})\nfig.text(0,1.01, '''Sự giảm của loss_hist và tăng của acc_hist sau mỗi epoch là tích cực và chứng tỏ mô hình của đang học tốt.''',{'fontfamily':'serif', 'size':12})\n        \nfig.text(0.75,-0.05,'© Made by dứa',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.tight_layout(h_pad = 5)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:46:00.370241Z","iopub.execute_input":"2024-01-13T21:46:00.370627Z","iopub.status.idle":"2024-01-13T21:46:00.912125Z","shell.execute_reply.started":"2024-01-13T21:46:00.370594Z","shell.execute_reply":"2024-01-13T21:46:00.911204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**confusion matrix**","metadata":{}},{"cell_type":"code","source":"vani_pred = vani_model.predict_generator(vani_test_data)\ntest_df['vani_pred'] = np.argmax(vani_pred, axis = -1)\nlabels = dict((v,k) for k,v in vani_train_data.class_indices.items())\n\ntest_df['vani_pred'] = test_df['vani_pred'].map(labels)\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:45:27.137314Z","iopub.execute_input":"2024-01-13T21:45:27.137713Z","iopub.status.idle":"2024-01-13T21:45:38.696251Z","shell.execute_reply.started":"2024-01-13T21:45:27.137678Z","shell.execute_reply":"2024-01-13T21:45:38.695165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_confusion_matrix(cf,\n                          group_names=None,\n                          categories='auto',\n                          count=True,\n                          percent=True,\n                          cbar=True,\n                          xyticks=True,\n                          xyplotlabels=True,\n                          sum_stats=True,\n                          figsize=None,\n                          cmap='Blues',\n                          title=None):\n\n\n    # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n    blanks = ['' for i in range(cf.size)]\n\n    if group_names and len(group_names)==cf.size:\n        group_labels = [\"{}\\n\".format(value) for value in group_names]\n    else:\n        group_labels = blanks\n\n    if count:\n        group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n    else:\n        group_counts = blanks\n\n    if percent:\n        group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n    else:\n        group_percentages = blanks\n\n    box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n    box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n\n\n    # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n    if sum_stats:\n        #Accuracy is sum of diagonal divided by total observations\n        accuracy  = np.trace(cf) / float(np.sum(cf))\n\n        #if it is a binary confusion matrix, show some more stats\n        if len(cf)==2:\n            #Metrics for Binary Confusion Matrices\n            precision = cf[1,1] / sum(cf[:,1])\n            recall    = cf[1,1] / sum(cf[1,:])\n            f1_score  = 2*precision*recall / (precision + recall)\n            stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(\n                accuracy,precision,recall,f1_score)\n        else:\n            stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n    else:\n        stats_text = \"\"\n\n\n    # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n    if figsize==None:\n        #Get default figure size if not set\n        figsize = plt.rcParams.get('figure.figsize')\n\n    if xyticks==False:\n        #Do not show categories if xyticks is False\n        categories=False\n\n\n    # MAKE THE HEATMAP VISUALIZATION\n    fig = plt.figure(figsize=figsize)\n    fig.patch.set_facecolor('#f5f6f6')\n    sns.heatmap(cf,annot=box_labels,fmt=\"\",linewidths = 1,square = True,linecolor= '#f5f6f6',\n                cmap=cmap,cbar=cbar,annot_kws={'fontfamily':'serif','size':18,'weight':'bold'},\n                xticklabels=categories,\n                yticklabels=categories,)\n\n    if xyplotlabels:\n        plt.ylabel('True label', **{'fontfamily':'serif','size':12,'weight':'bold'})\n        plt.xlabel('Predicted label' + stats_text,**{'fontfamily':'serif','size':12,'weight':'bold'})\n    else:\n        plt.xlabel(stats_text,**{'fontfamily':'serif','size':12,'weight':'bold'})\n    \n    plt.gca().set_xticklabels(categories, {'fontfamily':'serif','size':16,'weight':'bold'})\n    plt.gca().set_yticklabels(categories, {'fontfamily':'serif','size':16,'weight':'bold'})","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:46:38.501720Z","iopub.execute_input":"2024-01-13T21:46:38.502106Z","iopub.status.idle":"2024-01-13T21:46:38.521214Z","shell.execute_reply.started":"2024-01-13T21:46:38.502075Z","shell.execute_reply":"2024-01-13T21:46:38.520142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vani_cf_matrix = confusion_matrix(test_df['category'],test_df['vani_pred'])\nmy_cols = [colors[3],colors[2]]\n\nlabels = [ 'True Neg','False Pos','False Neg','True Pos']\ncategories = ['Cat', 'Dog']\nmake_confusion_matrix(vani_cf_matrix,figsize = (10,5),\n                      group_names=labels,cbar = False,cmap = matplotlib.colors.LinearSegmentedColormap.from_list(\"\",my_cols),\n                      categories=categories, \n                      title = 'Vanila CNN comfusion matrix')\n\nplt.gcf().text(0,1.1,' Vanilla CNN Test Data Evaluation',{'fontfamily':'serif', 'size':24,  'color':'black', 'weight':'bold'})\nplt.gcf().text(0,0.995,\"\"\"F1 Score 87%\"\"\",{'fontfamily':'serif', 'size':14,  'color':'black', })\n\nplt.gcf().text(0.85,-0.15,'© Made by dứa',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.gcf().show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:48:01.140341Z","iopub.execute_input":"2024-01-13T21:48:01.140726Z","iopub.status.idle":"2024-01-13T21:48:01.330868Z","shell.execute_reply.started":"2024-01-13T21:48:01.140695Z","shell.execute_reply":"2024-01-13T21:48:01.329838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n**Data Agumentation, Early Stopping, Learning Rate Schedule**","metadata":{}},{"cell_type":"markdown","source":"**hàm hỗ trợ để trực quan hóa tăng cường ảnh**","metadata":{}},{"cell_type":"code","source":"print(color.BOLD +'\\n'+'Helper funtions for Image Agumentation visualizations' +'\\n'+color.END)\n\ndef data_argumentation_show(n, grid_size):\n    sample_aug_map = ImageDataGenerator(\n            #zoom_range = 0.1,\n            rotation_range = 25,\n            horizontal_flip = True,\n            height_shift_range =0.2,\n            width_shift_range = 0.2,\n            fill_mode='nearest',\n            rescale = 1/255)\n    sample_data = sample_aug_map.flow_from_dataframe(\n            (train_df.sample(n)),\n            train_dir,\n            x_col = 'filename',\n            y_col = 'category',\n            target_size = (img_size, img_size),\n            class_mode = 'categorical')\n  \n  #subplot grid \n    fig = plt.figure(figsize = (10,10))\n    fig.patch.set_facecolor('#f5f6f6')\n    for i in range(0,grid_size*grid_size):\n        plt.subplot(grid_size,grid_size, i+1)\n        for x,y in sample_data:\n            img = x[0]\n            plt.imshow(img)\n            plt.axis('off')\n            break\n            plt.tight_layout()\n            del img\n    fig.show()\n\n     \n    fig.text(0.1,0.93, ' Tăng cường ảnh',{'fontfamily':'serif','size':20,'weight':'bold'})\n    \n    return None\n\n","metadata":{"id":"1xh9oi9dQYdu","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:49:58.194846Z","iopub.execute_input":"2024-01-13T21:49:58.195262Z","iopub.status.idle":"2024-01-13T21:49:58.206501Z","shell.execute_reply.started":"2024-01-13T21:49:58.195221Z","shell.execute_reply":"2024-01-13T21:49:58.205378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# To visulalize the effect of data argumentation \n#select number of samples to argument----> n = \n# total number of argumentation is grid_Size**2\n\ndata_argumentation_show(1, 5)","metadata":{"id":"VXw80kw6QYbi","outputId":"7c0ee447-836a-4198-8687-38d4bfc415f0","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:50:02.854300Z","iopub.execute_input":"2024-01-13T21:50:02.854687Z","iopub.status.idle":"2024-01-13T21:50:04.411737Z","shell.execute_reply.started":"2024-01-13T21:50:02.854655Z","shell.execute_reply":"2024-01-13T21:50:04.410771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_argumentation_show(2, 5)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:50:08.568499Z","iopub.execute_input":"2024-01-13T21:50:08.568882Z","iopub.status.idle":"2024-01-13T21:50:10.374917Z","shell.execute_reply.started":"2024-01-13T21:50:08.568846Z","shell.execute_reply":"2024-01-13T21:50:10.373935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Hàm Thiết lập Tốc độ học giảm**","metadata":{}},{"cell_type":"code","source":"print(color.BOLD + '\\nSetting a decay learning rate for learning rate schedule\\n'+ color.END)\nepoch = 50\nlearning_rate = 3e-5 \nlr_start = 0.00000001\nlr_min = 0.000001\nlr_max = 3e-5 \nlr_rampup_epochs = 1\nlr_sustain_epochs = 1\nlr_exp_decay = .8\n\ndef lrfn(epoch):\n    if epoch < lr_rampup_epochs:\n        lr = (lr_max - lr_start) / lr_rampup_epochs * epoch + lr_start\n    elif epoch < lr_rampup_epochs + lr_sustain_epochs:\n        lr = lr_max\n    else:\n        lr = (lr_max - lr_min) * lr_exp_decay**(epoch - lr_rampup_epochs - lr_sustain_epochs) + lr_min\n    return lr\n    \nprint(color.BOLD_COLOR + 'Done!' +color.END)\n","metadata":{"id":"Hdjed4u7oYx8","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:50:47.083927Z","iopub.execute_input":"2024-01-13T21:50:47.084329Z","iopub.status.idle":"2024-01-13T21:50:47.093131Z","shell.execute_reply.started":"2024-01-13T21:50:47.084295Z","shell.execute_reply":"2024-01-13T21:50:47.092122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 20\nepochs_range = [i for i in range(50 if epochs<50 else epochs)]\nlearn_rate = [lrfn(x) for x in epochs_range]\n\n\nfig,ax = plt.subplots(figsize = (10,5))\nfig.patch.set_facecolor('#f5f6f6')\nax.set_facecolor('#f5f6f6')\n\nfor loc in ['right','top',]:\n    ax.spines[loc].set_visible(False)\n\nax.plot(epochs_range, learn_rate, linewidth = 4, color= colors[2]) \nplt.xlabel('Range of epochs',{'fontfamily':'serif', 'size':14,  'color':'black', 'weight':'bold'})\nplt.ylabel('Learning rate in 10^-5',{'fontfamily':'serif', 'size':14,  'color':'black', 'weight':'bold'})\n\n\nplt.gcf().text(0,1.06,'Tốc Độ Học',{'fontfamily':'serif', 'size':24,  'color':'black', 'weight':'bold'})\nplt.gcf().text(0,0.975,\"\"\"Ban đầu, đặt một tỷ lệ học tăng tuyến tính từ 1e-08 đến 3e-05, và sau đó giảm một cách mũi tên từ 3e-05 đến 1e-06\"\"\",{'fontfamily':'serif', 'size':14,  'color':'black', })\n\nplt.gcf().text(0.75,0,'© Made by dứa',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.gcf().show()","metadata":{"id":"v79OSrS0FWvK","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:51:57.453832Z","iopub.execute_input":"2024-01-13T21:51:57.454249Z","iopub.status.idle":"2024-01-13T21:51:57.681661Z","shell.execute_reply.started":"2024-01-13T21:51:57.454210Z","shell.execute_reply":"2024-01-13T21:51:57.680630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Phân loại bằng ResNet50**","metadata":{"id":"b5wQCvt-njNa"}},{"cell_type":"markdown","source":"**Chuẩn bị dữ liệu tăng cường hình ảnh với ImageDataGenerator**","metadata":{}},{"cell_type":"code","source":"print(color.BOLD_COLOR + '\\n Agumenting Train, Validation images... and testing images just passing through... \\n'+ color.END)\n\nprint(color.BOLD)\n# using standard data augumentation\n\ntrain_aug_map = ImageDataGenerator(\n                    rotation_range=10,\n                    #zoom_range=0.1,\n                    horizontal_flip=True,\n                    fill_mode='nearest',\n                    #width_shift_range=0.1,\n                    #height_shift_range=0.1,\n                    preprocessing_function = preprocess_input)\nres_train_data = train_aug_map.flow_from_dataframe(\n            train_df, train_dir,\n            x_col = 'filename',\n            y_col = 'category',\n            target_size = (img_size, img_size),\n            batch_size = batch_size,\n            class_mode = 'categorical')\n\n#one should validate the generality of model on the actcual target images\n#so not supposed agumentation\nvalid_aug_map = ImageDataGenerator(preprocessing_function = preprocess_input)\n\nres_valid_data = valid_aug_map.flow_from_dataframe(\n             valid_df, train_dir,\n             x_col = 'filename',\n             y_col = 'category',\n             target_size = (img_size, img_size),\n             batch_size = batch_size,\n             class_mode = 'categorical')\n\n\n#test data rescaling images\n\ntest_aug_map = ImageDataGenerator(preprocessing_function = preprocess_input)\n\nres_test_data = test_aug_map.flow_from_dataframe(\n             test_df, train_dir,\n             x_col = 'filename',\n             y_col = None,\n             class_mode = None,\n             target_size = (img_size, img_size),\n             shuffle = False)\n           \n","metadata":{"id":"YXMZlhOfPQt5","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:52:48.210494Z","iopub.execute_input":"2024-01-13T21:52:48.210879Z","iopub.status.idle":"2024-01-13T21:52:48.568953Z","shell.execute_reply.started":"2024-01-13T21:52:48.210845Z","shell.execute_reply":"2024-01-13T21:52:48.567820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Xây dựng mô hình cho việc chuyển giao học trên đỉnh của mô hình ResNet50 đã được tiền huấn luyện**","metadata":{}},{"cell_type":"code","source":"#loading resent \nresNet = tf.keras.applications.ResNet50(weights = 'imagenet',\n                        include_top = False,\n                        input_shape = (224,224, 3))\n\nresNet.trainable = False # Freeze layers\nresNet_model = Sequential([\n        resNet,\n        Flatten(),\n        Dense(1024, activation = 'relu'),\n        Dropout(0.4),\n        Dense(2, activation = 'softmax')])\n     \n\noptimizer = optimizers.Adam(1e-5)\n\nprint(color.BOLD_COLOR + '\\nResNet based Transfer learning Model layers and output shapes with params...\\n'+color.END)\n\nprint(color.BOLD)\nresNet_model.summary()\n#plot_model(resNet_model, to_file='resNet_model.png')","metadata":{"id":"vf854PFUPQ0z","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:53:18.738036Z","iopub.execute_input":"2024-01-13T21:53:18.738433Z","iopub.status.idle":"2024-01-13T21:53:21.536872Z","shell.execute_reply.started":"2024-01-13T21:53:18.738400Z","shell.execute_reply":"2024-01-13T21:53:21.535926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(color.BOLD + '\\nSetting early stopping factor and learning rate schedule\\n' +color.END)\n\nearlystop = EarlyStopping(patience= 5)\n    \nlr_callback = LearningRateScheduler(lrfn, verbose = True)\n\ncallbacks = [earlystop, lr_callback]\nprint(color.BOLD_COLOR + 'Done!')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:53:25.938809Z","iopub.execute_input":"2024-01-13T21:53:25.939203Z","iopub.status.idle":"2024-01-13T21:53:25.945754Z","shell.execute_reply.started":"2024-01-13T21:53:25.939170Z","shell.execute_reply":"2024-01-13T21:53:25.944628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Lets train and validate Pre-trained ResNet50 model**","metadata":{}},{"cell_type":"code","source":"resNet_model.compile(optimizer = optimizer,\n             loss = 'categorical_crossentropy',\n             metrics = ['accuracy'])\n\nprint(color.BOLD_COLOR + 'Training on ResNet50 has started ....\\n'+ color.END)\nprint(color.BOLD)\n\nresnet_history = resNet_model.fit_generator(res_train_data, epochs = 15,\n                          validation_data = res_valid_data,\n                          validation_steps= valid_images//batch_size,\n                          steps_per_epoch= train_images//batch_size,\n                          callbacks = callbacks)\nprint(color.END)\nprint(color.BOLD_COLOR + 'Done!\\n'+ color.END)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T21:53:56.535750Z","iopub.execute_input":"2024-01-13T21:53:56.536148Z","iopub.status.idle":"2024-01-13T23:02:25.576812Z","shell.execute_reply.started":"2024-01-13T21:53:56.536113Z","shell.execute_reply":"2024-01-13T23:02:25.575727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**vẽ biểu đồ thay đổi của mô hình ResNet trong độ mất mát và độ chính xác theo số epoch.**","metadata":{}},{"cell_type":"code","source":"fig,ax  = plt.subplots(2,1, figsize =(8,8), dpi = 100)\nfig.patch.set_facecolor('#f5f6f6')\n\naxes  = ax.ravel()\n\nfor ax in axes:\n    ax.set_facecolor('#f5f6f6')\n    for loc in ['right','top',]:\n        ax.spines[loc].set_visible(False)\n        \nhist2 = resnet_history.history\nEpochs =  range(len(hist2['loss']))\n\n## loss plot\nsns.lineplot(x = Epochs, y = hist2['val_loss'],  ax = axes[0], linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist2['loss'], ax  = axes[0], linewidth =4,  color = colors[4])\n\n\naxes[0].text(Epochs[-1]+0.25,hist2['val_loss'][-1],'Validation Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[0].text(Epochs[-1]+0.25,hist2['loss'][-1]-0.1 ,'Training Loss',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\n# accuracy plot\nsns.lineplot(x = Epochs, y = hist2['val_accuracy'],ax = axes[1],linewidth = 4, color = colors[3])\nsns.lineplot(x = Epochs, y = hist2['accuracy'],ax = axes[1],linewidth =4,  color = colors[4])\naxes[1].text(Epochs[-1]+0.25,hist2['val_accuracy'][-1]-0.04,'Validation Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[3]})\naxes[1].text(Epochs[-1]+0.25,hist2['accuracy'][-1] ,'Training Accuracy',{'fontfamily':'serif', 'size':12, 'weight':'bold','color':colors[4]})\n\n\nfig.text(0,1.06, 'ResNet Loss and Accuracy ',{'fontfamily':'serif', 'size':18, 'weight':'bold'})\nfig.text(0,1.01, '''chênh lệch gần như không đáng kể giữa độ mất mát và độ chính xác trên tập kiểm tra và tập huấn luyện..''',{'fontfamily':'serif', 'size':12})\nfig.text(0.75,-0.05,'© Made by dứa',{'fontfamily':'serif', 'size':10,  'color':'black'})\n        \nplt.tight_layout(h_pad = 5)\n\nfig.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T23:03:31.857198Z","iopub.execute_input":"2024-01-13T23:03:31.857566Z","iopub.status.idle":"2024-01-13T23:03:32.502017Z","shell.execute_reply.started":"2024-01-13T23:03:31.857536Z","shell.execute_reply":"2024-01-13T23:03:32.501027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**ResNet predictions with confusion matrix**","metadata":{}},{"cell_type":"code","source":"res_pred = resNet_model.predict_generator(res_test_data)\ntest_df['res_pred'] = np.argmax(res_pred, axis = -1)\nlabels = dict((v,k) for k,v in res_train_data.class_indices.items())\n\ntest_df['res_pred'] = test_df['res_pred'].map(labels)\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T23:04:00.046801Z","iopub.execute_input":"2024-01-13T23:04:00.047250Z","iopub.status.idle":"2024-01-13T23:04:05.301884Z","shell.execute_reply.started":"2024-01-13T23:04:00.047211Z","shell.execute_reply":"2024-01-13T23:04:05.300957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res_cf_matrix = confusion_matrix(test_df['category'],test_df['res_pred'])\nmy_cols = [colors[3],colors[2]]\n\nlabels = [ 'True Neg','False Pos','False Neg','True Pos']\ncategories = ['Cat', 'Dog']\nmake_confusion_matrix(res_cf_matrix,figsize = (10,5),\n                      group_names=labels,cbar = False,cmap = matplotlib.colors.LinearSegmentedColormap.from_list(\"\",my_cols),\n                      categories=categories, \n                      title = 'Vanila CNN comfusion matrix')\n\nplt.gcf().text(0,1.1,'ResNet Test Data Evaluation',{'fontfamily':'serif', 'size':24,  'color':'black', 'weight':'bold'})\nplt.gcf().text(0,0.995,\"\"\"F1 score là 0.992 và độ chính xác bằng với F1. Đây là một kết quả rất tốt.\"\"\",{'fontfamily':'serif', 'size':14,  'color':'black', })\n\nplt.gcf().text(0.85,-0.15,'© Made by dứa',{'fontfamily':'serif', 'size':10,  'color':'black'})\nplt.gcf().show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T23:04:50.100154Z","iopub.execute_input":"2024-01-13T23:04:50.100526Z","iopub.status.idle":"2024-01-13T23:04:50.303390Z","shell.execute_reply.started":"2024-01-13T23:04:50.100494Z","shell.execute_reply":"2024-01-13T23:04:50.302432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Dự đoán cuối cùng trên Tập Kiểm thử**","metadata":{}},{"cell_type":"code","source":"print(color.BOLD_COLOR + '\\n Final test data preperation for both vanilla and resnet for final predictions \\n'+ color.END)\n# generating an dataframe iterator for test dataset\n\nprint(color.BOLD)\nvani_sub_aug_map = ImageDataGenerator()\nres_sub_aug_map = ImageDataGenerator(preprocessing_function = preprocess_input)\n\nvani_sub_data = vani_sub_aug_map.flow_from_dataframe(\n             submission_image_df, test_dir,\n             x_col = 'filename',\n             y_col = None,\n             class_mode = None,\n             target_size = (img_size, img_size),\n             shuffle = False)\n\n\nres_sub_data = res_sub_aug_map.flow_from_dataframe(\n             submission_image_df, test_dir,\n             x_col = 'filename',\n             y_col = None,\n             class_mode = None,\n             target_size = (img_size, img_size),\n             shuffle = False)","metadata":{"id":"-_YrpgMEPQhT","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T23:05:29.572565Z","iopub.execute_input":"2024-01-13T23:05:29.572972Z","iopub.status.idle":"2024-01-13T23:05:29.854658Z","shell.execute_reply.started":"2024-01-13T23:05:29.572927Z","shell.execute_reply":"2024-01-13T23:05:29.853740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(color.BOLD_COLOR + '\\n Making final predictions with both resnet and vanilla cnns for Test data'+color.END)\nvani_pred_sub = vani_model.predict_generator(vani_sub_data)\nsubmission_image_df['vani_pred_sub'] = np.argmax(vani_pred_sub, axis = -1)\nlabels = dict((v,k) for k,v in res_train_data.class_indices.items())\nsubmission_image_df['vani_pred_sub'] = submission_image_df['vani_pred_sub'].map(labels)\n\n\nres_pred_sub = resNet_model.predict_generator(res_sub_data)\nsubmission_image_df['res_pred_sub'] = np.argmax(res_pred_sub, axis = -1)\nlabels = dict((v,k) for k,v in res_train_data.class_indices.items())\nsubmission_image_df['res_pred_sub'] = submission_image_df['res_pred_sub'].map(labels)\n\nprint(color.BOLD)\nprint(submission_image_df.head())","metadata":{"id":"PXXnPlqpPQfQ","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T23:05:35.062888Z","iopub.execute_input":"2024-01-13T23:05:35.063253Z","iopub.status.idle":"2024-01-13T23:07:35.650143Z","shell.execute_reply.started":"2024-01-13T23:05:35.063221Z","shell.execute_reply":"2024-01-13T23:07:35.648845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**dự đoán của chúng ta được thực hiện trên Dữ liệu Kiểm thử bởi cả hai mạng**","metadata":{}},{"cell_type":"code","source":"pred_sample = submission_image_df.sample(18)\npred_sample.reset_index(drop = True, inplace = True)\n\nfig = plt.figure(figsize=(12,24))\nfig.patch.set_facecolor('#f5f6f6')\n\nfor index, row in pred_sample.iterrows():\n    filename = row['filename']\n    vani_pred = row['vani_pred_sub']\n    res_pred = row['res_pred_sub']\n    img = load_img( test_dir + filename, target_size= (img_size, img_size))\n    plt.subplot(6,3, index+1)\n    plt.imshow(img)\n    plt.gca().axis('off')\n    plt.text(130, 175, 'vanila_pred: {}'.format(vani_pred), color='lightgreen',fontsize= 11, bbox=dict(facecolor='black', alpha=0.9))\n    plt.text(130, 200, 'resNet_pred: {}'.format(res_pred), color='red',fontsize= 11, bbox=dict(facecolor='black', alpha=0.9))\n    #plt.title(filename.split('.')[0])\n    del img\nplt.tight_layout()\n#plt.subplots_adjust( wspace=0, hspace= 1)\nfig.text(0,1, 'Hey Siri! is it cat or dog?: Test data labels',{'fontfamily':'serif','size':24,'weight':'bold'})\nfig.show()\n   ","metadata":{"id":"yL1uQEtzPQdP","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-01-13T23:10:49.892686Z","iopub.execute_input":"2024-01-13T23:10:49.893107Z","iopub.status.idle":"2024-01-13T23:10:51.933440Z","shell.execute_reply.started":"2024-01-13T23:10:49.893073Z","shell.execute_reply":"2024-01-13T23:10:51.932092Z"},"trusted":true},"execution_count":null,"outputs":[]}]}