{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"from datetime import datetime\nstart_time=datetime.now()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Imports","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import math, re, os\nimport tensorflow as tf\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\nfrom kaggle_datasets import KaggleDatasets\nprint(\"Tensorflow version \" + tf.__version__)\nAUTO = tf.data.experimental.AUTOTUNE\nGCS_DS_PATH = KaggleDatasets().get_gcs_path() ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**TPU DETECTION**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Detect hardware, return appropriate distribution strategy\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  # TPU detection. No parameters necessary if TPU_NAME environment variable is set. On Kaggle this is always the case.\n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy() # default distribution strategy in Tensorflow. Works on CPU and single GPU.\n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**HYPERPARAMS**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE=8*strategy.num_replicas_in_sync\n\nIMAGE_SIZE = 1024\n\nEPOCHS = 5\n\n\n#train tfrec files\nTRAINING_FILENAMES=['gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train00-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train01-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train02-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train03-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train04-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train05-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train06-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train07-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train08-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train09-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train10-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train11-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train12-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train13-2071.tfrec',\n 'gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train14-2071.tfrec',\n]\n\nVALID=tf.io.gfile.glob('gs://kds-f941eda182a90288c86bd91ec807ec5f6c58e5c4e0fbf9ad2114f762/tfrecords/train14-2071.tfrec')\n\n#test tfrec files\nTEST_FILENAMES=tf.io.gfile.glob(GCS_DS_PATH+ '/tfrecords/test*.tfrec')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# *Preprocessing*","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0  # convert image to floats in [0, 1] range\n    image = tf.reshape(image, [IMAGE_SIZE,IMAGE_SIZE, 3]) # explicit size needed for TPU\n    return image\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), # tf.string means bytestring\n        \"target\": tf.io.FixedLenFeature([], tf.int64),  # shape [] means single element\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image = decode_image(example['image'])\n    label = tf.cast(example['target'], tf.int32)\n    return image, label # returns a dataset of (image, label) pairs\n\ndef read_unlabeled_tfrecord(example):\n    UNLABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), # tf.string means bytestring\n        \"image_name\": tf.io.FixedLenFeature([], tf.string),  # shape [] means single element\n        # class is missing, this competitions's challenge is to predict flower classes for the test dataset\n    }\n    example = tf.io.parse_single_example(example, UNLABELED_TFREC_FORMAT)\n    image = decode_image(example['image'])\n    idnum = example['image_name']\n    return image, idnum # returns a dataset of image(s)\n\ndef load_dataset(filenames, labeled=True, ordered=False):\n    # Read from TFRecords. For optimal performance, reading from multiple files at once and\n    # disregarding data order. Order does not matter since we will be shuffling the data anyway.\n\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False # disable order, increase speed\n\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO) # automatically interleaves reads from multiple files\n    dataset = dataset.with_options(ignore_order) # uses data as soon as it streams in, rather than in its original order\n    dataset = dataset.map(read_labeled_tfrecord if labeled else read_unlabeled_tfrecord, num_parallel_calls=AUTO)\n    # returns a dataset of (image, label) pairs if labeled=True or (image, id) pairs if labeled=False\n    return dataset\n\ndef data_augment(image, label):\n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_hue(image,0.05)\n    image = tf.image.random_saturation(image, 0, 0.05)\n    return image, label  \n\ndef get_training_dataset():\n    dataset = load_dataset(TRAINING_FILENAMES, labeled=True)\n    dataset = dataset.map(data_augment, num_parallel_calls=AUTO)\n    dataset = dataset.repeat() # the training dataset must repeat for several epochs\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO) # prefetch next batch while training (autotune prefetch buffer size)\n    return dataset\n\ndef get_validation_dataset():\n    dataset = load_dataset(VALID, labeled=True)\n    dataset = dataset.map(data_augment, num_parallel_calls=AUTO)\n    dataset = dataset.repeat() # the training dataset must repeat for several epochs\n    dataset = dataset.shuffle(128)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO) # prefetch next batch while training (autotune prefetch buffer size)\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(AUTO) # prefetch next batch while training (autotune prefetch buffer size)\n    return dataset\n\ndef count_data_items(filenames):\n    # the number of data items is written in the name of the .tfrec files, i.e. flowers00-230.tfrec = 230 data items\n    n = [int(re.compile(r\"-([0-9]*)\\.\").search(filename).group(1)) for filename in filenames]\n    return np.sum(n)\n\nNUM_TRAINING_IMAGES = count_data_items(TRAINING_FILENAMES)\nNUM_VALIDATION_IMAGES= count_data_items(VALID)\nNUM_TEST_IMAGES = count_data_items(TEST_FILENAMES)\nSTEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE\nVALIDATION_STEPS= NUM_VALIDATION_IMAGES // BATCH_SIZE\nprint('Dataset: {} training images, {} validation images {} unlabeled test images'.format(NUM_TRAINING_IMAGES,NUM_VALIDATION_IMAGES,NUM_TEST_IMAGES))\nprint(\"STEPS_PER_EPOCH are {}\".format(STEPS_PER_EPOCH))\nprint(\"VALIDATION_STEPS are {}\".format(VALIDATION_STEPS))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Training Dataset**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#training preprocessed dataset \ntrain_ds=get_training_dataset()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_ds=get_validation_dataset()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for img,label in valid_ds.take(1):\n    print(img.numpy())\n    print(label.numpy())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Model imports**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2\nfrom tensorflow.keras import Sequential\nfrom tensorflow.keras.layers import GlobalAveragePooling2D,Dense,Flatten","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Callbacks**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def scheduler(epoch):\n  if epoch < 2:\n    return 0.001\n  else:\n    return 0.001 * tf.math.exp(0.1 * (10 - epoch))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"LR=tf.keras.callbacks.LearningRateScheduler(scheduler)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Training**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model=Sequential([\n        InceptionResNetV2(include_top=False,input_shape=(IMAGE_SIZE,IMAGE_SIZE,3)),\n        GlobalAveragePooling2D(),\n        Flatten(),\n        Dense(1024,activation='relu'),\n        Dense(1,activation='sigmoid')\n    ])\n    model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])\n    \n    model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit(train_ds,\n          epochs=EPOCHS,\n          steps_per_epoch=STEPS_PER_EPOCH,\n          validation_data=valid_ds,\n          validation_steps=VALIDATION_STEPS,\n          callbacks=[LR]\n         )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nloss=model.history.history.get('loss')\nacc=model.history.history.get('accuracy')\nval_loss=model.history.history.get('val_loss')\nval_acc=model.history.history.get('val_accuracy')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(loss,acc)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(val_acc)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predictions","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#testing dataset\ntest_ds=get_test_dataset(ordered=True)\n\ntest_images_ids=test_ds.map(lambda image ,idnum : image) #Retriving the image data from the test dataset\n\npredictions = model.predict(test_images_ids) #predictions on images\n\ntest_ids_ds = test_ds.map(lambda image, idnum: idnum).unbatch() #Retriving the Image name i.e., IDNUM\n\ntest_ids = next(iter(test_ids_ds.batch(NUM_TEST_IMAGES))).numpy().astype('U') #Getting the image names for the csv file\n\nprediction_df=pd.DataFrame({'image_name':test_ids ,'target':np.concatenate(predictions)})\n\nprediction_df.to_csv('submission.csv',index=False) #generating the submission.csv file","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Time taken\")\nprint(datetime.now()-start_time)","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}