{"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":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport random\nimport cv2\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport tensorflow as tf\n# Chuyển dữ liệu landmark thành onehot vector, ví dụ: [1, 2, 3] -> [[1, 0, 0], [0, 1, 0], [0, 0, 1]]\nfrom tensorflow.keras.utils import to_categorical\n# Chia dữ liệu train thành train và valid để chạy \nfrom sklearn.model_selection import train_test_split\n#https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator\nfrom tensorflow.python.keras.preprocessing.image import ImageDataGenerator","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-04-25T18:40:15.370351Z","iopub.execute_input":"2022-04-25T18:40:15.370767Z","iopub.status.idle":"2022-04-25T18:40:15.376353Z","shell.execute_reply.started":"2022-04-25T18:40:15.370725Z","shell.execute_reply":"2022-04-25T18:40:15.375636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Class config bao gồm:**\n1. IMAGE_SIZE: Kích thước input \n2. LANDMARK_IDS: Số landmark (class) được chọn (theo yêu cầu là 30-40% của 81313 => 25000\n3. PATIENCE: Số lần chờ với early stopping\n4. NUM_EPOCHS: Số epoch dùng để huấn luyện\n5. ER_VERBOSE: Verbose cho early stopping\n6. BATCH_SIZE: Lô huấn luyện\n7. EST_DATA: Số lượng ảnh test cần test (tổng là ~10345 ảnh)\n8. TRAIN_ROOT: Đường dẫn tới thư mục train\n9. TEST_ROOT: Đường dẫn tới thư mục test","metadata":{}},{"cell_type":"code","source":"class CFG:\n    IMAGE_SIZE=112 #112 224 448 \n    LANDMARK_IDS=100 # replace  = 16k = 20%\n    PATIENCE=5\n    NUM_EPOCHS=30\n    ER_VERBOSE=1\n    BATCH_SIZE=32\n    TEST_DATA=4000 # 40%\n    TRAIN_ROOT='../input/landmark-recognition-2020/train'\n    TEST_ROOT='../input/landmark-recognition-2020/test'","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:15.378123Z","iopub.execute_input":"2022-04-25T18:40:15.378514Z","iopub.status.idle":"2022-04-25T18:40:15.388537Z","shell.execute_reply.started":"2022-04-25T18:40:15.378478Z","shell.execute_reply":"2022-04-25T18:40:15.387939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Đọc dữ liệu bằng pandas\ntrain_df = pd.read_csv(\"../input/landmark-recognition-2020/train.csv\")\ntest_df = pd.read_csv('../input/landmark-recognition-2020/sample_submission.csv')\ntrain_df.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:15.389759Z","iopub.execute_input":"2022-04-25T18:40:15.390122Z","iopub.status.idle":"2022-04-25T18:40:16.276394Z","shell.execute_reply.started":"2022-04-25T18:40:15.390087Z","shell.execute_reply":"2022-04-25T18:40:16.275688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(test_df)","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:16.277738Z","iopub.execute_input":"2022-04-25T18:40:16.278018Z","iopub.status.idle":"2022-04-25T18:40:16.282963Z","shell.execute_reply.started":"2022-04-25T18:40:16.277983Z","shell.execute_reply":"2022-04-25T18:40:16.282264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hiển thị kích thước dữ liệu:\n# Hàng: Số ảnh\n# Cột ids + landmark ids\nprint('Train data shape:', train_df.shape)\nprint('Test data shape:', test_df.shape)","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:16.28554Z","iopub.execute_input":"2022-04-25T18:40:16.286045Z","iopub.status.idle":"2022-04-25T18:40:16.292997Z","shell.execute_reply.started":"2022-04-25T18:40:16.286008Z","shell.execute_reply":"2022-04-25T18:40:16.292201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hiển thị số class\nprint(\"Len unique train label:\", len(train_df['landmark_id'].unique()))","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:16.29459Z","iopub.execute_input":"2022-04-25T18:40:16.29516Z","iopub.status.idle":"2022-04-25T18:40:16.317107Z","shell.execute_reply.started":"2022-04-25T18:40:16.295056Z","shell.execute_reply":"2022-04-25T18:40:16.316466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hiển thị một vài landmark id trong tập huấn luyện mình lấy ra\nlandmark_unique = train_df['landmark_id'].unique()\nlandmark_unique[0: CFG.LANDMARK_IDS]","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:16.318215Z","iopub.execute_input":"2022-04-25T18:40:16.318439Z","iopub.status.idle":"2022-04-25T18:40:16.337799Z","shell.execute_reply.started":"2022-04-25T18:40:16.318407Z","shell.execute_reply":"2022-04-25T18:40:16.337161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Hàm này sẽ phân tích số ảnh trong mỗi class (số ảnh chứa landmark cụ thể)**","metadata":{}},{"cell_type":"code","source":"def samples_distribution(value_counts: pd.Series):\n    mean_images = round(value_counts.mean(), 0)\n    median_images = round(value_counts.median(), 0)\n    print(f'Total number of classes: {len(value_counts)}')\n    print(f'{value_counts.min()} - {value_counts.max()} samples per class')\n    print(f'Mean value: {mean_images} samples\\n')\n    images_per_class.hist(bins=20, log=True)\n    plt.vlines(mean_images, ymin=0, ymax=80_000, colors='red', label='Mean number')\n    plt.vlines(median_images, ymin=0, ymax=80_000, colors='green', label='Median number')\n    plt.title('Train samples per class')\n    plt.xlabel('Number of images')\n    plt.ylabel('Frequency')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:16.338879Z","iopub.execute_input":"2022-04-25T18:40:16.339102Z","iopub.status.idle":"2022-04-25T18:40:16.346292Z","shell.execute_reply.started":"2022-04-25T18:40:16.339069Z","shell.execute_reply":"2022-04-25T18:40:16.345655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_per_class = train_df['landmark_id'].value_counts()\nn_classes = len(images_per_class)\nsamples_distribution(images_per_class)\n\n# xem đồ thị để xem dl có balance k để dùng hàm loss -> focal loss for unbalanced data\n#https://blog.vietnamlab.vn/focal-loss/?fbclid=IwAR2LYWGydqFzOgcio9fy2qGF0OoegO2DcBG9oafqBKPnVKiIWbi6tZkAWe8 -> focal loss","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:16.347777Z","iopub.execute_input":"2022-04-25T18:40:16.34835Z","iopub.status.idle":"2022-04-25T18:40:16.916981Z","shell.execute_reply.started":"2022-04-25T18:40:16.348259Z","shell.execute_reply":"2022-04-25T18:40:16.91627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Lấy ra id của những ảnh mình huấn luyện**","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm\ntrain_image_ids = []\ntest_image_ids = []\nlabels = []\ntemp_labels = []\ni = 0\nfor id_ in tqdm(landmark_unique[0:CFG.LANDMARK_IDS]):\n    for id in train_df['id'][train_df['landmark_id'] == id_]:\n        train_image_ids.append(id)\n        labels.append(id_)\n        temp_labels.append(i)\n    i = i+1\nlen(train_image_ids)\n\n#486.474 images ","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:16.918257Z","iopub.execute_input":"2022-04-25T18:40:16.918786Z","iopub.status.idle":"2022-04-25T18:40:17.143372Z","shell.execute_reply.started":"2022-04-25T18:40:16.918668Z","shell.execute_reply":"2022-04-25T18:40:17.1427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Lấy ra id của tất cả ảnh test**","metadata":{}},{"cell_type":"code","source":"test_image_ids = test_df['id']","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:17.144659Z","iopub.execute_input":"2022-04-25T18:40:17.145074Z","iopub.status.idle":"2022-04-25T18:40:17.149238Z","shell.execute_reply.started":"2022-04-25T18:40:17.145037Z","shell.execute_reply":"2022-04-25T18:40:17.148547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image_ids[0]","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:17.15046Z","iopub.execute_input":"2022-04-25T18:40:17.15086Z","iopub.status.idle":"2022-04-25T18:40:17.159643Z","shell.execute_reply.started":"2022-04-25T18:40:17.150812Z","shell.execute_reply":"2022-04-25T18:40:17.158753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image_ids[0]","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:17.161012Z","iopub.execute_input":"2022-04-25T18:40:17.161251Z","iopub.status.idle":"2022-04-25T18:40:17.169138Z","shell.execute_reply.started":"2022-04-25T18:40:17.161217Z","shell.execute_reply":"2022-04-25T18:40:17.168345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Hàm get_image_path sẽ lấy ra kết quả:**\n1. List đường dẫn tới các ảnh (train/ test)\n2. Ảnh (train/ test)","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm\n\ndef get_image_path(root, ids):\n    image_paths = []\n    images = []\n    for i in tqdm(range(len(ids))):\n        # lấy image path từ thư mục root\n        first_dir = os.path.join(root,ids[i][0])\n        second_dir = os.path.join(first_dir,ids[i][1])\n        third_dir = os.path.join(second_dir,ids[i][2])\n        final_path = os.path.join(third_dir,ids[i]+'.jpg')\n        #đọc ảnh = opencv\n        img = cv2.imread(final_path)[:,:,::-1]\n        #resize ảnh về CFG_IMAGE_SIZE e.g = 224\n        images.append(cv2.resize(img, (CFG.IMAGE_SIZE, CFG.IMAGE_SIZE)))\n        image_paths.append(final_path)\n    r = {\n        'image_paths': image_paths,\n        'images': images\n    }\n    return r","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:17.173137Z","iopub.execute_input":"2022-04-25T18:40:17.173352Z","iopub.status.idle":"2022-04-25T18:40:17.180977Z","shell.execute_reply.started":"2022-04-25T18:40:17.173327Z","shell.execute_reply":"2022-04-25T18:40:17.180121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"r_train = get_image_path(CFG.TRAIN_ROOT, train_image_ids)\nr_test = get_image_path(CFG.TEST_ROOT, test_image_ids)","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:40:17.182261Z","iopub.execute_input":"2022-04-25T18:40:17.182968Z","iopub.status.idle":"2022-04-25T18:43:33.580109Z","shell.execute_reply.started":"2022-04-25T18:40:17.182932Z","shell.execute_reply":"2022-04-25T18:43:33.579377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image_paths, train_images = r_train['image_paths'], r_train['images']\ntest_image_paths, test_images = r_test['image_paths'], r_test['images']","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:33.581539Z","iopub.execute_input":"2022-04-25T18:43:33.58203Z","iopub.status.idle":"2022-04-25T18:43:33.587332Z","shell.execute_reply.started":"2022-04-25T18:43:33.581991Z","shell.execute_reply":"2022-04-25T18:43:33.586644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Plot trực quan một số ảnh trong tập train**","metadata":{}},{"cell_type":"code","source":"fig = plt.gcf()\nfig.set_size_inches(16, 16)\nnext_pix_ = train_image_paths\nfor i, img_path in enumerate(next_pix_[0:16]):\n    sp = plt.subplot(5, 4, i + 1)\n    sp.axis('Off')\n    img = mpimg.imread(img_path)\n    plt.imshow(img)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:33.58856Z","iopub.execute_input":"2022-04-25T18:43:33.588807Z","iopub.status.idle":"2022-04-25T18:43:35.253705Z","shell.execute_reply.started":"2022-04-25T18:43:33.588774Z","shell.execute_reply":"2022-04-25T18:43:35.253102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Plot trực quan một số ảnh trong tập test**","metadata":{}},{"cell_type":"code","source":"fig = plt.gcf()\nfig.set_size_inches(16, 16)\nnext_pix_ = test_image_paths\nfor i, img_path in enumerate(next_pix_[0:16]):\n    sp = plt.subplot(5, 4, i + 1)\n    sp.axis('Off')\n    img = mpimg.imread(img_path)\n    plt.imshow(img)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:35.254616Z","iopub.execute_input":"2022-04-25T18:43:35.254883Z","iopub.status.idle":"2022-04-25T18:43:36.540265Z","shell.execute_reply.started":"2022-04-25T18:43:35.254831Z","shell.execute_reply":"2022-04-25T18:43:36.539668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#tạo image và labels\n#https://www.w3schools.com/python/ref_func_zip.asp\nshuf = list(zip(train_images,temp_labels))\nrandom.shuffle(shuf)\ntrain_data, labels_data = zip(*shuf)\nprint('Images: ', len(train_data))\nprint('Labels: ', len(labels_data))","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:36.54152Z","iopub.execute_input":"2022-04-25T18:43:36.54197Z","iopub.status.idle":"2022-04-25T18:43:36.552414Z","shell.execute_reply.started":"2022-04-25T18:43:36.541933Z","shell.execute_reply":"2022-04-25T18:43:36.551779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ma trận của 1 ảnh\n# train_data[0]","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:36.553585Z","iopub.execute_input":"2022-04-25T18:43:36.554025Z","iopub.status.idle":"2022-04-25T18:43:36.561961Z","shell.execute_reply.started":"2022-04-25T18:43:36.553991Z","shell.execute_reply":"2022-04-25T18:43:36.561097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#landmark_id hoặc class\nlabels_data[0]","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:36.563352Z","iopub.execute_input":"2022-04-25T18:43:36.563886Z","iopub.status.idle":"2022-04-25T18:43:36.573309Z","shell.execute_reply.started":"2022-04-25T18:43:36.56384Z","shell.execute_reply":"2022-04-25T18:43:36.572479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# chuẩn hóa ảnh\nX_train_data = np.array(train_data) / 255\n# one hot\nY_data = to_categorical(labels_data, num_classes=100) \n# chia train test\nX_train, X_val, Y_train, Y_val = train_test_split(X_train_data, Y_data, test_size=0.3, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:36.574814Z","iopub.execute_input":"2022-04-25T18:43:36.575297Z","iopub.status.idle":"2022-04-25T18:43:37.037561Z","shell.execute_reply.started":"2022-04-25T18:43:36.575263Z","shell.execute_reply":"2022-04-25T18:43:37.036787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Chuẩn hóa ảnh test\nX_test_data = test_images[0: CFG.TEST_DATA]\ntest_image_ids = test_image_ids[0: CFG.TEST_DATA]\nX_test_data = np.array(X_test_data) / 255","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:37.039046Z","iopub.execute_input":"2022-04-25T18:43:37.039296Z","iopub.status.idle":"2022-04-25T18:43:37.457978Z","shell.execute_reply.started":"2022-04-25T18:43:37.039261Z","shell.execute_reply":"2022-04-25T18:43:37.457187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Sử dụng augment cho ảnh train**","metadata":{}},{"cell_type":"code","source":"#augment: https://github.com/albumentations-team/albumentations\n#https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator\ndatagen = ImageDataGenerator(\n    featurewise_center=False,\n    samplewise_center=False,\n    featurewise_std_normalization=False,\n    samplewise_std_normalization=False,\n    zca_whitening=False,\n    zca_epsilon=1e-06,\n    rotation_range=0,\n    width_shift_range=0.5,\n    height_shift_range=0.0,\n    brightness_range=None,\n    shear_range=0.3,\n    zoom_range=0.0,\n    channel_shift_range=0.0,\n    fill_mode='nearest',\n    cval=0.0,\n    horizontal_flip=True,\n    vertical_flip=True,\n    rescale=None,\n    preprocessing_function=None,\n    data_format=None,\n    validation_split=0.0,\n    dtype=None\n)","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-04-25T18:43:37.459408Z","iopub.execute_input":"2022-04-25T18:43:37.459669Z","iopub.status.idle":"2022-04-25T18:43:37.468191Z","shell.execute_reply.started":"2022-04-25T18:43:37.459633Z","shell.execute_reply":"2022-04-25T18:43:37.467405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**TRAINING**","metadata":{}},{"cell_type":"code","source":"# Tạo mô hình huấn luyện dữ liệu\n# lấy pretrained từ tập imagenet 1K https://image-net.org/download.php\n# finetune lại mô hình (mình đã có các features từ tập ảnh imagenet)\nmodel = tf.keras.applications.ResNet101V2(input_shape=(CFG.IMAGE_SIZE,CFG.IMAGE_SIZE,3),  # đổi thành Densnet: https://d2l.aivivn.com/chapter_convolutional-modern/densenet_vn.html?fbclid=IwAR32rQfUj2eIJ54eVw8MjKCRBHEDk8BupCTe4__oNSKBqkyRyMgC5oHJHc8 -> densenet\n                                                      include_top=False, # k lấy đầu của densenet, \n                                                      weights='imagenet',\n                                                      pooling='avg')\nmodel.trainable = False\ninputs = model.input\ndrop_layer = tf.keras.layers.Dropout(0.2)(model.output)\nx_layer = tf.keras.layers.Dense(512, activation='relu')(drop_layer)\nx_layer1 = tf.keras.layers.Dense(128, activation='relu')(x_layer)\ndrop_layer1 = tf.keras.layers.Dropout(0.20)(x_layer1)\noutputs = tf.keras.layers.Dense(CFG.LANDMARK_IDS, activation='softmax')(drop_layer1)\nmodel = tf.keras.Model(inputs=inputs, outputs=outputs)","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:37.469293Z","iopub.execute_input":"2022-04-25T18:43:37.46984Z","iopub.status.idle":"2022-04-25T18:43:46.293511Z","shell.execute_reply.started":"2022-04-25T18:43:37.469789Z","shell.execute_reply":"2022-04-25T18:43:46.292778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:46.294636Z","iopub.execute_input":"2022-04-25T18:43:46.294904Z","iopub.status.idle":"2022-04-25T18:43:46.298111Z","shell.execute_reply.started":"2022-04-25T18:43:46.294869Z","shell.execute_reply":"2022-04-25T18:43:46.297461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Thuật toán tối ưu: Adam\noptimizer = tf.keras.optimizers.Adam(learning_rate=0.001)\n# Loss CE https://tonydeep.github.io/tensorflow/2017/07/07/Cross-Entropy-Loss.html\n# Hàm loss sử dụng: Cross Entropy Loss\nmodel.compile(optimizer=optimizer,loss='categorical_crossentropy',metrics=['acc'])\n# Kỹ thuật dừng sớm tránh overfitting\n# https://machinelearningcoban.com/2017/03/04/overfitting/\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    min_delta=0,\n    patience=CFG.PATIENCE,\n    verbose=CFG.ER_VERBOSE,\n    mode='auto',\n    baseline=None,\n    restore_best_weights=False\n)\n# Tiến hành fit data và huấn luyện mô hình\nhistory = model.fit(datagen.flow(X_train,Y_train,batch_size=CFG.BATCH_SIZE),\\\n                    validation_data=(X_val,Y_val),\\\n                    epochs=CFG.NUM_EPOCHS,\\\n                    callbacks=[early_stopping])","metadata":{"execution":{"iopub.status.busy":"2022-04-25T18:43:46.299086Z","iopub.execute_input":"2022-04-25T18:43:46.299813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualize đồ thì accuracy của quá trình huấn luyện (training) và kiểm thử (validation)**","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs = range(len(acc))\nplt.plot(epochs, acc, 'r', label='Train accuracy')\nplt.plot(epochs, val_acc, 'b', label='Valid accuracy')\nplt.title('Training log')\nplt.legend(loc=0)\nplt.figure()\n\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualize đồ thì lỗi của quá trình huấn luyện (training) và kiểm thử (validation)**","metadata":{}},{"cell_type":"code","source":"plt.plot(epochs, loss, 'r', label='Train loss')\nplt.plot(epochs, val_loss, 'b', label='Valid loss')\nplt.title('Training log')\nplt.legend(loc=0)\nplt.figure()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**INFERENCE**","metadata":{}},{"cell_type":"code","source":"# Kiểm tra đầu vào tập test\nX_test_data.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tiến hành predict dữ liệu\nresult = model.predict(X_test_data)\nresult = np.argmax(result, axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Ghi kết quả dự đoán ra file csv**","metadata":{}},{"cell_type":"code","source":"result_csv = pd.DataFrame(columns=['id', 'landmark_id'])\nresult_csv['id'] = test_image_ids\nresult_csv['landmark_id'] = result\nresult_csv","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Thu gom bộ nhớ**","metadata":{}},{"cell_type":"code","source":"import gc\ngc.collect()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://blog.vietnamlab.vn/focal-loss/?fbclid=IwAR2LYWGydqFzOgcio9fy2qGF0OoegO2DcBG9oafqBKPnVKiIWbi6tZkAWe8 -> focal loss\n#https://d2l.aivivn.com/chapter_convolutional-modern/densenet_vn.html?fbclid=IwAR32rQfUj2eIJ54eVw8MjKCRBHEDk8BupCTe4__oNSKBqkyRyMgC5oHJHc8 -> densenet","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}