{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"%ls ../input/dog-breed-identification/","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_hub as hub\nfrom tensorflow.keras import layers\n\nimport numpy as np\nimport pandas as pd\nfrom pathlib import Path\nfrom sklearn.model_selection import train_test_split\n\nINPUT_PATH = Path(\"../input/dog-breed-identification/\")\nTRAIN_ROOT_PATH = INPUT_PATH / \"train\"\nTEST_ROOT_PATH = INPUT_PATH / \"test\"\nLOG_PATH = Path(\"./logs\")\nCP_PATH = LOG_PATH / \"cp.ckpt\"\nlabels_df = pd.read_csv(INPUT_PATH / \"labels.csv\")\n\nprint(\"TF version:\", tf.__version__)\nprint(\"Hub version:\", hub.__version__)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# labels.csv\n# col_name\nimage_id_col = \"id\"\nlabel_col = \"breed\"\n\n# training settings\nEPOCHS = 10\nBATCH_SIZE = 32\nIMAGE_SIZE = 224\nCHANNELS = 3\nRANDOM_STATE = 1234\nSEED = 5678\nINPUT_SHAPE = (IMAGE_SIZE, IMAGE_SIZE, CHANNELS)\nNUM_CLASSES = labels_df[label_col].nunique()\n\n# tf.data.Dataset settings\nAUTOTUNE = tf.data.experimental.AUTOTUNE","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_to_index = dict((name, index) for index, name in enumerate(labels_df[label_col].unique()))\nlabel_to_index","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Reference\n# https://www.tensorflow.org/tutorials/load_data/images\ndef preprocess_image(image, size=224, channels=3):\n    image = tf.image.decode_jpeg(image, channels=channels)\n    image = tf.image.resize(image, [size, size])\n    image /= 255.0  # normalize to [0,1] range\n    return image\n\n\ndef load_and_preprocess_image(path):\n    image = tf.io.read_file(path)\n    return preprocess_image(image)\n\n\ndef get_label_index(label_name):\n    return label_to_index.get(label_name)\n\n\ndef get_image_path(part_path, ext=\".jpg\"):\n    file_name = part_path + ext\n    return str(TRAIN_ROOT_PATH / file_name)\n\n\ndef get_img_id(img_path):\n    return img_path.split(\"/\")[-1].strip(\".jpg\")\n\n\ndef get_label(img_path):\n    return labels_df[labels_df[\"id\"] == get_img_id(img_path)][label_col]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_image_paths = list(map(str, (INPUT_PATH / \"train\").glob(\"*.jpg\")))\ntest_image_paths = list(map(str, (INPUT_PATH / \"test\").glob(\"*.jpg\")))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train, x_valid, y_train, y_valid = train_test_split(labels_df[image_id_col],\n                                                      labels_df[label_col], \n                                                      stratify=labels_df[label_col],\n                                                      test_size=0.2,\n                                                      random_state=RANDOM_STATE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train.shape, x_valid.shape, y_train.shape, y_valid.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"get_image_path(x_train.values[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"get_label_index(y_train.values[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# TFRecord\n\n# train_image_ds = tf.data.Dataset.from_tensor_slices(train_image_paths).map(tf.io.read_file)\n# test_image_ds = tf.data.Dataset.from_tensor_slices(test_image_paths).map(tf.io.read_file)\n# train_paths_ds = tf.data.Dataset.from_tensor_slices(train_image_paths)\n# test_paths_ds = tf.data.Dataset.from_tensor_slices(test_image_paths)\n# train_image_ds = train_paths_ds.map(load_and_preprocess_image)\n# test_image_ds = test_paths_ds.map(load_and_preprocess_image)\n# train_tfrec = tf.data.experimental.TFRecordWriter('train_images.tfrec')\n# test_tfrec = tf.data.experimental.TFRecordWriter('test_images.tfrec')\n# train_image_ds = train_image_ds.map(tf.io.serialize_tensor)\n# test_image_ds = test_image_ds.map(tf.io.serialize_tensor)\n# train_tfrec.write(train_image_ds)\n# test_tfrec.write(test_image_ds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# path_ds = tf.data.Dataset.from_tensor_slices(list(map(get_image_path, x_train.values)))\n# image_ds = path_ds.map(load_and_preprocess_image, num_parallel_calls=AUTOTUNE)\n# label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(list(map(get_label_index, y_train.values)),\n#                                                       tf.int64))\n\ndef get_pair_ds(_images, _labels):\n    path_ds = tf.data.Dataset.from_tensor_slices(list(map(get_image_path, _images.values)))\n    image_ds = path_ds.map(load_and_preprocess_image, num_parallel_calls=AUTOTUNE)\n    label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(list(map(get_label_index, _labels.values)),\n                                                          tf.int64))\n    return image_ds, label_ds\n\n\ndef apply_ds(_length, _image_ds, _label_ds):\n    ds = tf.data.Dataset.zip((_image_ds, _label_ds))\n    ds = ds.apply(tf.data.experimental.shuffle_and_repeat(buffer_size=_length))\n    ds = ds.batch(BATCH_SIZE)\n    ds = ds.prefetch(buffer_size=AUTOTUNE)\n    return ds\n\ntrain_ds = apply_ds(len(x_train), *get_pair_ds(x_train, y_train))\nvalid_ds = apply_ds(len(x_valid), *get_pair_ds(x_valid, y_valid))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Reference\n# https://tfhub.dev/google/collections/efficientnet/1\nfeature_extractor_url = \"https://tfhub.dev/google/efficientnet/b0/feature-vector/1\"\n\ndef building_model(_input_shape, _num_classes):\n    feature_extractor_layer = hub.KerasLayer(feature_extractor_url,\n                                             input_shape=_input_shape)\n    feature_extractor_layer.trainable = False\n    model = tf.keras.Sequential([\n        feature_extractor_layer,\n        layers.Dense(_num_classes, activation='softmax')\n    ])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = building_model(INPUT_SHAPE, NUM_CLASSES)\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# callbacks\ntensorboard = tf.keras.callbacks.TensorBoard(str(LOG_PATH))\ncp_callback = tf.keras.callbacks.ModelCheckpoint(str(CP_PATH), \n                                                 save_weights_only=True,\n                                                 verbose=1)\nearly_stopping = tf.keras.callbacks.EarlyStopping(monitor=\"val_accuracy\",\n                                                  patience=3)\n_callbacks = [tensorboard, early_stopping, cp_callback]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr_steps_per_epoch = tf.math.ceil(len(x_train) / BATCH_SIZE).numpy()\nva_steps_per_epoch = tf.math.ceil(len(x_valid) / BATCH_SIZE).numpy()\ntr_steps_per_epoch, va_steps_per_epoch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(\n    optimizer=tf.keras.optimizers.Adam(),\n    loss='categorical_crossentropy',\n    metrics=['acc'])\n\nhistory = model.fit(train_ds,\n                    validation_data=valid_ds,\n                    epochs=EPOCHS,\n                    steps_per_epoch=tr_steps_per_epoch,\n                    validation_steps=va_steps_per_epoch,\n                    callbacks=_callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# loss, acc, val_loss, val_acc \nhist_keys = list(history.history.keys())","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}