{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Import libs"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"scrolled":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport shutil\nimport csv\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nfrom random import random\nfrom tensorflow.keras.activations import linear\nfrom tensorflow.keras.activations import softmax\nfrom tensorflow.keras.activations import tanh\nfrom tensorflow.keras.layers import BatchNormalization, Activation\nfrom tensorflow.keras.layers import Flatten, Dense\nfrom tensorflow.keras.layers.experimental.preprocessing import RandomRotation, RandomFlip, Resizing\nfrom tensorflow.keras.losses import categorical_crossentropy\nfrom tensorflow.keras.metrics import categorical_accuracy\nfrom tensorflow.keras.models import Model, Sequential\nfrom tensorflow.keras.optimizers import SGD\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras import Input\nfrom tensorflow.keras.layers import Concatenate\nfrom tensorflow.keras.optimizers import Adam","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Config TPU"},{"metadata":{"trusted":true},"cell_type":"code","source":"# try:\n#     tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n#     print(f'Running on TPU {tpu.master()}')\n# except ValueError:\n#     tpu = None\n\n# if tpu:\n#     tf.config.experimental_connect_to_cluster(tpu)\n#     tf.tpu.experimental.initialize_tpu_system(tpu)\n#     strategy = tf.distribute.experimental.TPUStrategy(tpu)\n# else:\n#     strategy = tf.distribute.get_strategy()\n\n# AUTO = tf.data.experimental.AUTOTUNE\n# REPLICAS = strategy.num_replicas_in_sync\n# print(f'REPLICAS: {REPLICAS}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Path variables"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"origin = \"../input/cassava-leaf-disease-classification\"\ndestination = \"../output/kaggle/working\"\ndataset_base_folder = destination + \"/dataset\"\ndataset_train_folder = f\"{dataset_base_folder}/train\"\nif not os.path.exists(dataset_train_folder):\n    os.makedirs(dataset_train_folder)\ndataset_val_folder = f\"{dataset_base_folder}/val\"\nif not os.path.exists(dataset_train_folder):\n    os.makedirs(dataset_train_folder)\ndestination_classes = [str(i) for i in range(5)]\noriginal_train_data_folder = origin + \"/train_images\"\nresize_train_data_folder = destination + \"/train_images_resized\"\ncsv_file = origin + \"/train.csv\"\nsub_df = pd.read_csv(origin + '/sample_submission.csv')\nsub_df['paths'] = origin + \"/test_images/\" + sub_df.image_id\nval_train_ratio = 0.2\ntarget_size = (128, 128)\ninput_shape = (128, 128, 3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Clean + Resize + Load dataset"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"# Clean\nfor c in destination_classes:\n    folder = f'{dataset_train_folder}/{c}'\n    if os.path.exists(folder):\n        for filename in os.listdir(folder):\n            os.remove(f'{folder}/{filename}')\n    else:\n        os.makedirs(folder)\n    folder = f'{dataset_val_folder}/{c}'\n    if os.path.exists(folder):\n        for filename in os.listdir(folder):\n            os.remove(f'{folder}/{filename}')\n    else:\n        os.makedirs(folder)\n\n# Resize\nif not os.path.exists(resize_train_data_folder):\n    os.makedirs(resize_train_data_folder)\nfor filename in os.listdir(original_train_data_folder):\n    image = Image.open(original_train_data_folder + \"/\" + filename)\n    image = image.resize(target_size)\n    image.save(resize_train_data_folder + '/' + filename)\n\n\n# Load\nfilename_to_class_folder = {}\n\nwith open(csv_file) as fo:\n    for row in csv.reader(fo):\n        filename_to_class_folder[row[0]] = row[1]\n\nfor filename in os.listdir(resize_train_data_folder):\n    destination_folder = dataset_train_folder\n    if random() < val_train_ratio:\n        destination_folder = dataset_val_folder\n\n    shutil.copyfile(\n        f'{resize_train_data_folder}/{filename}',\n        f'{destination_folder}/{filename_to_class_folder[filename]}/{filename}'\n    )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":" # Declare functions"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def compute_class_images_count(base_folder: str, class_name: str):\n    return sum((1 for _ in os.listdir(f'{base_folder}/{class_name}')))\n\n\ndef compute_all_classes_images_count(base_folder: str):\n    return sum((compute_class_images_count(base_folder, c) for c in destination_classes))\n\n\ndef compute_train_images_count():\n    return compute_all_classes_images_count(dataset_train_folder)\n\n\ndef compute_val_images_count():\n    return compute_all_classes_images_count(dataset_val_folder)\n\ndef create_dataset_iterator(base_folder: str, size: int):\n    def inner_func():\n        return ImageDataGenerator(\n            rescale=1.0 / 255,\n            preprocessing_function = None,\n            rotation_range = 45,\n            zoom_range = 0.2,\n            horizontal_flip = True,\n            vertical_flip = True,\n            fill_mode = 'nearest',\n            shear_range = 0.1,\n            height_shift_range = 0.1,\n            width_shift_range = 0.1\n        ).flow_from_directory(\n                base_folder,\n                target_size=target_size,\n                batch_size=1)\n\n    return (tf.data.Dataset.from_generator(\n        inner_func,\n        output_types=(tf.float32, tf.float32),\n        output_shapes= ((1, *target_size, 3), (1, len(destination_classes))))\n            .take(size)\n            .unbatch()\n            .batch(batch_size)\n            .cache()\n            .repeat()\n            .prefetch(2)\n            .as_numpy_iterator())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Declare variables"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"lr = 0.05\nref_batch_size = 1024\nbatch_size = 256\nmomentum = 0.95\ntrain_size = compute_train_images_count()\nval_size = compute_val_images_count()\nepochs = 100\ndropout = 0.2\ntrain_labels = pd.read_csv(os.path.join(origin, \"train.csv\"))\ntrain_labels.label = train_labels.label.astype('str')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train models"},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"def build_network_and_train_network(model, name, build_hidden_layers, dataset_train_it, dataset_val_it):\n    model.add(tf.keras.layers.Flatten())\n    build_hidden_layers(model)\n    model.add(tf.keras.layers.Flatten())\n    model.add(Dense(len(destination_classes), activation=softmax))\n    model.compile(\n#         optimizer=SGD(momentum=momentum, lr=lr),\n        optimizer=Adam(),\n        loss=categorical_crossentropy,\n        metrics=[categorical_accuracy]\n    )\n    result = model.fit(\n        dataset_train_it,\n        validation_data=dataset_val_it,\n        steps_per_epoch=train_size // batch_size,\n        validation_steps=val_size // batch_size,\n        batch_size=batch_size,\n        epochs=epochs\n    )\n\n    model.save(name + '.h5')        \n    model.summary()  \n    return result\ndef Linear(model):\n    pass\n\n\ndef MLP(model):\n    model.add(tf.keras.layers.Dense(1024, activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Dropout(dropout))\n    model.add(tf.keras.layers.Dense(1024, activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Dropout(dropout))\n    model.add(tf.keras.layers.Dense(1024, activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Dropout(dropout))\n\n\ndef CNN(model):\n    model.add(tf.keras.layers.Reshape(input_shape))\n    model.add(tf.keras.layers.Conv2D(128, (3, 3), padding='same', activation=tf.keras.activations.relu, input_shape=input_shape))\n    model.add(tf.keras.layers.Conv2D(128, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Conv2D(128, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.MaxPool2D(2, 2))\n    model.add(tf.keras.layers.Dropout(dropout))\n\n    model.add(tf.keras.layers.Conv2D(64, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Conv2D(64, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Conv2D(64, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.MaxPool2D(2, 2))\n    model.add(tf.keras.layers.Dropout(dropout))\n\n    model.add(tf.keras.layers.Conv2D(32, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Conv2D(32, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.MaxPool2D(2, 2))\n    model.add(tf.keras.layers.Dropout(dropout))\n\n    model.add(tf.keras.layers.Conv2D(16, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Conv2D(16, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.MaxPool2D(2, 2))\n    model.add(tf.keras.layers.Dropout(dropout))\n\n    model.add(tf.keras.layers.Conv2D(8, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.Conv2D(8, (3, 3), padding='same', activation=tf.keras.activations.relu))\n    model.add(tf.keras.layers.MaxPool2D(2, 2))\n    model.add(tf.keras.layers.Dropout(dropout))\n    \n\ndef VGG16(model):\n    CNN(model)\n    MLP(model)\n    \n    \nmodel = tf.keras.models.Sequential()\nall_logs = [\n#     build_network_and_train_network(model, 'Linear', Linear, create_dataset_iterator(dataset_train_folder, train_size), create_dataset_iterator(dataset_val_folder, val_size)),\n#     build_network_and_train_network(model, 'MLP', MLP, create_dataset_iterator(dataset_train_folder, train_size), create_dataset_iterator(dataset_val_folder, val_size)),\n#     build_network_and_train_network(model, 'CNN', CNN, create_dataset_iterator(dataset_train_folder, train_size), create_dataset_iterator(dataset_val_folder, val_size))\n#     build_network_and_train_network(model, 'CNNMLP', CNNMLP, create_dataset_iterator(dataset_train_folder, train_size), create_dataset_iterator(dataset_val_folder, val_size))\n    build_network_and_train_network(model, 'VGG16', VGG16, create_dataset_iterator(dataset_train_folder, train_size), create_dataset_iterator(dataset_val_folder, val_size))\n    ]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Show charts/results "},{"metadata":{"trusted":true},"cell_type":"code","source":"# acc\nfor logs in all_logs:\n    y_coords = logs.history['categorical_accuracy']\n    x_coords = list(range(len(y_coords)))\n    plt.plot(x_coords, y_coords)\n\n# val_acc\nfor logs in all_logs:\n    y_coords = logs.history['val_categorical_accuracy']\n    x_coords = list(range(len(y_coords)))\n    plt.plot(x_coords, y_coords)\n\nplt.grid()\nplt.show()\n\n# loss\nfor logs in all_logs:\n    y_coords = logs.history['loss']\n    x_coords = list(range(len(y_coords)))\n    plt.plot(x_coords, y_coords)\n\n# val_loss\nfor logs in all_logs:\n    y_coords = logs.history['val_loss']\n    x_coords = list(range(len(y_coords)))\n    plt.plot(x_coords, y_coords)\n\nplt.grid()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submit"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"preds = []\nsample_sub = pd.read_csv(origin + '/sample_submission.csv')\n\nfor image in sample_sub.image_id:\n    img = tf.keras.preprocessing.image.load_img(origin + '/test_images/' + image)\n    img = tf.keras.preprocessing.image.img_to_array(img)\n    img = tf.keras.preprocessing.image.smart_resize(img, (128, 128))\n    img = np.expand_dims(img, 0)\n    prediction = model.predict(img)\n    preds.append(np.argmax(prediction))\n\nmy_submission = pd.DataFrame({'image_id': sample_sub.image_id, 'label': preds})\nmy_submission.to_csv('submission.csv', index=False)\nmy_submission","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}