{"cells":[{"metadata":{},"cell_type":"markdown","source":"I'll attempt to make a decent prediction with fewest lines of simple code."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom matplotlib import pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom functools import partial\n\nAUTOTUNE = tf.data.experimental.AUTOTUNE\nBATCH_SIZE = 32\nIMAGE_SIZE = [128, 128]\nCLASSES = [str(i) for i in range(5)]\nEPOCHS = 20\nWEIGHTS_FILE = \"../input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def decode_image(image):\n    image = tf.image.decode_jpeg(image, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0\n    image = tf.reshape(image, [512, 512, 3]) # That's how it's saved in the tfrec file.\n    image = tf.image.resize(image, IMAGE_SIZE, method='nearest') # Make it smaller to run faster\n    return image\n\ndef read_tfrec(example, labeled):\n    tfrecord_format = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"target\": tf.io.FixedLenFeature([], tf.int64)\n    } if labeled else {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"image_name\": tf.io.FixedLenFeature([], tf.string)\n    }\n    example = tf.io.parse_example(example, tfrecord_format)\n    image = decode_image(example['image'])\n    if labeled:\n        label = tf.cast(example['target'], tf.int32)\n        return image, label\n    idnum = example['image_name']\n    return image, idnum","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PATH = (\"../input/cassava-leaf-disease-classification/\"\n        \"train_tfrecords/ld_train00-1338.tfrec\")\n\ndef load_dataset(filenames, labeled=True, ordered=False):\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False\n    dataset = tf.data.TFRecordDataset(filenames, \n                                      num_parallel_reads=AUTOTUNE)\n    dataset = dataset.with_options(ignore_order)\n    dataset = dataset.map(\n        partial(read_tfrec, labeled=labeled),\n        num_parallel_calls=AUTOTUNE\n    )\n    return dataset\n    \nfor image,idnum in load_dataset(PATH).take(3):\n    print(f\"Image: {image.shape}, {image.dtype}, \"\n          f\"min {tf.reduce_min(image)}, max {tf.reduce_max(image)};\")\n    print(f\"idnum: {idnum.shape}, {idnum.dtype}, {idnum}\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nINPUT_PATH = \"../input/cassava-leaf-disease-classification/\"\n\nTRAINING_FILENAMES, VALID_FILENAMES = train_test_split(\n    tf.io.gfile.glob(INPUT_PATH + \"train_tfrecords/*\"),\n    test_size=0.35, random_state=42,\n)\nTEST_FILENAMES = tf.io.gfile.glob(\n    INPUT_PATH + \"/test_tfrecords/*\"\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_train_dataset():\n    dataset = load_dataset(TRAINING_FILENAMES, labeled=True)\n    dataset = dataset.repeat()\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTOTUNE)\n    return dataset\n\ndef get_valid_dataset(ordered=False):\n    dataset = load_dataset(VALID_FILENAMES, labeled=True, \n                          ordered=ordered)\n    dataset = dataset.repeat()\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTOTUNE)\n    return dataset\n\ndef get_test_dataset(ordered=False):\n    dataset = load_dataset(TEST_FILENAMES, labeled=False, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTOTUNE)\n    return dataset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import re\ndef count_data_items(tfrec_filenames):\n    num_items = [\n        int(re.compile(r\"-(\\d*)\\.\").search(\n            filename).group(1)) for filename in tfrec_filenames\n    ]\n    return np.sum(num_items)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NUM_TRAIN_IMAGES = count_data_items(TRAINING_FILENAMES)\nNUM_VALID_IMAGES = count_data_items(VALID_FILENAMES)\nNUM_TEST_IMAGES = count_data_items(TEST_FILENAMES)\n\nprint(f\"Dataset: train:{NUM_TRAIN_IMAGES}, \" \n      f\"valid:{NUM_VALID_IMAGES}, test:{NUM_TEST_IMAGES}\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_adjust_layer = tf.keras.layers.Lambda(\n    keras.applications.resnet50.preprocess_input, \n)    \n\nresnet_model = tf.keras.applications.ResNet50(\n    weights=WEIGHTS_FILE,\n    include_top=False,\n)\n\nswitch_trainable = False\nfor layer in resnet_model.layers:\n    if layer.name == \"conv4_block1_out\": \n        switch_trainable = True\n    layer.trainable = switch_trainable\n    \nresnet_model = keras.Model(\n    inputs=resnet_model.input,\n    outputs=resnet_model.get_layer(\"conv4_block5_out\").output\n)\n\nresnet_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr_scheduler = keras.optimizers.schedules.ExponentialDecay(\n    initial_learning_rate=1e-4, \n    decay_steps=10000, \n    decay_rate=0.9)\n\nmodel = tf.keras.Sequential([\n    tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]),\n    tf.keras.layers.BatchNormalization(renorm=True),\n    img_adjust_layer,\n    resnet_model,\n    tf.keras.layers.GlobalAveragePooling2D(),\n    tf.keras.layers.Dense(300, activation='relu'),\n    tf.keras.layers.Dense(len(CLASSES), activation='softmax')  \n])\n\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=lr_scheduler, epsilon=0.001),\n    loss='sparse_categorical_crossentropy',  \n    metrics=['sparse_categorical_accuracy']\n)\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset = get_train_dataset()\nvalid_dataset = get_valid_dataset()\n\nSTEPS_PER_EPOCH = NUM_TRAIN_IMAGES // BATCH_SIZE\nVALID_STEPS = NUM_VALID_IMAGES // BATCH_SIZE\ncallbacks = [keras.callbacks.EarlyStopping(restore_best_weights=True,patience=int(EPOCHS/4))]\nhistory = model.fit(train_dataset, \n                    steps_per_epoch=STEPS_PER_EPOCH, \n                    epochs=EPOCHS,\n                    validation_data=valid_dataset,\n                    validation_steps=VALID_STEPS,\n                   callbacks=callbacks)\nmodel.save(\"model.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history_frame = pd.DataFrame(history.history)\nhistory_frame.loc[:, ['loss', 'val_loss']].plot()\nhistory_frame.loc[:, ['sparse_categorical_accuracy', 'val_sparse_categorical_accuracy']].plot();","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# this code will convert our test image data to a float32 \ndef to_float32(image, label):\n    return tf.cast(image, tf.float32), label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"testing_dataset = get_test_dataset()\ntesting_dataset = testing_dataset.unbatch().batch(20)\ntest_batch = iter(testing_dataset)\n\ntest_ds = get_test_dataset(ordered=True) \ntest_ds = test_ds.map(to_float32)\n\nprint('Computing predictions...')\ntest_images_ds = testing_dataset\ntest_images_ds = test_ds.map(lambda image, idnum: image)\nprobabilities = model.predict(test_images_ds)\npredictions = np.argmax(probabilities, axis=-1)\nprint(predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Generating submission.csv file...')\ntest_ids_ds = test_ds.map(lambda image, idnum: idnum).unbatch()\ntest_ids = next(iter(test_ids_ds.batch(NUM_TEST_IMAGES))).numpy().astype('U') # all in one batch\nnp.savetxt('submission.csv', np.rec.fromarrays([test_ids, predictions]), fmt=['%s', '%d'], delimiter=',', header='id,label', comments='')\n!head submission.csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}