{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\nprint(\"Tensorflow version \" + tf.__version__)\n\ntry:\n  tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  # TPU detection\n  print('Running on TPU ', tpu.cluster_spec().as_dict()['worker'])\nexcept ValueError:\n  raise BaseException('ERROR: Not connected to a TPU runtime; please see the previous cell in this notebook for instructions!')\n\ntf.config.experimental_connect_to_cluster(tpu)\ntf.tpu.experimental.initialize_tpu_system(tpu)\nstrategy = tf.distribute.experimental.TPUStrategy(tpu)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from kaggle_datasets import KaggleDatasets\nGCS_PATH = KaggleDatasets().get_gcs_path()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"one_hot = {'healthy': [0, 0, 0, 0, 0],\n           'scab': [0, 1, 0, 0, 0],\n           'scab frog_eye_leaf_spot': [0, 1, 1, 0, 0],\n           'frog_eye_leaf_spot': [0, 0, 1, 0, 0],\n           'rust': [0, 0, 0, 1, 0],\n           'complex': [1, 0, 0, 0, 0],\n           'powdery_mildew': [0, 0, 0, 0, 1],\n           'rust frog_eye_leaf_spot': [0, 0, 1, 1, 0],\n           'frog_eye_leaf_spot complex': [1, 0, 1, 0, 0],\n           'scab frog_eye_leaf_spot complex': [1, 1, 1, 0, 0],\n           'powdery_mildew complex': [1, 0, 0, 0, 1],\n           'rust complex': [1, 0, 0, 1, 0]}\nnum_classes = 5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\ndataframe = pd.read_csv('../input/plant-pathology-2021-fgvc8/train.csv')\ndataframe = dataframe.sample(frac=1, random_state=123)\ndataframe['labels'] = dataframe['labels'].map(lambda x: one_hot[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_split = 0.2\nsplit = len(dataframe) - int(len(dataframe) * validation_split)\ntrain_dataframe = dataframe[:split]\nvalidation_dataframe = dataframe[split:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_size = 224\nbatch_size = strategy.num_replicas_in_sync * 32\n\nsteps_per_epoch = len(train_dataframe) // batch_size\nvalidation_steps = len(validation_dataframe) // batch_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow_addons\nfrom tensorflow.keras import layers","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def parse_function(filename, label):\n    image_string = tf.io.read_file(GCS_PATH+'/train_images/'+filename)\n    image = tf.io.decode_image(image_string, channels=3, expand_animations=False)\n    image = tf.image.resize(image, (image_size, image_size))\n    image = tf.cast(image, tf.float32) / 255.\n    return image, label\n\naugmentor = tf.keras.Sequential([\n    layers.experimental.preprocessing.RandomContrast(.5),\n    layers.experimental.preprocessing.RandomZoom(.5, .5),\n    layers.experimental.preprocessing.RandomRotation(1),\n    layers.experimental.preprocessing.RandomTranslation(.25, .25)\n])\n\ndef data_augmentation(images, labels):\n    images = augmentor.call(images)\n    return images, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_dataset(dataframe, training=True, include_labels=True):\n    filenames = dataframe.pop('image')\n    labels = dataframe.pop('labels')\n    dataset = tf.data.Dataset.from_tensor_slices((filenames.values, labels.values.tolist()))\n    \n    dataset = dataset.shuffle(buffer_size=len(dataframe), \n                              seed=123, reshuffle_each_iteration=False)\n    dataset = dataset.map(parse_function, \n                          num_parallel_calls=tf.data.AUTOTUNE)\n    dataset = dataset.batch(batch_size=batch_size).cache('')\n\n    if training:\n        dataset = dataset.map(data_augmentation, \n                              num_parallel_calls=tf.data.AUTOTUNE)\n    if not include_labels:\n        dataset = dataset.map(lambda x, y: x, \n                              num_parallel_calls=tf.data.AUTOTUNE)\n        \n    return dataset.repeat().prefetch(tf.data.AUTOTUNE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = create_dataset(train_dataframe.copy())\nvalidation_data = create_dataset(validation_dataframe.copy(), training=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model():\n    base_model = tf.keras.applications.MobileNet(\n                        include_top=False,\n                        dropout=0.5,\n                        weights=\"imagenet\",\n                        input_shape=(image_size, image_size, 3))\n    for layer in base_model.layers:\n        layer.trainable = True\n\n    model = tf.keras.models.Sequential([\n            layers.BatchNormalization(input_shape=(image_size, image_size, 3)),\n            base_model,\n            layers.GlobalAveragePooling2D(),\n            layers.Dropout(0.5),\n            layers.Dense(512, activation='relu'),\n            layers.Dropout(0.5),\n            layers.Dense(num_classes, activation=\"sigmoid\")\n    ])\n    return model    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model = build_model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    f1_score = tensorflow_addons.metrics.FBetaScore(num_classes=num_classes, \n                                                    threshold=None, beta=1.0,\n                                                    name='f1_score')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoint = tf.keras.callbacks.ModelCheckpoint('bestmodel_tpu.h5',\n                                                monitor='val_loss',\n                                                mode='auto',\n                                                save_best_only=True,\n                                                save_weights_only=False,\n                                                verbose=1)\n\nreduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',\n                                                 mode='auto',\n                                                 factor=0.1,\n                                                 min_lr=0,\n                                                 patience=3,\n                                                 verbose=1)\n\nearly_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', \n                                                  mode='auto',\n                                                  patience=7,\n                                                  verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = tf.keras.optimizers.Nadam(lr=0.0001, \n                                      beta_1=0.9, beta_2=0.999, \n                                      epsilon=1e-7)\nloss = tf.keras.losses.BinaryCrossentropy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 30\n\ncallbacks = [checkpoint, reduce_lr]\n\nmodel.compile(optimizer=optimizer, \n                loss=loss, \n                metrics=[f1_score, 'accuracy'])\n\nhistory = model.fit(train_data,\n                    epochs=epochs,\n                    verbose=1, callbacks=callbacks,\n                    validation_data=validation_data,\n                    steps_per_epoch=steps_per_epoch,\n                    validation_steps=validation_steps)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n# list all data in history\nprint(history.history.keys())\n# summarize history for accuracy\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()\n# summarize history for loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_weights('./bestmodel_tpu.h5', by_name=True)","execution_count":null,"outputs":[]}],"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}