{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-16T16:48:15.624654Z","iopub.execute_input":"2022-05-16T16:48:15.625188Z","iopub.status.idle":"2022-05-16T16:48:15.704838Z","shell.execute_reply.started":"2022-05-16T16:48:15.625146Z","shell.execute_reply":"2022-05-16T16:48:15.70388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\n\nprint(f\"Tensorflow version ${tf.__version__}\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:15.707467Z","iopub.execute_input":"2022-05-16T16:48:15.707865Z","iopub.status.idle":"2022-05-16T16:48:15.713487Z","shell.execute_reply.started":"2022-05-16T16:48:15.707825Z","shell.execute_reply":"2022-05-16T16:48:15.712405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print(f\"Running on TPU: ${tpu.master()}\")\nexcept ValueError:\n    print(\"failed\")\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()\n\nprint(f\"REPLICAS: {strategy.num_replicas_in_sync}\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:15.714654Z","iopub.execute_input":"2022-05-16T16:48:15.714957Z","iopub.status.idle":"2022-05-16T16:48:21.871479Z","shell.execute_reply.started":"2022-05-16T16:48:15.714924Z","shell.execute_reply":"2022-05-16T16:48:21.870467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from kaggle_datasets import KaggleDatasets\n\nGCS_DS_PATH = KaggleDatasets().get_gcs_path(\"tpu-getting-started\")\nprint(GCS_DS_PATH)\n!gsutil ls $GCS_DS_PATH","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:21.873476Z","iopub.execute_input":"2022-05-16T16:48:21.873767Z","iopub.status.idle":"2022-05-16T16:48:25.914628Z","shell.execute_reply.started":"2022-05-16T16:48:21.873732Z","shell.execute_reply":"2022-05-16T16:48:25.913202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE = [512, 512] # or 224, 331, 512\nGCS_PATH = f\"{GCS_DS_PATH}/tfrecords-jpeg-{IMAGE_SIZE[0]}x{IMAGE_SIZE[1]}\"\n\nTRAINING_FILENAMES = tf.io.gfile.glob(f\"{GCS_PATH}/train/*.tfrec\")\nVALIDATION_FILENAMES = tf.io.gfile.glob(f\"{GCS_PATH}/val/*.tfrec\")\nTEST_FILENAMES = tf.io.gfile.glob(f\"{GCS_PATH}/test/*.tfrec\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:25.917837Z","iopub.execute_input":"2022-05-16T16:48:25.919059Z","iopub.status.idle":"2022-05-16T16:48:26.183393Z","shell.execute_reply.started":"2022-05-16T16:48:25.918982Z","shell.execute_reply":"2022-05-16T16:48:26.182135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.data.experimental import AUTOTUNE\n\nCLASSES = ['pink primrose',    'hard-leaved pocket orchid', \n           'canterbury bells', 'sweet pea',     \n           'wild geranium',    'tiger lily',           \n           'moon orchid',      'bird of paradise', \n           'monkshood',        'globe thistle',         # 00 - 09\n           \n           'snapdragon',       \"colt's foot\",               \n           'king protea',      'spear thistle', \n           'yellow iris',      'globe-flower',\n           'purple coneflower','peruvian lily',\n           'balloon flower',   'giant white arum lily', # 10 - 19\n           \n           'fire lily',        'pincushion flower',\n           'fritillary',       'red ginger',\n           'grape hyacinth',    'corn poppy',\n           'prince of wales feathers', 'stemless gentian',\n           'artichoke',        'sweet william',         # 20 - 29\n           \n           'carnation',        'garden phlox',\n           'love in the mist', 'cosmos',\n           'alpine sea holly', 'ruby-lipped cattleya',\n           'cape flower',      'great masterwort',\n           'siam tulip',       'lenten rose',           # 30 - 39\n           \n           'barberton daisy',  'daffodil',\n           'sword lily',       'poinsettia',\n           'bolero deep blue', 'wallflower',\n           'marigold',         'buttercup',\n           'daisy',            'common dandelion',      # 40 - 49\n           \n           'petunia',          'wild pansy',\n           'primula',          'sunflower',\n           'lilac hibiscus',   'bishop of llandaff',\n           'gaura',            'geranium',\n           'orange dahlia',    'pink-yellow dahlia',    # 50 - 59\n           \n           'cautleya spicata', 'japanese anemone',\n           'black-eyed susan', 'silverbush',\n           'californian poppy','osteospermum',\n           'spring crocus',    'iris',\n           'windflower',       'tree poppy',            # 60 - 69\n           \n           'gazania',          'azalea',\n           'water lily',       'rose',\n           'thorn apple',      'morning glory',\n           'passion flower',   'lotus',\n           'toad lily',        'anthurium',             # 70 - 79\n           \n           'frangipani',       'clematis',\n           'hibiscus',         'columbine',\n           'desert-rose',      'tree mallow',\n           'magnolia',         'cyclamen ',\n           'watercress',       'canna lily',            # 80 - 89\n           \n           'hippeastrum ',     'bee balm',\n           'pink quill',       'foxglove',\n           'bougainvillea',    'camellia',\n           'mallow',           'mexican petunia',\n           'bromelia',         'blanket flower',        # 90 - 99\n           \n           'trumpet creeper',  'blackberry lily',\n           'common tulip',     'wild rose']                                                                                                                                               # 100 - 102\n\ndef decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.cast(image, tf.float32)/255.0\n    image = tf.reshape(image, [*IMAGE_SIZE,3])\n    return image\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFR_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"class\": tf.io.FixedLenFeature([], tf.int64)\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFR_FORMAT)\n    image = decode_image(example[\"image\"])\n    label = tf.cast(example[\"class\"], tf.int32)\n    return image, label\n\ndef read_unlabeled_tfrecord(example):\n    UNLABELED_TFR_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"id\": tf.io.FixedLenFeature([], tf.string)\n    }\n    example = tf.io.parse_single_example(example, UNLABELED_TFR_FORMAT)\n    image = decode_image(example[\"image\"])\n    idnum = example[\"id\"]\n    return image, idnum\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 # disable order, increase speed\n    \n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTOTUNE)\n    dataset = dataset.with_options(ignore_order)\n    if labeled:\n        dataset = dataset.map(read_labeled_tfrecord, num_parallel_calls=AUTOTUNE)\n    else:\n        dataset = dataset.map(read_unlabeled_tfrecord, num_parallel_calls=AUTOTUNE)\n    return dataset","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:26.185715Z","iopub.execute_input":"2022-05-16T16:48:26.18611Z","iopub.status.idle":"2022-05-16T16:48:26.212939Z","shell.execute_reply.started":"2022-05-16T16:48:26.186054Z","shell.execute_reply":"2022-05-16T16:48:26.211436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import re\nimport random\nBATCH_SIZE = 16 * strategy.num_replicas_in_sync\n\nrng = tf.random.Generator.from_seed(4711, alg='philox')\n\ndef data_augment(image, label):\n    # fill here with data augmentation manipulations later\n    seed = rng.make_seeds(2)[0]\n    image = tf.image.stateless_random_brightness(image, 0.25, seed)\n    image = tf.image.stateless_random_contrast(image, 0.9, 1.1, seed)\n    #image = tf.image.stateless_random_hue(image, 0.1, seed)\n    #image = tf.image.stateless_random_saturation(image, 1, 1.5, seed)\n    image = tf.image.stateless_random_flip_left_right(image, seed)\n    image = tf.image.stateless_random_flip_up_down(image, seed)\n    coeff1 = random.uniform(0.7, 0.9)\n    coeff2 = random.uniform(0.7, 0.9)\n    crop = [int(IMAGE_SIZE[0]*coeff1), int(IMAGE_SIZE[1]*coeff2)]\n    image = tf.image.stateless_random_crop(image, (crop[0], crop[1],3),\n                                          seed)\n    image = tf.image.resize(image, [IMAGE_SIZE[0], IMAGE_SIZE[1]])\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=AUTOTUNE)\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_validation_dataset(ordered=False):\n    dataset = load_dataset(VALIDATION_FILENAMES, labeled=True, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.cache()\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\n\ndef count_data_items(filenames):\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(VALIDATION_FILENAMES)\nNUM_TEST_IMAGES = count_data_items(TEST_FILENAMES)\n\nprint(f\"\"\"\n{NUM_TRAINING_IMAGES} training images\n{NUM_VALIDATION_IMAGES} validation images\n{NUM_TEST_IMAGES} unlabeled testing images\"\"\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:26.214719Z","iopub.execute_input":"2022-05-16T16:48:26.215042Z","iopub.status.idle":"2022-05-16T16:48:26.241492Z","shell.execute_reply.started":"2022-05-16T16:48:26.215003Z","shell.execute_reply":"2022-05-16T16:48:26.240592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train = get_training_dataset()\nds_val = get_validation_dataset()\nds_test = get_test_dataset()\n\nprint(f\"\"\"\nTraining data: {ds_train}\nValidation data: {ds_val}\nTest data: {ds_test}\n\"\"\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:26.243344Z","iopub.execute_input":"2022-05-16T16:48:26.243664Z","iopub.status.idle":"2022-05-16T16:48:27.194498Z","shell.execute_reply.started":"2022-05-16T16:48:26.243628Z","shell.execute_reply":"2022-05-16T16:48:27.193172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Training data shapes:\")\nfor image, label in ds_train.take(3):\n    print(image.numpy().shape, label.numpy().shape)\nprint(f\"Training data labels: \\n{label.numpy()}\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:27.196115Z","iopub.execute_input":"2022-05-16T16:48:27.196439Z","iopub.status.idle":"2022-05-16T16:48:33.049137Z","shell.execute_reply.started":"2022-05-16T16:48:27.196403Z","shell.execute_reply":"2022-05-16T16:48:33.04808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Test data shapes:\")\nfor image, idnum in ds_test.take(3):\n    print(image.numpy().shape, idnum.numpy().shape)\nprint(f\"Test data labels: \\n{idnum.numpy().astype('U')}\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:33.052872Z","iopub.execute_input":"2022-05-16T16:48:33.053579Z","iopub.status.idle":"2022-05-16T16:48:36.054889Z","shell.execute_reply.started":"2022-05-16T16:48:33.053526Z","shell.execute_reply":"2022-05-16T16:48:36.053741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib import pyplot\n\nimage, label = next(ds_train.take(1).as_numpy_iterator())\npyplot.figure(figsize=(20,20))\nfor i in range(100):\n    pyplot.subplot(10,10,i+1)\n    pyplot.imshow(image[i,:,:,:])\n    pyplot.axis(\"off\")\n    pyplot.title(CLASSES[label[i]])","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:36.057385Z","iopub.execute_input":"2022-05-16T16:48:36.058095Z","iopub.status.idle":"2022-05-16T16:48:53.441177Z","shell.execute_reply.started":"2022-05-16T16:48:36.058038Z","shell.execute_reply":"2022-05-16T16:48:53.438721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -q efficientnet","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:48:53.443103Z","iopub.execute_input":"2022-05-16T16:48:53.443734Z","iopub.status.idle":"2022-05-16T16:49:03.032718Z","shell.execute_reply.started":"2022-05-16T16:48:53.443693Z","shell.execute_reply":"2022-05-16T16:49:03.031477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow import keras\n#from tensorflow.keras.applications import DenseNet201\nfrom efficientnet.tfkeras import EfficientNetB7\nwith strategy.scope():\n    base_model =EfficientNetB7(\n    include_top=False,\n    weights='noisy-student',\n    input_shape=[*IMAGE_SIZE, 3]\n    )\n    base_model.trainable = False\n    model = tf.keras.Sequential([\n        base_model,\n        keras.layers.GlobalAveragePooling2D(),\n        keras.layers.Dense(2048, activation='relu'),\n        keras.layers.Dropout(0.2),\n        keras.layers.Dense(1024, activation='relu'),\n        keras.layers.Dropout(0.5),\n        #keras.layers.Dense(1024, activation='elu'),\n        #keras.layers.Dropout(0.5),\n        #keras.layers.Dense(512, activation='elu'),\n        tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n    ])\nprint(model.summary())\nkeras.utils.plot_model(model)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:49:03.036104Z","iopub.execute_input":"2022-05-16T16:49:03.036584Z","iopub.status.idle":"2022-05-16T16:49:50.642348Z","shell.execute_reply.started":"2022-05-16T16:49:03.036527Z","shell.execute_reply":"2022-05-16T16:49:50.640452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"from tensorflow import keras\n\nwith strategy.scope():\n    inputs = keras.Input(shape=[*IMAGE_SIZE, 3])\n    conv1 = keras.layers.Conv2D(256, kernel_size=4, activation='relu')(model)\n    pool1 = keras.layers.MaxPooling2D(pool_size=(2,2))(conv1)\n    conv2 = keras.layers.Conv2D(128, kernel_size=4, activation='relu')(pool1)\n    pool2 = keras.layers.MaxPooling2D(pool_size=(2,2))(conv2)\n    conv3 = keras.layers.Conv2D(64, kernel_size=4, activation='relu')(pool2)\n    pool3 = keras.layers.MaxPooling2D(pool_size=(2,2))(conv3)\n    conv4 = keras.layers.Conv2D(64, kernel_size=4, activation='relu')(pool3)\n    pool4 = keras.layers.MaxPooling2D(pool_size=(2,2))(conv4)\n    flat = keras.layers.Flatten()(pool4)\n    hidden = keras.layers.Dense(128, activation='relu')(flat)\n    outputs = keras.layers.Dense(len(CLASSES), activation=\"softmax\")(hidden)\n    model = keras.Model(inputs=inputs, outputs=outputs)\nprint(model.summary())\nkeras.utils.plot_model(model)","metadata":{"execution":{"iopub.status.busy":"2022-04-06T15:08:16.790263Z","iopub.execute_input":"2022-04-06T15:08:16.791027Z","iopub.status.idle":"2022-04-06T15:08:16.849242Z","shell.execute_reply.started":"2022-04-06T15:08:16.790985Z","shell.execute_reply":"2022-04-06T15:08:16.848017Z"}}},{"cell_type":"code","source":"model.compile(\n    optimizer=keras.optimizers.Adam(learning_rate=0.001,beta_1=0.9,beta_2=0.999,amsgrad=False),\n    loss='sparse_categorical_crossentropy',\n    metrics=['sparse_categorical_accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:49:50.645659Z","iopub.execute_input":"2022-05-16T16:49:50.646682Z","iopub.status.idle":"2022-05-16T16:49:50.741885Z","shell.execute_reply.started":"2022-05-16T16:49:50.646631Z","shell.execute_reply":"2022-05-16T16:49:50.740519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LR_START = 0.0001\nLR_MAX = 0.00005 * strategy.num_replicas_in_sync\nLR_MIN = 0.00001\nLR_RAMPUP_EPOCHS = 4\nLR_SUSTAIN_EPOCHS = 6\nLR_EXP_DECAY = 0.8\n\ndef lrfn(epoch):\n    if epoch < LR_RAMPUP_EPOCHS:\n        lr = np.random.random_sample()*LR_START\n    elif epoch < LR_RAMPUP_EPOCHS + LR_SUSTAIN_EPOCHS:\n        lr = LR_MAX\n    else:\n        lr = (LR_MAX - LR_MIN) * LR_EXP_DECAY ** (epoch - LR_RAMPUP_EPOCHS - LR_SUSTAIN_EPOCHS) + LR_MIN\n    return lr\n\nlocal_save_options = tf.saved_model.SaveOptions(experimental_io_device='/job:localhost')\nlr_callback = keras.callbacks.LearningRateScheduler(lrfn, verbose=True)\ncp_callback = keras.callbacks.ModelCheckpoint(\n        \"best_model.hdf5\",\n        monitor=\"val_sparse_categorical_accuracy\",\n        save_best_only=True,\n        verbose=1,\n        options=local_save_options\n    )","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:49:50.744847Z","iopub.execute_input":"2022-05-16T16:49:50.746812Z","iopub.status.idle":"2022-05-16T16:49:50.763549Z","shell.execute_reply.started":"2022-05-16T16:49:50.746748Z","shell.execute_reply":"2022-05-16T16:49:50.761741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE\nhistories = []","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:49:50.765786Z","iopub.execute_input":"2022-05-16T16:49:50.766173Z","iopub.status.idle":"2022-05-16T16:49:50.778309Z","shell.execute_reply.started":"2022-05-16T16:49:50.76613Z","shell.execute_reply":"2022-05-16T16:49:50.776792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS = 500\n#STEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE\n\nhistories.append(model.fit(\n    ds_train,\n    validation_data=ds_val,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH,\n    callbacks=[lr_callback, cp_callback]\n))\nmodel.load_weights(\"best_model.hdf5\")\n#16/16: 0.87123","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:49:50.780868Z","iopub.execute_input":"2022-05-16T16:49:50.78134Z","iopub.status.idle":"2022-05-16T17:50:45.640799Z","shell.execute_reply.started":"2022-05-16T16:49:50.781272Z","shell.execute_reply":"2022-05-16T17:50:45.638863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pyplot.figure(figsize=(16,8))\npyplot.plot(np.hstack([history.history[\"loss\"] for history in histories]))\npyplot.plot(np.hstack([history.history[\"val_loss\"] for history in histories]))\npyplot.title(\"Loss vs. Validation Loss\")\npyplot.xlabel(\"Epoch\")\npyplot.legend([\"train\", \"valid.\"])","metadata":{"execution":{"iopub.status.busy":"2022-05-16T17:50:45.642203Z","iopub.status.idle":"2022-05-16T17:50:45.642718Z","shell.execute_reply.started":"2022-05-16T17:50:45.642498Z","shell.execute_reply":"2022-05-16T17:50:45.642519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pyplot.figure(figsize=(16,8))\npyplot.plot(np.hstack([history.history[\"sparse_categorical_accuracy\"] \n                  for history in histories]))\npyplot.plot(np.hstack([history.history[\"val_sparse_categorical_accuracy\"]\n                 for history in histories]))\npyplot.title(\"Accuracy vs. Validation Accuracy\")\npyplot.xlabel(\"Epoch\")\npyplot.legend([\"train\", \"valid.\"])","metadata":{"execution":{"iopub.status.busy":"2022-05-16T17:50:45.644524Z","iopub.status.idle":"2022-05-16T17:50:45.645425Z","shell.execute_reply.started":"2022-05-16T17:50:45.645165Z","shell.execute_reply":"2022-05-16T17:50:45.645192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_test = get_test_dataset(ordered=True)\nds_test_images = ds_test.map(lambda image,idnum: image)\nds_test_idnums = ds_test.map(lambda image,idnum: idnum)\n\nprint(\"Computing predictions...\")\nprobabilities = model.predict(ds_test_images)\npredictions = np.argmax(probabilities, axis=-1)\nprint(predictions)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T17:50:45.646795Z","iopub.status.idle":"2022-05-16T17:50:45.647204Z","shell.execute_reply.started":"2022-05-16T17:50:45.646992Z","shell.execute_reply":"2022-05-16T17:50:45.647011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'id': next(iter(ds_test_idnums.unbatch().batch(NUM_TEST_IMAGES))).numpy().astype(\"U\"),\n    'label': predictions\n}).set_index('id')\nsubmission","metadata":{"execution":{"iopub.status.busy":"2022-05-16T17:50:45.648617Z","iopub.status.idle":"2022-05-16T17:50:45.649055Z","shell.execute_reply.started":"2022-05-16T17:50:45.64885Z","shell.execute_reply":"2022-05-16T17:50:45.648871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T17:50:45.651443Z","iopub.status.idle":"2022-05-16T17:50:45.652086Z","shell.execute_reply.started":"2022-05-16T17:50:45.651881Z","shell.execute_reply":"2022-05-16T17:50:45.651905Z"},"trusted":true},"execution_count":null,"outputs":[]}]}