{"cells":[{"metadata":{},"cell_type":"markdown","source":"This notebook is the first of two parts time-saving quickstart baseline for you. Submission accuracy is 0.88 in public dataset. I will list model details and tricks for training. If you are experienced in Keras model, reading only the list and skipping the code could be your option.\n\n* Model: Keras EfficientNetB4 with Imagenet weights, (380,380,3) input size, average pooling + 5 class softmax top, without dropout.\n* Data generator(augmentation): rotate 45, zoom 0.2, horizontal and vertical flip, height and width shift 0.2, interpolation nearest, validation split 0.2\n* Hyperparameters and tricks: epochs 20, batch size 16, learning rate 1e-3, reduce learning rate to 1e-6, early stoping."},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\n\nCassava_dir = \"../input/cassava-leaf-disease-classification/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(Cassava_dir, \"train.csv\"))\ntrain_df['label'] = train_df['label'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TARGET_SIZE = (380,380)\nBATCH_SIZE = 16\nSTEPS_PER_EPOCH = len(train_df)*0.8 // BATCH_SIZE\nVALIDATION_STEPS = len(train_df)*0.2 // BATCH_SIZE\nEPOCHS = 20","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(validation_split = 0.2,\n                                    rotation_range = 45,\n                                    zoom_range = 0.2,\n                                    horizontal_flip = True,\n                                    vertical_flip = True,\n                                    fill_mode = 'nearest',\n                                    height_shift_range = 0.2,\n                                    width_shift_range = 0.2,\n                                  )\n\ntrain_generator = train_datagen.flow_from_dataframe(train_df,\n                         directory = os.path.join(Cassava_dir, \"train_images\"),\n                         subset = \"training\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = TARGET_SIZE,\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\",\n                         seed = 2020,\n                         shuffle= True)\n\n\nvalidation_datagen = ImageDataGenerator(validation_split = 0.2)\n\nvalidation_generator = validation_datagen.flow_from_dataframe(train_df,\n                         directory = os.path.join(Cassava_dir, \"train_images\"),\n                         subset = \"validation\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = TARGET_SIZE,\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\",\n                         seed = 2020,\n                         shuffle= True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.applications import EfficientNetB4\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\n\nbasemodel = EfficientNetB4(weights=\"imagenet\", include_top=False,input_shape=TARGET_SIZE+(3,))\nheadmodel = layers.GlobalAveragePooling2D()(basemodel.output)\nheadmodel = layers.Dense(5, activation=\"softmax\")(headmodel)\nmodel = keras.Model(inputs=basemodel.input, outputs=headmodel)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_save = ModelCheckpoint('best_weights.h5', \n                             save_best_only = True, \n                             monitor = 'val_loss', \n                             mode = 'min', verbose = 1)\nreduce_lr = ReduceLROnPlateau(monitor = 'val_loss', factor = 0.3, \n                              patience = 2, min_lr = 1e-6, \n                              mode = 'min', verbose = 1)\nearly_stop = EarlyStopping(monitor = 'val_loss', \n                           patience = 3, mode = 'min', verbose = 1,\n                           restore_best_weights = True)\n\n\nmodel.compile(\n    optimizer=keras.optimizers.Adam(1e-3),\n    loss=\"sparse_categorical_crossentropy\",\n    metrics=[\"accuracy\"],\n)\n\nhistory = model.fit(\n    train_generator,\n    steps_per_epoch = STEPS_PER_EPOCH,\n    epochs = EPOCHS,\n    validation_data = validation_generator,\n    validation_steps = VALIDATION_STEPS,\n    callbacks = [model_save, early_stop, reduce_lr],\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history_df = pd.DataFrame(history.history)\nhistory_df.loc[:, ['loss', 'val_loss']].plot()\nhistory_df.loc[:, ['accuracy', 'val_accuracy']].plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save('weights.h5')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Thanks to the notebooks below for inspiring:\n* [https://www.kaggle.com/eceifter/xception-cassava-leaf-disease-classification](https://www.kaggle.com/eceifter/xception-cassava-leaf-disease-classification)\n* [https://www.kaggle.com/marto24/cassava-baseline-model](https://www.kaggle.com/marto24/cassava-baseline-model)"}],"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":4,"nbformat_minor":4}