{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport os\nimport cv2\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport tensorflow as tf\nimport tensorflow_addons as tfa\nimport matplotlib.pyplot as plt\nimport albumentations as album\nfrom tqdm import tqdm\nfrom sklearn.model_selection import StratifiedKFold\n\nplt.style.use('_mpl-gallery')\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-04-04T15:26:46.857706Z","iopub.execute_input":"2022-04-04T15:26:46.85814Z","iopub.status.idle":"2022-04-04T15:26:54.462644Z","shell.execute_reply.started":"2022-04-04T15:26:46.858054Z","shell.execute_reply":"2022-04-04T15:26:54.461882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Config","metadata":{}},{"cell_type":"code","source":"JOB_NAME = 'sorghum-id-fgvc-9'\nPATH = f'../input/{JOB_NAME}/'\n# split data\nN_SPLITS = 4\n# data process\nIMG_HEIGHT = 512\nIMG_WIDTH = 512\n# train cycle\nBATCH_SIZE = 12\nPATIENCE = 15\nEPOCHS = 100\nINIT_LR = 1e-4\nMAX_LR = 1e-3\ntf.keras.mixed_precision.set_global_policy('mixed_float16')","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:54.467477Z","iopub.execute_input":"2022-04-04T15:26:54.469718Z","iopub.status.idle":"2022-04-04T15:26:54.636513Z","shell.execute_reply.started":"2022-04-04T15:26:54.469677Z","shell.execute_reply":"2022-04-04T15:26:54.635605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(PATH + 'train_cultivar_mapping.csv')\ndf.dropna(inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:54.641474Z","iopub.execute_input":"2022-04-04T15:26:54.642327Z","iopub.status.idle":"2022-04-04T15:26:54.719673Z","shell.execute_reply.started":"2022-04-04T15:26:54.642284Z","shell.execute_reply":"2022-04-04T15:26:54.718946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images = df['image'].to_numpy()\nimages = np.array([PATH+'train_images/'+i for i in images])\nimages","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:54.721838Z","iopub.execute_input":"2022-04-04T15:26:54.72233Z","iopub.status.idle":"2022-04-04T15:26:54.758701Z","shell.execute_reply.started":"2022-04-04T15:26:54.722291Z","shell.execute_reply":"2022-04-04T15:26:54.758023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_images = len(images)\nnum_images","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:54.75969Z","iopub.execute_input":"2022-04-04T15:26:54.760035Z","iopub.status.idle":"2022-04-04T15:26:54.771443Z","shell.execute_reply.started":"2022-04-04T15:26:54.760002Z","shell.execute_reply":"2022-04-04T15:26:54.77009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cultivars = df['cultivar'].to_numpy()\ncultivars = cultivars\ncultivars","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:54.773559Z","iopub.execute_input":"2022-04-04T15:26:54.776472Z","iopub.status.idle":"2022-04-04T15:26:54.785058Z","shell.execute_reply.started":"2022-04-04T15:26:54.776422Z","shell.execute_reply":"2022-04-04T15:26:54.784268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_names = np.unique(cultivars)\nnum_classes = len(class_names)\nnum_classes","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:54.786788Z","iopub.execute_input":"2022-04-04T15:26:54.788847Z","iopub.status.idle":"2022-04-04T15:26:54.832358Z","shell.execute_reply.started":"2022-04-04T15:26:54.788811Z","shell.execute_reply":"2022-04-04T15:26:54.831765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_onehot(label):\n    one_hot = label == class_names\n    return np.argmax(one_hot)\n\ncultivars = np.array([get_onehot(cultivar) for cultivar in cultivars])","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:54.836072Z","iopub.execute_input":"2022-04-04T15:26:54.838241Z","iopub.status.idle":"2022-04-04T15:26:55.084279Z","shell.execute_reply.started":"2022-04-04T15:26:54.838204Z","shell.execute_reply":"2022-04-04T15:26:55.08355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## EDA","metadata":{}},{"cell_type":"code","source":"counts_each_class = np.zeros((num_classes))\nfor cultivar in cultivars:\n    counts_each_class += (np.arange(num_classes) == cultivar)\n\nplt.subplots(figsize=(20, 5))\nplt.bar(np.arange(num_classes)+0.5, counts_each_class)\nplt.hlines(counts_each_class.min(), 0, num_classes, colors='r')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:55.085408Z","iopub.execute_input":"2022-04-04T15:26:55.085646Z","iopub.status.idle":"2022-04-04T15:26:55.556836Z","shell.execute_reply.started":"2022-04-04T15:26:55.085614Z","shell.execute_reply":"2022-04-04T15:26:55.556147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## StratifiedKFold","metadata":{}},{"cell_type":"code","source":"skf = StratifiedKFold(n_splits=N_SPLITS, shuffle=True, random_state=42)\n\nfor train_index, valid_index in skf.split(images, cultivars):\n    train_images, valid_images = images[train_index], images[valid_index]\n    train_cultivars, valid_cultivars = cultivars[train_index], cultivars[valid_index]\n\nprint(f\"train size: {len(train_images)}\")\nprint(f\"valid size: {len(valid_images)}\")","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:55.559166Z","iopub.execute_input":"2022-04-04T15:26:55.559614Z","iopub.status.idle":"2022-04-04T15:26:55.588121Z","shell.execute_reply.started":"2022-04-04T15:26:55.559575Z","shell.execute_reply":"2022-04-04T15:26:55.587397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_splits = {'train':[train_images, train_cultivars], \n             'valid':[valid_images, valid_cultivars]}","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:26:55.589415Z","iopub.execute_input":"2022-04-04T15:26:55.589804Z","iopub.status.idle":"2022-04-04T15:26:55.594233Z","shell.execute_reply.started":"2022-04-04T15:26:55.589769Z","shell.execute_reply":"2022-04-04T15:26:55.593437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Writing TFRecords","metadata":{}},{"cell_type":"code","source":"def _bytes_feature(value):\n    \"\"\"Returns a bytes_list from a string / byte.\"\"\"\n    if isinstance(value, type(tf.constant(0))):\n        value = value.numpy() # BytesList won't unpack a string from an EagerTensor.\n    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))\n\ndef _int64_feature(value):\n    \"\"\"Returns an int64_list from a bool / enum / int / uint.\"\"\"\n    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))\n\ndef image_example(image_string, label):\n    image = tf.io.decode_png(image_string)\n    image = tf.image.resize(image, size=[IMG_HEIGHT, IMG_WIDTH])\n    image = tf.cast(image, 'uint8')\n    image = tf.io.encode_jpeg(image)\n\n    feature = {\n        'label': _int64_feature(label),\n        'image_raw': _bytes_feature(image),\n    }\n\n    return tf.train.Example(features=tf.train.Features(feature=feature))","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:27:49.260982Z","iopub.execute_input":"2022-04-04T15:27:49.261232Z","iopub.status.idle":"2022-04-04T15:27:49.271128Z","shell.execute_reply.started":"2022-04-04T15:27:49.261205Z","shell.execute_reply":"2022-04-04T15:27:49.270378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for ds_split in ds_splits:\n#     record_file = f'./tfrecords/sorghum-id-fgvc-9_{ds_split}.tfrecords'\n#     subset = ds_splits[ds_split]\n#     filenames, labels = subset\n#     with tf.io.TFRecordWriter(record_file) as writer:\n#         for filename, label in tqdm(list(zip(filenames, labels))):\n#             image_string = open(filename, 'rb').read()\n#             tf_example = image_example(image_string, label)\n#             writer.write(tf_example.SerializeToString())","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:19:07.16513Z","iopub.execute_input":"2022-04-04T11:19:07.165725Z","iopub.status.idle":"2022-04-04T11:37:05.439543Z","shell.execute_reply.started":"2022-04-04T11:19:07.165685Z","shell.execute_reply":"2022-04-04T11:37:05.436648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Reading TFRecords","metadata":{}},{"cell_type":"code","source":"image_feature_description = {\n    'label': tf.io.FixedLenFeature([], tf.int64),\n    'image_raw': tf.io.FixedLenFeature([], tf.string),\n}\n\ndef _parse_image_function(example_proto):\n    example_message = tf.io.parse_single_example(example_proto, image_feature_description)\n\n    img_raw = example_message['image_raw']\n    label = example_message['label']\n    \n    image = tf.io.decode_jpeg(img_raw, channels=3)\n    image = tf.reshape(image, shape=[IMG_HEIGHT, IMG_WIDTH, 3])\n    return (image, label)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:27:52.070728Z","iopub.execute_input":"2022-04-04T15:27:52.071391Z","iopub.status.idle":"2022-04-04T15:27:52.077059Z","shell.execute_reply.started":"2022-04-04T15:27:52.071329Z","shell.execute_reply":"2022-04-04T15:27:52.076404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_dataset(filename):\n    options = tf.data.Options()\n#     options.deterministic = False\n    dataset = tf.data.TFRecordDataset(filename)  \n    dataset = dataset.with_options(options)  \n\n    dataset = dataset.map(_parse_image_function, num_parallel_calls=tf.data.AUTOTUNE)\n    return dataset","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:30:05.388759Z","iopub.execute_input":"2022-04-04T15:30:05.389018Z","iopub.status.idle":"2022-04-04T15:30:05.394119Z","shell.execute_reply.started":"2022-04-04T15:30:05.388988Z","shell.execute_reply":"2022-04-04T15:30:05.393382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://www.kaggle.com/datasets/waynewhying/sorghum-512512-jpge-tfrecords\ntrain_ds = get_dataset(f'../input/sorghum-512512-jpge-tfrecords/{JOB_NAME}_train.tfrecords')\nvalid_ds = get_dataset(f'../input/sorghum-512512-jpge-tfrecords/{JOB_NAME}_valid.tfrecords')","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:31:52.061719Z","iopub.execute_input":"2022-04-04T15:31:52.061976Z","iopub.status.idle":"2022-04-04T15:31:52.099591Z","shell.execute_reply.started":"2022-04-04T15:31:52.061947Z","shell.execute_reply":"2022-04-04T15:31:52.098828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data augmentation","metadata":{}},{"cell_type":"code","source":"transforms = album.Compose([\n    album.RandomResizedCrop(height=IMG_HEIGHT, width=IMG_WIDTH),\n    album.Flip(p=0.5),\n    album.ShiftScaleRotate(border_mode=cv2.BORDER_CONSTANT, p=0.5),\n    album.HueSaturationValue(p=0.5),\n    album.OneOf([\n        album.RandomBrightnessContrast(p=0.5),\n        album.RandomGamma(p=0.5),\n        ], p=0.5),\n    album.OneOf([\n        album.Blur(p=0.1),\n        album.GaussianBlur(p=0.1),\n        album.MotionBlur(p=0.1),\n        ], p=0.1),\n    album.OneOf([\n        album.GaussNoise(p=0.1),\n        album.ISONoise(p=0.1),\n        album.GridDropout(ratio=0.5, p=0.2),\n        album.CoarseDropout(max_holes=16, max_height=16, max_width=16, min_holes=8, min_height=8, min_width=8, p=0.2)\n        ], p=0.2),\n    ])","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:30:23.421243Z","iopub.execute_input":"2022-04-04T15:30:23.421779Z","iopub.status.idle":"2022-04-04T15:30:23.430873Z","shell.execute_reply.started":"2022-04-04T15:30:23.421742Z","shell.execute_reply":"2022-04-04T15:30:23.428802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def aug_fn(image):\n    data = {\"image\":image}\n    aug_data = transforms(**data)\n    aug_img = aug_data[\"image\"]\n    aug_img = tf.cast(aug_img, tf.float32)\n    return aug_img","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:30:38.154063Z","iopub.execute_input":"2022-04-04T15:30:38.15486Z","iopub.status.idle":"2022-04-04T15:30:38.160076Z","shell.execute_reply.started":"2022-04-04T15:30:38.154814Z","shell.execute_reply":"2022-04-04T15:30:38.158859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def process_data_train(img, label):\n    aug_img = tf.numpy_function(func=aug_fn, inp=[img], Tout=tf.float32)\n    return aug_img, label\n\ndef process_data_test(path):\n    img = tf.io.read_file(path)\n    img = tf.io.decode_png(img, channels=3)\n    img = tf.image.resize(img, size=[IMG_HEIGHT, IMG_WIDTH])\n    return img","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:31:18.050082Z","iopub.execute_input":"2022-04-04T15:31:18.050393Z","iopub.status.idle":"2022-04-04T15:31:18.057012Z","shell.execute_reply.started":"2022-04-04T15:31:18.050352Z","shell.execute_reply":"2022-04-04T15:31:18.056239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds = train_ds.map(process_data_train, num_parallel_calls=tf.data.AUTOTUNE)\n\ntrain_ds = train_ds.batch(BATCH_SIZE).prefetch(buffer_size=tf.data.AUTOTUNE).repeat()\nvalid_ds = valid_ds.batch(BATCH_SIZE).prefetch(buffer_size=tf.data.AUTOTUNE).repeat()","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:31:55.047901Z","iopub.execute_input":"2022-04-04T15:31:55.048325Z","iopub.status.idle":"2022-04-04T15:31:55.064271Z","shell.execute_reply.started":"2022-04-04T15:31:55.048286Z","shell.execute_reply":"2022-04-04T15:31:55.063511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_batch, label_batch = next(iter(train_ds))\n\nplt.figure(figsize=(9, 6))\nfor i in range(6):\n    ax = plt.subplot(2, 3, i + 1)\n    plt.imshow(image_batch[i].numpy().astype(np.uint8))\n    label = label_batch[i].numpy()\n    plt.title(class_names[label])\n    plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:31:59.874215Z","iopub.execute_input":"2022-04-04T15:31:59.874737Z","iopub.status.idle":"2022-04-04T15:32:01.315885Z","shell.execute_reply.started":"2022-04-04T15:31:59.874696Z","shell.execute_reply":"2022-04-04T15:32:01.313818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Build Model","metadata":{}},{"cell_type":"code","source":"base_model = tf.keras.applications.efficientnet.EfficientNetB0(input_shape=(IMG_HEIGHT, IMG_WIDTH, 3), include_top=False)\ninputs = tf.keras.Input(shape=(IMG_HEIGHT, IMG_WIDTH, 3))\n# Transfer Learning\nx = base_model(inputs)\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\n# Dense\nx = tf.keras.layers.Dropout(0.5)(x)\noutputs = tf.keras.layers.Dense(num_classes, activation=\"softmax\", dtype='float32')(x)\n\nmodel = tf.keras.Model(inputs, outputs)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:32:20.539161Z","iopub.execute_input":"2022-04-04T15:32:20.539454Z","iopub.status.idle":"2022-04-04T15:32:23.525746Z","shell.execute_reply.started":"2022-04-04T15:32:20.53942Z","shell.execute_reply":"2022-04-04T15:32:23.525021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:32:26.780887Z","iopub.execute_input":"2022-04-04T15:32:26.781503Z","iopub.status.idle":"2022-04-04T15:32:26.808268Z","shell.execute_reply.started":"2022-04-04T15:32:26.781462Z","shell.execute_reply":"2022-04-04T15:32:26.807518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Define CLR schedule","metadata":{}},{"cell_type":"code","source":"steps_per_epoch = len(train_images)//BATCH_SIZE\n\nclr = tfa.optimizers.CyclicalLearningRate(initial_learning_rate=INIT_LR,\n    maximal_learning_rate=MAX_LR,\n    scale_fn=lambda x: 1/(2.**(x-1)),\n    step_size=2 * steps_per_epoch\n)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:32:31.482313Z","iopub.execute_input":"2022-04-04T15:32:31.482933Z","iopub.status.idle":"2022-04-04T15:32:31.488133Z","shell.execute_reply.started":"2022-04-04T15:32:31.482891Z","shell.execute_reply":"2022-04-04T15:32:31.487365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train Model","metadata":{}},{"cell_type":"code","source":"model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=clr), \n              loss=tf.losses.SparseCategoricalCrossentropy(), \n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:32:33.507795Z","iopub.execute_input":"2022-04-04T15:32:33.508052Z","iopub.status.idle":"2022-04-04T15:32:33.529642Z","shell.execute_reply.started":"2022-04-04T15:32:33.508024Z","shell.execute_reply":"2022-04-04T15:32:33.528988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_callbacks = tf.keras.callbacks.EarlyStopping(patience=PATIENCE, \n                                                monitor='val_loss', \n                                                restore_best_weights=True)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:32:34.55783Z","iopub.execute_input":"2022-04-04T15:32:34.558093Z","iopub.status.idle":"2022-04-04T15:32:34.562964Z","shell.execute_reply.started":"2022-04-04T15:32:34.558063Z","shell.execute_reply":"2022-04-04T15:32:34.56226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"counts_each_class_train = np.zeros((num_classes))\nfor cultivar in train_cultivars:\n    counts_each_class_train += (np.arange(num_classes) == cultivar)\n\nweight = (1/counts_each_class_train) * (num_images/num_classes)\nclass_weight = {i:weight[i] for i in range(len(weight))}","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:32:36.179499Z","iopub.execute_input":"2022-04-04T15:32:36.180047Z","iopub.status.idle":"2022-04-04T15:32:36.276795Z","shell.execute_reply.started":"2022-04-04T15:32:36.180008Z","shell.execute_reply":"2022-04-04T15:32:36.276068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_ds, \n                    validation_data=valid_ds, \n                    epochs=EPOCHS, \n                    callbacks=[my_callbacks], \n                    class_weight=class_weight, \n                    steps_per_epoch=steps_per_epoch,\n                    validation_steps=len(valid_images)//BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T15:32:37.669516Z","iopub.execute_input":"2022-04-04T15:32:37.669993Z","iopub.status.idle":"2022-04-04T15:44:49.983727Z","shell.execute_reply.started":"2022-04-04T15:32:37.669952Z","shell.execute_reply":"2022-04-04T15:44:49.981385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Validate the Model","metadata":{}},{"cell_type":"code","source":"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nax1.set_title('Accuracy')\nax1.plot(history.history['accuracy'], 'r', marker=\"o\", label='accuracy')\nax1.plot(history.history['val_accuracy'], 'g', marker=\"x\", label='val_accuracy')\nax1.legend()\n\nax2.set_title('Loss')\nax2.plot(history.history['loss'], 'r', marker=\"o\", label='loss')\nax2.plot(history.history['val_loss'], 'g', marker=\"x\", label='val_loss')\nax2.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.474158Z","iopub.status.idle":"2022-04-04T11:37:05.475074Z","shell.execute_reply.started":"2022-04-04T11:37:05.474816Z","shell.execute_reply":"2022-04-04T11:37:05.474858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(6, 4))\nstep = np.arange(0, 50 * steps_per_epoch)\nlr = clr(step)\nplt.plot(step, lr)\nplt.xlabel(\"Steps\")\nplt.ylabel(\"Learning Rate\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.476165Z","iopub.status.idle":"2022-04-04T11:37:05.476712Z","shell.execute_reply.started":"2022-04-04T11:37:05.476464Z","shell.execute_reply":"2022-04-04T11:37:05.476489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_preds = model.predict(valid_ds, steps=len(valid_images)//BATCH_SIZE)\nval_preds = np.argmax(val_preds, axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.478507Z","iopub.status.idle":"2022-04-04T11:37:05.47926Z","shell.execute_reply.started":"2022-04-04T11:37:05.478996Z","shell.execute_reply":"2022-04-04T11:37:05.479022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"matrix = tf.math.confusion_matrix(valid_cultivars[:len(valid_images)//BATCH_SIZE * BATCH_SIZE], val_preds).numpy()\n\nplt.figure(figsize=(6, 6))\nplt.imshow(matrix)\nplt.title(\"Confusion Matrix\")\nplt.xlabel(\"Predicted Class\")\nplt.ylabel(\"True Class\")\nplt.grid(0)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.480631Z","iopub.status.idle":"2022-04-04T11:37:05.481267Z","shell.execute_reply.started":"2022-04-04T11:37:05.481009Z","shell.execute_reply":"2022-04-04T11:37:05.481036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submit the Result","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(PATH + 'sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.484082Z","iopub.status.idle":"2022-04-04T11:37:05.484659Z","shell.execute_reply.started":"2022-04-04T11:37:05.484416Z","shell.execute_reply":"2022-04-04T11:37:05.484443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = PATH + 'test/'\ntest_images = np.array([path+i for i in df['filename']])\n\ntest_ds = tf.data.Dataset.from_tensor_slices(test_images)\ntest_ds = test_ds.map(process_data_test, num_parallel_calls=tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.485755Z","iopub.status.idle":"2022-04-04T11:37:05.486309Z","shell.execute_reply.started":"2022-04-04T11:37:05.48608Z","shell.execute_reply":"2022-04-04T11:37:05.486106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds = test_ds.batch(BATCH_SIZE)\npreds = model.predict(test_ds)\npreds = np.argmax(preds, axis=1)\npreds = [class_names[i] for i in preds]","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.487385Z","iopub.status.idle":"2022-04-04T11:37:05.487986Z","shell.execute_reply.started":"2022-04-04T11:37:05.487716Z","shell.execute_reply":"2022-04-04T11:37:05.487744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['cultivar'] = preds\ndf.to_csv(f'./{JOB_NAME}_submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-04-04T11:37:05.489143Z","iopub.status.idle":"2022-04-04T11:37:05.48973Z","shell.execute_reply.started":"2022-04-04T11:37:05.489478Z","shell.execute_reply":"2022-04-04T11:37:05.489504Z"},"trusted":true},"execution_count":null,"outputs":[]}]}