{"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":"import tensorflow as tf\nimport numpy as np\nimport pandas as pd\nkeras = tf.keras","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-04-24T08:13:43.966227Z","iopub.execute_input":"2023-04-24T08:13:43.966841Z","iopub.status.idle":"2023-04-24T08:13:52.827157Z","shell.execute_reply.started":"2023-04-24T08:13:43.966811Z","shell.execute_reply":"2023-04-24T08:13:52.826013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from os import listdir\nfrom os.path import isfile, join\n\nTRAIN_IMG_PATH = \"/kaggle/input/dog-breed-identification/train/\"\nTEST_IMG_PATH = \"/kaggle/input/dog-breed-identification/test/\"\n\ntrain_paths = tf.constant([\n    TRAIN_IMG_PATH + f for f in listdir(TRAIN_IMG_PATH) if isfile(join(TRAIN_IMG_PATH, f))\n])\ntest_paths = tf.constant([\n    TEST_IMG_PATH + f for f in listdir(TEST_IMG_PATH) if isfile(join(TEST_IMG_PATH, f))\n])\nlen(train_paths), len(test_paths)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:14:33.515591Z","iopub.execute_input":"2023-04-24T08:14:33.516368Z","iopub.status.idle":"2023-04-24T08:14:55.244109Z","shell.execute_reply.started":"2023-04-24T08:14:33.516328Z","shell.execute_reply":"2023-04-24T08:14:55.243097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train = pd.read_csv(\"/kaggle/input/dog-breed-identification/labels.csv\")[\"breed\"]\ny_train.head()","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:06.051485Z","iopub.execute_input":"2023-04-24T08:15:06.052132Z","iopub.status.idle":"2023-04-24T08:15:06.089223Z","shell.execute_reply.started":"2023-04-24T08:15:06.052092Z","shell.execute_reply":"2023-04-24T08:15:06.088066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nencoder = LabelEncoder()\ny_train_enc = tf.constant(encoder.fit_transform(list(y_train)), dtype=tf.int32)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:09.769304Z","iopub.execute_input":"2023-04-24T08:15:09.769803Z","iopub.status.idle":"2023-04-24T08:15:10.140613Z","shell.execute_reply.started":"2023-04-24T08:15:09.769744Z","shell.execute_reply":"2023-04-24T08:15:10.139321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train_enc","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:18.460161Z","iopub.execute_input":"2023-04-24T08:15:18.460971Z","iopub.status.idle":"2023-04-24T08:15:18.470155Z","shell.execute_reply.started":"2023-04-24T08:15:18.460932Z","shell.execute_reply":"2023-04-24T08:15:18.469089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def path_to_ds(path, label):\n    ds = tf.data.Dataset.from_tensor_slices((path, label))\n    def _parse_function(filename, label):\n        image_string = tf.io.read_file(filename)\n        tensor = tf.io.decode_jpeg(image_string, channels=3)\n        tensor = tf.image.resize(tensor, [224, 224])\n        image = tf.cast(tensor, tf.float32)\n        return image, label\n\n    return ds.map(_parse_function).batch(32).prefetch(tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:20.259823Z","iopub.execute_input":"2023-04-24T08:15:20.260544Z","iopub.status.idle":"2023-04-24T08:15:20.267488Z","shell.execute_reply.started":"2023-04-24T08:15:20.260505Z","shell.execute_reply":"2023-04-24T08:15:20.266299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds = path_to_ds(train_paths[:int(0.8*len(train_paths))], y_train_enc[:int(0.8*len(train_paths))])\nvalid_ds = path_to_ds(train_paths[int(0.8*len(train_paths)):], y_train_enc[int(0.8*len(train_paths)):])","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:23.005867Z","iopub.execute_input":"2023-04-24T08:15:23.006583Z","iopub.status.idle":"2023-04-24T08:15:23.308238Z","shell.execute_reply.started":"2023-04-24T08:15:23.006545Z","shell.execute_reply":"2023-04-24T08:15:23.304916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train[:int(0.8*len(train_paths))].value_counts().plot(kind=\"barh\") # for train","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:26.187966Z","iopub.execute_input":"2023-04-24T08:15:26.188958Z","iopub.status.idle":"2023-04-24T08:15:28.187910Z","shell.execute_reply.started":"2023-04-24T08:15:26.188919Z","shell.execute_reply":"2023-04-24T08:15:28.186993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train[int(0.8*len(train_paths)):].value_counts().plot(kind=\"barh\") # for validation","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:31.077257Z","iopub.execute_input":"2023-04-24T08:15:31.077847Z","iopub.status.idle":"2023-04-24T08:15:32.956956Z","shell.execute_reply.started":"2023-04-24T08:15:31.077810Z","shell.execute_reply":"2023-04-24T08:15:32.955991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.utils.class_weight import compute_class_weight\nclass_weight = compute_class_weight(\n    class_weight=\"balanced\", classes=np.unique(y_train_enc.numpy()), y=y_train_enc.numpy()\n)\nclass_weight = {i:w for i,w in enumerate(class_weight)}","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:15:37.077560Z","iopub.execute_input":"2023-04-24T08:15:37.078266Z","iopub.status.idle":"2023-04-24T08:15:37.087521Z","shell.execute_reply.started":"2023-04-24T08:15:37.078222Z","shell.execute_reply":"2023-04-24T08:15:37.086433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_augmentation = tf.keras.Sequential([\n  tf.keras.layers.RandomFlip('horizontal'),\n  tf.keras.layers.RandomRotation(0.2),\n  tf.keras.layers.RandomBrightness(0.2, value_range=(-1, 1)),\n])\n\npreprocess_input = keras.applications.xception.preprocess_input\n\nbase_model = keras.applications.Xception(\n    weights=\"imagenet\",\n    include_top=False)\n\nglobal_avg = keras.layers.GlobalAveragePooling2D()\n\n# make not trainable\nbase_model.trainable = False\n\ninputs = tf.keras.Input(shape=(224, 224, 3))\nx = data_augmentation(inputs)\nx = preprocess_input(x)\n# `training=False` to make it run in inference mode: e.g. for batch-norm\nx = base_model(x, training=False)\nx = global_avg(x)\n\n# for now remove dropout\n# x = tf.keras.layers.Dropout(0.3)(x)\n\n# 120 classes so 120 units\n# I removed \"prediction_layer(x)\" to make things explicit\noutputs = tf.keras.layers.Dense(units=120, name='logits')(x)\n\n\nmodel = tf.keras.Model(inputs, outputs)\n\nmodel.compile(optimizer=\"adam\",\n              loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n              metrics = ['sparse_categorical_accuracy', \"sparse_top_k_categorical_accuracy\"]\n                        )\n\nhistory = model.fit(\n    train_ds,\n    epochs=50,\n    validation_data=valid_ds,\n    # try without class weights first\n    # class_weight=class_weight\n)","metadata":{"execution":{"iopub.status.busy":"2023-04-24T08:42:27.349102Z","iopub.execute_input":"2023-04-24T08:42:27.350165Z","iopub.status.idle":"2023-04-24T09:02:29.821692Z","shell.execute_reply.started":"2023-04-24T08:42:27.350114Z","shell.execute_reply":"2023-04-24T09:02:29.819943Z"},"trusted":true},"execution_count":null,"outputs":[]}]}