{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Multi-Label Image Classification","metadata":{}},{"cell_type":"markdown","source":"#### Quick Introductory Example","metadata":{}},{"cell_type":"code","source":"!wget https://dl.dropbox.com/s/0htmeoie69q650p/miml_dataset.zip?dl=1 -O dataset.zip\n!unzip -q dataset.zip \n!rm dataset.zip","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import Sequential\n\nfrom keras_preprocessing.image import ImageDataGenerator\nfrom keras.layers import Dense, Activation, Flatten, Dropout, BatchNormalization\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras import regularizers, optimizers\nimport pandas as pd\nimport numpy as np","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(\"./miml_dataset/miml_labels_1.csv\")\n\ncolumns = list(df.columns[1:])\ncolumns","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Making Data Generators for Augmentation","metadata":{}},{"cell_type":"code","source":"datagen = ImageDataGenerator(rescale = 1./255.)\n\ntest_datagen = ImageDataGenerator(rescale = 1./255.)\n\ntrain_generator=datagen.flow_from_dataframe(\ndataframe=df[:1800],\ndirectory=\"./miml_dataset/images\",\nx_col=\"Filenames\",\ny_col=columns,\nbatch_size=32,\nseed=42,\nshuffle=True,\nclass_mode=\"raw\",\ntarget_size=(100,100))\nvalid_generator=test_datagen.flow_from_dataframe(\ndataframe=df[1800:1900],\ndirectory=\"./miml_dataset/images\",\nx_col=\"Filenames\",\ny_col=columns,\nbatch_size=32,\nseed=42,\nshuffle=True,\nclass_mode=\"raw\",\ntarget_size=(100,100))\ntest_generator=test_datagen.flow_from_dataframe(\ndataframe=df[1900:],\ndirectory=\"./miml_dataset/images\",\nx_col=\"Filenames\",\nbatch_size=1,\nseed=42,\nshuffle=False,\nclass_mode=None,\ntarget_size=(100,100))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(32, (3,3), padding = 'same', input_shape = (100,100,3)))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(32, (3,3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size = (2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(64, (3,3), padding = 'same'))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(64, (3,3)))\nmodel.add(Activation('relu'))\n\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Flatten())\nmodel.add(Dense(512))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(5, activation='sigmoid'))\nmodel.compile(optimizers.RMSprop(lr=0.0001, decay=1e-6),loss=\"binary_crossentropy\",metrics=[\"accuracy\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID=valid_generator.n//valid_generator.batch_size\nSTEP_SIZE_TEST=test_generator.n//test_generator.batch_size\nmodel.fit(train_generator,\n                    steps_per_epoch=STEP_SIZE_TRAIN,\n                    validation_data=valid_generator,\n                    validation_steps=STEP_SIZE_VALID,\n                    epochs=30\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Plant Pathology 2021 - FGVC8","metadata":{}},{"cell_type":"markdown","source":"https://www.kaggle.com/nickuzmenkov/pp2021-tpu-tf-training/data <br>\nhttps://www.kaggle.com/nickuzmenkov/pp2021-tpu-tf-inference","metadata":{"_kg_hide-input":true}},{"cell_type":"code","source":"from kaggle_secrets import UserSecretsClient\nuser_secrets = UserSecretsClient()\nsecret_value_0 = user_secrets.get_secret(\"wandb_login\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%capture\n!pip install wandb","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%capture\n\nimport wandb\nfrom wandb.keras import WandbCallback \n\n\nwandb.login(key = secret_value_0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport matplotlib.pyplot as plt \nimport seaborn as sns\nimport tensorflow as tf\nfrom tqdm.auto import tqdm\n\nsns.set_style('darkgrid')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('../input/plant-pathology-2021-fgvc8/train.csv')\nprint(train.shape)\ntrain.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import MultiLabelBinarizer\n\nmlb = MultiLabelBinarizer().fit(train.labels.apply(lambda x : x.split()))\nlabels = pd.DataFrame(mlb.transform(train.labels.apply(lambda x : x.split())), columns = mlb.classes_)\n\nfig, ax = plt.subplots(figsize = (20, 6))\nlabels.sum().plot.bar(title = 'Target Class Distribution')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(20, 6))\nlabels.sum(axis=1).value_counts().plot.bar(title='Distribution of Number of Labels per Image');","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.concat([train['image'], labels], axis=1)\nlabels.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_data_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, validation_split=0.1)\n\ntrain_generator = image_data_generator.flow_from_dataframe(\n    dataframe=labels,\n    directory='../input/plant-pathology-2021-fgvc8/train_images',\n    x_col='image',\n    y_col=labels.columns.tolist()[1:],\n    class_mode='raw',\n    color_mode=\"rgb\",\n    target_size=(224, 224),\n    batch_size=64,\n    subset='training'\n)\n\nvalid_generator = image_data_generator.flow_from_dataframe(\n    dataframe=labels,\n    directory='../input/plant-pathology-2021-fgvc8/train_images',\n    x_col='image',\n    y_col=labels.columns.tolist()[1:],\n    class_mode='raw',\n    color_mode=\"rgb\",\n    target_size=(224, 224),\n    batch_size=64,\n    subset='validation'\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# inputs = tf.keras.Input(shape = (224,224,3))\n\n# x = tf.keras.applications.MobileNetV2(include_top = False)(inputs)\n# x = tf.keras.layers.GlobalAveragePooling2D()(x)\n# outputs = tf.keras.layers.Dense(6, activation = 'sigmoid')(x)\n\n# model = tf.keras.Model(inputs, outputs)\n# model.compile(loss = 'binary_crossentropy', optimizer = tf.keras.optimizers.Adam(lr = 1e-4))\n\n# model.summary()\n\n# tf.keras.utils.plot_model(model, show_shapes = True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def Model():\n    inputs = tf.keras.Input(shape = (224,224,3))\n\n    x = tf.keras.applications.MobileNetV2(include_top = False)(inputs)\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    outputs = tf.keras.layers.Dense(6, activation = 'sigmoid')(x)\n\n    model = tf.keras.Model(inputs, outputs)\n    return model\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.test.is_gpu_available()\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if tf.test.is_gpu_available():\n    configs = {\n\n        \"learning_rate\" : 0.0001, \n        \"loss_function\" : 'binary_crossentropy',\n        \"epochs\" : 10, \n        \"batch_size\" : 64,\n        \"log_step\" : 200,\n        \"val_log_step\" : 50,\n        \"architecture\" : \"MobileNetV2\",\n        \"dataset\" : \"Plant Pathology FGVC8\"\n    }\n\n    run = wandb.init(project = \"Plant Pathology FGVC8\", config = configs)\n\n    config = wandb.config\n\n    model = Model()\n    model.summary()\n\n    optimizer = tf.keras.optimizers.Adam(config.learning_rate)\n    model.compile(optimizer, config.loss_function, metrics = ['acc'])\n\n    rlp = tf.keras.callbacks.ReduceLROnPlateau(monitor = 'val_loss', patience = 2, verbose = 1, factor = 0.01)\n\n    es = tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 3, verbose = 1, restore_best_weights = True)\n\n\n\n    model.fit(train_generator, validation_data = valid_generator, epochs = 20, callbacks = [WandbCallback(), rlp, es])\n    \n    fig, ax = plt.subplots(figsize = (20, 6))\n    pd.DataFrame(history.history)[['loss', 'val_loss']].plot(ax = ax, title = 'Model Loss Curve')\n    \n    submissions = pd.read_csv('../input/plant-pathology-2021-fgvc8/sample_submission.csv')\n    \n    test_data_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale = 1./255)\n    test_generator = test_data_generator.flow_from_dataframe( \n    submissions, \n    directory = '../input/plant-pathology-2021-fgvc8/test_images',\n    x_col = \"image\",\n    y_col = None,\n    target_size = (224,224),\n    color_mode = \"rgb\",\n    classes = None,\n    class_mode = None,\n    shuffle = False, \n    batch_size = 1\n    )\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# rlp = tf.keras.callbacks.ReduceLROnPlateau(monitor = 'val_loss', patience = 2, verbose = 1, factor = 0.01)\n\n# es = tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 3, verbose = 1, restore_best_weights = True)\n\n# history = model.fit(train_generator, validation_data = valid_generator, epochs = 10, callbacks = [rlp, es])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"TF TPU Training","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Notebook in Making","metadata":{}}]}