{"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":"markdown","source":"# Implementing ResNet-18 Using Keras","metadata":{}},{"cell_type":"markdown","source":"In this note book I will try to implement ResNet-18 using Keras and compare my implementation with the standard implementation provided in keras.application","metadata":{}},{"cell_type":"markdown","source":"**## preprocess","metadata":{}},{"cell_type":"code","source":"# imoport module\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport keras\nfrom tensorflow.keras import datasets,models,layers\nimport skimage.io\nimport skimage.transform\nimport os\nimport time\nimport tensorflow_datasets as tfds\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# special function\ndef time_print(t1,t2):\n    print(\"time: \",end=\"\")\n    print(round((t2-t1),1),end=\"\")\n    print(\" sec\")","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:13:34.515725Z","iopub.execute_input":"2021-06-14T02:13:34.516398Z","iopub.status.idle":"2021-06-14T02:13:34.521396Z","shell.execute_reply.started":"2021-06-14T02:13:34.516352Z","shell.execute_reply":"2021-06-14T02:13:34.520442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## define label\nclass_dir = {}\nroot = \"../input/garbageclassificationzip3/garbage_classification\"\ni = 0.0\nfor dir_name in os.listdir(root):\n    class_dir[dir_name] = i\n    i = i + 1.0\nprint(class_dir)\n\n### get filenames and labels\nfilenames = []\nlabels = []\nt1 = time.time()\nfor dir_name in os.listdir(root):\n    img_dir_path = os.path.join(root,dir_name)\n    for file_name in os.listdir(img_dir_path):\n        img_file_path = os.path.join(img_dir_path,file_name)\n        label_num = class_dir[dir_name]\n        filenames.append(img_file_path)\n        labels.append(label_num)\n\n        \nimg_shape = 128\n## load image\nt3 = time.time()\nimg_list = []\nfor file_name in filenames:\n    img = tf.keras.preprocessing.image.load_img(file_name,target_size =(img_shape,img_shape))\n    img = np.array(img)\n    unit_ = img.reshape((1,img_shape,img_shape,3))\n    img_list.append(unit_)\n    print(\".\",end=\"\")\nt4=time.time()    \ntime_print(t3,t4)","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:13:37.084711Z","iopub.execute_input":"2021-06-14T02:13:37.08511Z","iopub.status.idle":"2021-06-14T02:15:47.308533Z","shell.execute_reply.started":"2021-06-14T02:13:37.085078Z","shell.execute_reply":"2021-06-14T02:15:47.307032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''## define label\nclass_dir = {}\nroot = \"../input/my-trash-test-3/my trash test\"\ni = 0.0\nfor dir_name in os.listdir(root):\n    class_dir[dir_name] = i\n    i = i + 1.0\nprint(class_dir)\n\n### get filenames and labels\nfilenames = []\nlabels = []\nt1 = time.time()\nfor dir_name in os.listdir(root):\n    img_dir_path = os.path.join(root,dir_name)\n    for file_name in os.listdir(img_dir_path):\n        img_file_path = os.path.join(img_dir_path,file_name)\n        label_num = class_dir[dir_name]\n        filenames.append(img_file_path)\n        labels.append(label_num)\n\nimg_shape = 64\n## load image\nt3 = time.time()\nimg_list = []\nfor file_name in filenames:\n    img = tf.keras.preprocessing.image.load_img(file_name,target_size =(img_shape,img_shape))\n    img = np.array(img)\n    unit_ = img.reshape((1,img_shape,img_shape,3))\n    img_list.append(unit_)\n    print(\".\",end=\"\")\nt4 = time.time()\ntime_print(t3,t4)\n'''","metadata":{"execution":{"iopub.status.busy":"2021-06-14T00:19:33.622131Z","iopub.execute_input":"2021-06-14T00:19:33.622726Z","iopub.status.idle":"2021-06-14T00:19:33.630622Z","shell.execute_reply.started":"2021-06-14T00:19:33.622673Z","shell.execute_reply":"2021-06-14T00:19:33.629629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_dataset = np.concatenate(img_list,axis=0)\nprint(x_dataset.shape)\ny_dataset = np.reshape(np.array(labels),(np.array(labels).shape[0],1))\nprint(y_dataset.shape)","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:19.060708Z","iopub.execute_input":"2021-06-14T02:16:19.061148Z","iopub.status.idle":"2021-06-14T02:16:20.33989Z","shell.execute_reply.started":"2021-06-14T02:16:19.061114Z","shell.execute_reply":"2021-06-14T02:16:20.338251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Normalize the data.\nX_train = x_dataset.astype('float32')/255.0\nY_train = y_dataset","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:21.889775Z","iopub.execute_input":"2021-06-14T02:16:21.890398Z","iopub.status.idle":"2021-06-14T02:16:26.740034Z","shell.execute_reply.started":"2021-06-14T02:16:21.89029Z","shell.execute_reply":"2021-06-14T02:16:26.738995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size = 0.2,shuffle = True)","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:30.330606Z","iopub.execute_input":"2021-06-14T02:16:30.331162Z","iopub.status.idle":"2021-06-14T02:16:35.744109Z","shell.execute_reply.started":"2021-06-14T02:16:30.331101Z","shell.execute_reply":"2021-06-14T02:16:35.742776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import OneHotEncoder\nencoder = OneHotEncoder()\nencoder.fit(Y_train.tolist())\nY_train = encoder.transform(Y_train.tolist()).toarray()\nY_val =  encoder.transform(Y_val.tolist()).toarray()\n","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:37.715442Z","iopub.execute_input":"2021-06-14T02:16:37.715877Z","iopub.status.idle":"2021-06-14T02:16:37.758661Z","shell.execute_reply.started":"2021-06-14T02:16:37.715815Z","shell.execute_reply":"2021-06-14T02:16:37.757467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Y_train\",Y_train.shape)\nprint(\"Y_val\",Y_val.shape)","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:41.307684Z","iopub.execute_input":"2021-06-14T02:16:41.30812Z","iopub.status.idle":"2021-06-14T02:16:41.315447Z","shell.execute_reply.started":"2021-06-14T02:16:41.308087Z","shell.execute_reply":"2021-06-14T02:16:41.314148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nResNet-18\nReference:\n[1] K. He et al. Deep Residual Learning for Image Recognition. CVPR, 2016\n[2] K. He, X. Zhang, S. Ren, and J. Sun. Delving deep into rectifiers:\nSurpassing human-level performance on imagenet classification. In\nICCV, 2015.\n\"\"\"\n\n\nfrom keras.callbacks import EarlyStopping\nfrom keras.layers import Dense, Conv2D,  MaxPool2D, Flatten, GlobalAveragePooling2D,  BatchNormalization, Layer, Add\nfrom keras.models import Sequential\nfrom keras.models import Model\nimport tensorflow as tf\n\n\nclass ResnetBlock(Model):\n    \"\"\"\n    A standard resnet block.\n    \"\"\"\n\n    def __init__(self, channels: int, down_sample=False):\n        \"\"\"\n        channels: same as number of convolution kernels\n        \"\"\"\n        super().__init__()\n\n        self.__channels = channels\n        self.__down_sample = down_sample\n        self.__strides = [2, 1] if down_sample else [1, 1]\n\n        KERNEL_SIZE = (3, 3)\n        # use He initialization, instead of Xavier (a.k.a 'glorot_uniform' in Keras), as suggested in [2]\n        INIT_SCHEME = \"he_normal\"\n\n        self.conv_1 = Conv2D(self.__channels, strides=self.__strides[0],\n                             kernel_size=KERNEL_SIZE, padding=\"same\", kernel_initializer=INIT_SCHEME)\n        self.bn_1 = BatchNormalization()\n        self.conv_2 = Conv2D(self.__channels, strides=self.__strides[1],\n                             kernel_size=KERNEL_SIZE, padding=\"same\", kernel_initializer=INIT_SCHEME)\n        self.bn_2 = BatchNormalization()\n        self.merge = Add()\n\n        if self.__down_sample:\n            # perform down sampling using stride of 2, according to [1].\n            self.res_conv = Conv2D(\n                self.__channels, strides=2, kernel_size=(1, 1), kernel_initializer=INIT_SCHEME, padding=\"same\")\n            self.res_bn = BatchNormalization()\n\n    def call(self, inputs):\n        res = inputs\n\n        x = self.conv_1(inputs)\n        x = self.bn_1(x)\n        x = tf.nn.relu(x)\n        x = self.conv_2(x)\n        x = self.bn_2(x)\n\n        if self.__down_sample:\n            res = self.res_conv(res)\n            res = self.res_bn(res)\n\n        # if not perform down sample, then add a shortcut directly\n        x = self.merge([x, res])\n        out = tf.nn.relu(x)\n        return out\n\n\nclass ResNet18(Model):\n\n    def __init__(self, num_classes, **kwargs):\n        \"\"\"\n            num_classes: number of classes in specific classification task.\n        \"\"\"\n        super().__init__(**kwargs)\n        self.conv_1 = Conv2D(64, (7, 7), strides=2,\n                             padding=\"same\", kernel_initializer=\"he_normal\")\n        self.init_bn = BatchNormalization()\n        self.pool_2 = MaxPool2D(pool_size=(2, 2), strides=2, padding=\"same\")\n        self.res_1_1 = ResnetBlock(64)\n        self.res_1_2 = ResnetBlock(64)\n        self.res_2_1 = ResnetBlock(128, down_sample=True)\n        self.res_2_2 = ResnetBlock(128)\n        self.res_3_1 = ResnetBlock(256, down_sample=True)\n        self.res_3_2 = ResnetBlock(256)\n        self.res_4_1 = ResnetBlock(512, down_sample=True)\n        self.res_4_2 = ResnetBlock(512)\n        self.avg_pool = GlobalAveragePooling2D()\n        self.flat = Flatten()\n        self.fc = Dense(num_classes, activation=\"softmax\")\n\n    def call(self, inputs):\n        out = self.conv_1(inputs)\n        out = self.init_bn(out)\n        out = tf.nn.relu(out)\n        out = self.pool_2(out)\n        for res_block in [self.res_1_1, self.res_1_2, self.res_2_1, self.res_2_2, self.res_3_1, self.res_3_2, self.res_4_1, self.res_4_2]:\n            out = res_block(out)\n        out = self.avg_pool(out)\n        out = self.flat(out)\n        out = self.fc(out)\n        return out","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:43.470269Z","iopub.execute_input":"2021-06-14T02:16:43.470727Z","iopub.status.idle":"2021-06-14T02:16:43.504795Z","shell.execute_reply.started":"2021-06-14T02:16:43.470691Z","shell.execute_reply":"2021-06-14T02:16:43.502926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = ResNet18(12)\nmodel.build(input_shape = (None,img_shape,img_shape,3))\n#use categorical_crossentropy since the label is one-hot encoded\nfrom keras.optimizers import SGD\n# opt = SGD(learning_rate=0.1,momentum=0.9,decay = 1e-04) #parameters suggested by He [1]\nmodel.compile(optimizer = \"adam\",loss='categorical_crossentropy', metrics=[\"accuracy\"]) \nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:50.444177Z","iopub.execute_input":"2021-06-14T02:16:50.444755Z","iopub.status.idle":"2021-06-14T02:16:51.226941Z","shell.execute_reply.started":"2021-06-14T02:16:50.44472Z","shell.execute_reply":"2021-06-14T02:16:51.225216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_train.shape)\nprint(Y_train.shape)\nhistory = model.fit(X_train,Y_train,epochs=10,validation_data=(X_val, Y_val))","metadata":{"execution":{"iopub.status.busy":"2021-06-14T02:16:56.177247Z","iopub.execute_input":"2021-06-14T02:16:56.177661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plotmodelhistory(history): \n    fig, axs = plt.subplots(1,2,figsize=(15,5)) \n    # summarize history for accuracy\n    axs[0].plot(history.history['accuracy']) \n    axs[0].plot(history.history['val_accuracy']) \n    axs[0].set_title('Model Accuracy')\n    axs[0].set_ylabel('Accuracy') \n    axs[0].set_xlabel('Epoch')\n    \n    axs[0].legend(['train', 'validate'], loc='upper left')\n    # summarize history for loss\n    axs[1].plot(history.history['loss']) \n    axs[1].plot(history.history['val_loss']) \n    axs[1].set_title('Model Loss')\n    axs[1].set_ylabel('Loss') \n    axs[1].set_xlabel('Epoch')\n    axs[1].legend(['train', 'validate'], loc='upper left')\n    plt.show()\n\n# list all data in history\n#print(history.history.keys())\nplotmodelhistory(history)\nprint(history.history)\n\nprint(type(history.history))","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:40:58.776518Z","iopub.execute_input":"2021-06-13T14:40:58.776948Z","iopub.status.idle":"2021-06-13T14:40:59.187005Z","shell.execute_reply.started":"2021-06-13T14:40:58.776908Z","shell.execute_reply":"2021-06-13T14:40:59.185763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plotmodelhistory(history)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:02.277475Z","iopub.execute_input":"2021-06-13T14:41:02.277798Z","iopub.status.idle":"2021-06-13T14:41:02.536463Z","shell.execute_reply.started":"2021-06-13T14:41:02.27776Z","shell.execute_reply":"2021-06-13T14:41:02.535781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\ndictionary_data = history.history\na_file = open(\"data.json\", \"w\")\njson. dump(dictionary_data, a_file)\na_file. close()\na_file = open(\"data.json\", \"r\")\noutput = a_file. read()\nprint(output)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:04.894257Z","iopub.execute_input":"2021-06-13T14:41:04.894591Z","iopub.status.idle":"2021-06-13T14:41:04.906463Z","shell.execute_reply.started":"2021-06-13T14:41:04.894558Z","shell.execute_reply":"2021-06-13T14:41:04.904483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Evaluation\n\nModelLoss, ModelAccuracy = model.evaluate(X_train, Y_train)\nprint('Model Loss is {}'.format(ModelLoss))\nprint('Model Accuracy is {}'.format(ModelAccuracy))","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:07.247567Z","iopub.execute_input":"2021-06-13T14:41:07.247887Z","iopub.status.idle":"2021-06-13T14:41:13.598695Z","shell.execute_reply.started":"2021-06-13T14:41:07.247856Z","shell.execute_reply":"2021-06-13T14:41:13.597887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Evaluation\n\nModelLoss, ModelAccuracy = model.evaluate(X_val, Y_val)\nprint('Model Loss is {}'.format(ModelLoss))\nprint('Model Accuracy is {}'.format(ModelAccuracy))","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:16.051858Z","iopub.execute_input":"2021-06-13T14:41:16.052202Z","iopub.status.idle":"2021-06-13T14:41:17.685882Z","shell.execute_reply.started":"2021-06-13T14:41:16.052169Z","shell.execute_reply":"2021-06-13T14:41:17.685211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_dir","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:19.462855Z","iopub.execute_input":"2021-06-13T14:41:19.463231Z","iopub.status.idle":"2021-06-13T14:41:19.471195Z","shell.execute_reply.started":"2021-06-13T14:41:19.463198Z","shell.execute_reply":"2021-06-13T14:41:19.469484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## define label\nroot = \"../input/my-trash-test-3/my trash test\"\n\n\n### get filenames and labels\nfilenames = []\nlabels = []\nt1 = time.time()\nfor dir_name in os.listdir(root):\n    img_dir_path = os.path.join(root,dir_name)\n    for file_name in os.listdir(img_dir_path):\n        img_file_path = os.path.join(img_dir_path,file_name)\n        label_num = class_dir[dir_name]\n        filenames.append(img_file_path)\n        labels.append(label_num)\n\n      \nimg_shape = 128\n## load image\nt3 = time.time()\nimg_list = []\nfor file_name in filenames:\n    img = tf.keras.preprocessing.image.load_img(file_name,target_size =(img_shape,img_shape))\n    img = np.array(img)\n    unit_ = img.reshape((1,img_shape,img_shape,3))\n    img_list.append(unit_)\n    print(\".\",end=\"\")\nt4 = time.time()\ntime_print(t3,t4)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:23.49705Z","iopub.execute_input":"2021-06-13T14:41:23.497376Z","iopub.status.idle":"2021-06-13T14:41:25.779587Z","shell.execute_reply.started":"2021-06-13T14:41:23.497344Z","shell.execute_reply":"2021-06-13T14:41:25.778716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_my_dataset = np.concatenate(img_list,axis=0)\nprint(x_my_dataset.shape)\ny_my_dataset = np.reshape(np.array(labels),(np.array(labels).shape[0],1))\nprint(y_my_dataset.shape)\n# Normalize the data.\nX_test =  x_my_dataset.astype('float32')/255.0\nY_test = y_my_dataset\n\nY_test = encoder.transform(Y_test.tolist()).toarray()","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:49.29173Z","iopub.execute_input":"2021-06-13T14:41:49.292075Z","iopub.status.idle":"2021-06-13T14:41:49.319592Z","shell.execute_reply.started":"2021-06-13T14:41:49.292041Z","shell.execute_reply":"2021-06-13T14:41:49.318865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(Y_test)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:41:52.206406Z","iopub.execute_input":"2021-06-13T14:41:52.206723Z","iopub.status.idle":"2021-06-13T14:41:52.216235Z","shell.execute_reply.started":"2021-06-13T14:41:52.206692Z","shell.execute_reply":"2021-06-13T14:41:52.215047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Evaluation\n\nModelLoss, ModelAccuracy = model.evaluate(X_test, Y_test)\nprint('Model Loss is {}'.format(ModelLoss))\nprint('Model Accuracy is {}'.format(ModelAccuracy))\n\nresult = model.predict(X_test)\nprint(result.shape)\nfor i in range(12):\n    print(str(i).zfill(2),end=\":\")\n    print(result[15,i])","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:45:59.577064Z","iopub.execute_input":"2021-06-13T14:45:59.577395Z","iopub.status.idle":"2021-06-13T14:45:59.768835Z","shell.execute_reply.started":"2021-06-13T14:45:59.577364Z","shell.execute_reply":"2021-06-13T14:45:59.768079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(X_test,Y_test,epochs=1000,validation_data=(X_test, Y_test))","metadata":{"execution":{"iopub.status.busy":"2021-06-13T05:25:01.0657Z","iopub.execute_input":"2021-06-13T05:25:01.066042Z","iopub.status.idle":"2021-06-13T05:27:51.310378Z","shell.execute_reply.started":"2021-06-13T05:25:01.066011Z","shell.execute_reply":"2021-06-13T05:27:51.3097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model.save(\"model\")\nimport keras\nmodel.save('model')\nmodel_test = keras.models.load_model(\"model\")\nprint(model_test.predict(X_train))","metadata":{"execution":{"iopub.status.busy":"2021-06-13T05:28:54.516342Z","iopub.execute_input":"2021-06-13T05:28:54.516883Z","iopub.status.idle":"2021-06-13T05:29:15.376634Z","shell.execute_reply.started":"2021-06-13T05:28:54.516839Z","shell.execute_reply":"2021-06-13T05:29:15.375856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a = open(\"test.txt\",\"w\")","metadata":{"execution":{"iopub.status.busy":"2021-06-13T05:29:49.810768Z","iopub.execute_input":"2021-06-13T05:29:49.811115Z","iopub.status.idle":"2021-06-13T05:29:49.815333Z","shell.execute_reply.started":"2021-06-13T05:29:49.811081Z","shell.execute_reply":"2021-06-13T05:29:49.814519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2021-06-13T05:29:45.681181Z","iopub.execute_input":"2021-06-13T05:29:45.681502Z","iopub.status.idle":"2021-06-13T05:29:46.40808Z","shell.execute_reply.started":"2021-06-13T05:29:45.681473Z","shell.execute_reply":"2021-06-13T05:29:46.406986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(Y_test)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T14:24:27.400481Z","iopub.execute_input":"2021-06-13T14:24:27.400836Z","iopub.status.idle":"2021-06-13T14:24:27.716211Z","shell.execute_reply.started":"2021-06-13T14:24:27.400803Z","shell.execute_reply":"2021-06-13T14:24:27.71503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"============================================================================\")\nprint(\"5/26\")","metadata":{"execution":{"iopub.status.busy":"2021-06-13T05:29:52.92925Z","iopub.execute_input":"2021-06-13T05:29:52.929604Z","iopub.status.idle":"2021-06-13T05:29:52.934746Z","shell.execute_reply.started":"2021-06-13T05:29:52.929575Z","shell.execute_reply":"2021-06-13T05:29:52.933593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## define label\nclass_dir = {}\nroot = \"../input/garbage-classification/garbage_classification\"\ni = 0.0\nfor dir_name in os.listdir(root):\n    class_dir[dir_name] = i\n    i = i + 1.0\nprint(class_dir)\n\n### get filenames and labels\nfilenames = []\nlabels = []\nt1 = time.time()\nfor dir_name in os.listdir(root):\n    img_dir_path = os.path.join(root,dir_name)\n    for file_name in os.listdir(img_dir_path):\n        img_file_path = os.path.join(img_dir_path,file_name)\n        label_num = class_dir[dir_name]\n        filenames.append(img_file_path)\n        labels.append(label_num)\n\n        \nimg_shape = 128\n## load image\nt3 = time.time()\nimg_list = []\nfor file_name in filenames:\n    img = tf.keras.preprocessing.image.load_img(file_name,target_size =(img_shape,img_shape))\n    img = np.array(img)\n    unit_ = img.reshape((1,img_shape,img_shape,3))\n    img_list.append(unit_)\n    print(\".\",end=\"\")\nt4=time.time()    \ntime_print(t3,t4)","metadata":{"execution":{"iopub.status.busy":"2021-05-30T09:02:41.43297Z","iopub.execute_input":"2021-05-30T09:02:41.433546Z","iopub.status.idle":"2021-05-30T09:04:07.818491Z","shell.execute_reply.started":"2021-05-30T09:02:41.433506Z","shell.execute_reply":"2021-05-30T09:04:07.81742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_dataset = np.concatenate(img_list,axis=0)\nprint(x_dataset.shape)\ny_dataset = np.reshape(np.array(labels),(np.array(labels).shape[0],1))\nprint(y_dataset.shape)","metadata":{"execution":{"iopub.status.busy":"2021-05-29T06:10:54.527575Z","iopub.execute_input":"2021-05-29T06:10:54.527955Z","iopub.status.idle":"2021-05-29T06:10:54.557766Z","shell.execute_reply.started":"2021-05-29T06:10:54.527917Z","shell.execute_reply":"2021-05-29T06:10:54.556644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Normalize the data.\nX_train = x_dataset.astype('float32')/255.0\nY_train = y_dataset","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:40:31.900848Z","iopub.execute_input":"2021-05-22T13:40:31.901273Z","iopub.status.idle":"2021-05-22T13:40:33.28136Z","shell.execute_reply.started":"2021-05-22T13:40:31.90124Z","shell.execute_reply":"2021-05-22T13:40:33.280172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size = 0.2,shuffle = True)","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:40:35.382749Z","iopub.execute_input":"2021-05-22T13:40:35.38318Z","iopub.status.idle":"2021-05-22T13:40:36.594825Z","shell.execute_reply.started":"2021-05-22T13:40:35.383146Z","shell.execute_reply":"2021-05-22T13:40:36.59363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import OneHotEncoder\nencoder = OneHotEncoder()\nencoder.fit(Y_train.tolist())\nY_train = encoder.transform(Y_train.tolist()).toarray()\nY_val =  encoder.transform(Y_val.tolist()).toarray()","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:40:38.216009Z","iopub.execute_input":"2021-05-22T13:40:38.216407Z","iopub.status.idle":"2021-05-22T13:40:38.254714Z","shell.execute_reply.started":"2021-05-22T13:40:38.216373Z","shell.execute_reply":"2021-05-22T13:40:38.253627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Y_train\",Y_train.shape)\nprint(\"Y_val\",Y_val.shape)","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:40:41.566623Z","iopub.execute_input":"2021-05-22T13:40:41.567022Z","iopub.status.idle":"2021-05-22T13:40:41.574371Z","shell.execute_reply.started":"2021-05-22T13:40:41.566989Z","shell.execute_reply":"2021-05-22T13:40:41.573159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nResNet-18\nReference:\n[1] K. He et al. Deep Residual Learning for Image Recognition. CVPR, 2016\n[2] K. He, X. Zhang, S. Ren, and J. Sun. Delving deep into rectifiers:\nSurpassing human-level performance on imagenet classification. In\nICCV, 2015.\n\"\"\"\n\n\nfrom keras.callbacks import EarlyStopping\nfrom keras.layers import Dense, Conv2D,  MaxPool2D, Flatten, GlobalAveragePooling2D,  BatchNormalization, Layer, Add\nfrom keras.models import Sequential\nfrom keras.models import Model\nimport tensorflow as tf\n\n\nclass ResnetBlock(Model):\n    \"\"\"\n    A standard resnet block.\n    \"\"\"\n\n    def __init__(self, channels: int, down_sample=False):\n        \"\"\"\n        channels: same as number of convolution kernels\n        \"\"\"\n        super().__init__()\n\n        self.__channels = channels\n        self.__down_sample = down_sample\n        self.__strides = [2, 1] if down_sample else [1, 1]\n\n        KERNEL_SIZE = (3, 3)\n        # use He initialization, instead of Xavier (a.k.a 'glorot_uniform' in Keras), as suggested in [2]\n        INIT_SCHEME = \"he_normal\"\n\n        self.conv_1 = Conv2D(self.__channels, strides=self.__strides[0],\n                             kernel_size=KERNEL_SIZE, padding=\"same\", kernel_initializer=INIT_SCHEME)\n        self.bn_1 = BatchNormalization()\n        self.conv_2 = Conv2D(self.__channels, strides=self.__strides[1],\n                             kernel_size=KERNEL_SIZE, padding=\"same\", kernel_initializer=INIT_SCHEME)\n        self.bn_2 = BatchNormalization()\n        self.merge = Add()\n\n        if self.__down_sample:\n            # perform down sampling using stride of 2, according to [1].\n            self.res_conv = Conv2D(\n                self.__channels, strides=2, kernel_size=(1, 1), kernel_initializer=INIT_SCHEME, padding=\"same\")\n            self.res_bn = BatchNormalization()\n\n    def call(self, inputs):\n        res = inputs\n\n        x = self.conv_1(inputs)\n        x = self.bn_1(x)\n        x = tf.nn.relu(x)\n        x = self.conv_2(x)\n        x = self.bn_2(x)\n\n        if self.__down_sample:\n            res = self.res_conv(res)\n            res = self.res_bn(res)\n\n        # if not perform down sample, then add a shortcut directly\n        x = self.merge([x, res])\n        out = tf.nn.relu(x)\n        return out\n\n\nclass ResNet18(Model):\n\n    def __init__(self, num_classes, **kwargs):\n        \"\"\"\n            num_classes: number of classes in specific classification task.\n        \"\"\"\n        super().__init__(**kwargs)\n        self.conv_1 = Conv2D(64, (7, 7), strides=2,\n                             padding=\"same\", kernel_initializer=\"he_normal\")\n        self.init_bn = BatchNormalization()\n        self.pool_2 = MaxPool2D(pool_size=(2, 2), strides=2, padding=\"same\")\n        self.res_1_1 = ResnetBlock(64)\n        self.res_1_2 = ResnetBlock(64)\n        self.res_2_1 = ResnetBlock(128, down_sample=True)\n        self.res_2_2 = ResnetBlock(128)\n        self.res_3_1 = ResnetBlock(256, down_sample=True)\n        self.res_3_2 = ResnetBlock(256)\n        self.res_4_1 = ResnetBlock(512, down_sample=True)\n        self.res_4_2 = ResnetBlock(512)\n        self.avg_pool = GlobalAveragePooling2D()\n        self.flat = Flatten()\n        self.fc = Dense(num_classes, activation=\"softmax\")\n\n    def call(self, inputs):\n        out = self.conv_1(inputs)\n        out = self.init_bn(out)\n        out = tf.nn.relu(out)\n        out = self.pool_2(out)\n        for res_block in [self.res_1_1, self.res_1_2, self.res_2_1, self.res_2_2, self.res_3_1, self.res_3_2, self.res_4_1, self.res_4_2]:\n            out = res_block(out)\n        out = self.avg_pool(out)\n        out = self.flat(out)\n        out = self.fc(out)\n        return out","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:40:44.328353Z","iopub.execute_input":"2021-05-22T13:40:44.328708Z","iopub.status.idle":"2021-05-22T13:40:44.360396Z","shell.execute_reply.started":"2021-05-22T13:40:44.328675Z","shell.execute_reply":"2021-05-22T13:40:44.359403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = ResNet18(12)\nmodel.build(input_shape = (None,img_shape,img_shape,3))\n#use categorical_crossentropy since the label is one-hot encoded\nfrom keras.optimizers import SGD\n# opt = SGD(learning_rate=0.1,momentum=0.9,decay = 1e-04) #parameters suggested by He [1]\nmodel.compile(optimizer = \"adam\",loss='categorical_crossentropy', metrics=[\"accuracy\"]) \nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:40:47.725288Z","iopub.execute_input":"2021-05-22T13:40:47.725666Z","iopub.status.idle":"2021-05-22T13:40:50.819275Z","shell.execute_reply.started":"2021-05-22T13:40:47.725633Z","shell.execute_reply":"2021-05-22T13:40:50.818102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_train.shape)\nprint(Y_train.shape)\nhistory = model.fit(X_train,Y_train,epochs=100validation_data=(X_val, Y_val))","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:42:08.408493Z","iopub.execute_input":"2021-05-22T13:42:08.408961Z","iopub.status.idle":"2021-05-22T13:44:27.024547Z","shell.execute_reply.started":"2021-05-22T13:42:08.408907Z","shell.execute_reply":"2021-05-22T13:44:27.022807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plotmodelhistory(history): \n    fig, axs = plt.subplots(1,2,figsize=(15,5)) \n    # summarize history for accuracy\n    axs[0].plot(history.history['accuracy']) \n    axs[0].plot(history.history['val_accuracy']) \n    axs[0].set_title('Model Accuracy')\n    axs[0].set_ylabel('Accuracy') \n    axs[0].set_xlabel('Epoch')\n    \n    axs[0].legend(['train', 'validate'], loc='upper left')\n    # summarize history for loss\n    axs[1].plot(history.history['loss']) \n    axs[1].plot(history.history['val_loss']) \n    axs[1].set_title('Model Loss')\n    axs[1].set_ylabel('Loss') \n    axs[1].set_xlabel('Epoch')\n    axs[1].legend(['train', 'validate'], loc='upper left')\n    plt.show()\n\n# list all data in history\n#print(history.history.keys())\nplotmodelhistory(history)\nprint(history.history)\n\nprint(type(history.history))","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:44:39.304708Z","iopub.execute_input":"2021-05-22T13:44:39.305193Z","iopub.status.idle":"2021-05-22T13:44:39.999373Z","shell.execute_reply.started":"2021-05-22T13:44:39.30516Z","shell.execute_reply":"2021-05-22T13:44:39.998024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\ndictionary_data = history.history\na_file = open(\"data.json\", \"w\")\njson. dump(dictionary_data, a_file)\na_file. close()\na_file = open(\"data.json\", \"r\")\noutput = a_file. read()\nprint(output)","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:45:18.809172Z","iopub.execute_input":"2021-05-22T13:45:18.80961Z","iopub.status.idle":"2021-05-22T13:45:18.818363Z","shell.execute_reply.started":"2021-05-22T13:45:18.809577Z","shell.execute_reply":"2021-05-22T13:45:18.817127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluation\n\nModelLoss, ModelAccuracy = model.evaluate(X_train, Y_train)\nprint('Model Loss is {}'.format(ModelLoss))\nprint('Model Accuracy is {}'.format(ModelAccuracy))","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:48:50.107338Z","iopub.execute_input":"2021-05-22T13:48:50.107715Z","iopub.status.idle":"2021-05-22T13:48:57.390376Z","shell.execute_reply.started":"2021-05-22T13:48:50.107682Z","shell.execute_reply":"2021-05-22T13:48:57.38862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(model.predict(X_train[3:5,:,:,:]))","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:49:50.320352Z","iopub.execute_input":"2021-05-22T13:49:50.320729Z","iopub.status.idle":"2021-05-22T13:49:50.96793Z","shell.execute_reply.started":"2021-05-22T13:49:50.320695Z","shell.execute_reply":"2021-05-22T13:49:50.965263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model.save(\"model\")\nimport keras\nmodel.save('model')\nmodel_test = keras.models.load_model(\"model\")\nprint(model_test.predict(X_train))","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:50:07.581469Z","iopub.execute_input":"2021-05-22T13:50:07.581951Z","iopub.status.idle":"2021-05-22T13:50:34.901534Z","shell.execute_reply.started":"2021-05-22T13:50:07.581914Z","shell.execute_reply":"2021-05-22T13:50:34.898622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a = open(\"test.txt\",\"w\")","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:51:21.173209Z","iopub.execute_input":"2021-05-22T13:51:21.173629Z","iopub.status.idle":"2021-05-22T13:51:21.179567Z","shell.execute_reply.started":"2021-05-22T13:51:21.173595Z","shell.execute_reply":"2021-05-22T13:51:21.178335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2021-05-22T13:51:24.220073Z","iopub.execute_input":"2021-05-22T13:51:24.220472Z","iopub.status.idle":"2021-05-22T13:51:25.182434Z","shell.execute_reply.started":"2021-05-22T13:51:24.22043Z","shell.execute_reply":"2021-05-22T13:51:25.180824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sub = pd.read_csv(\"../input/cifar-10/trainLabels.csv\")\n\n# Y_pred = np.argmax(model.predict(X_test),axis = 1) \n# #convert to string label\n# labels = ['Airplane', 'Automobile', 'Bird', 'Cat', 'Deer', 'Dog', 'Frog', 'Horse', 'Ship', 'Truck']\n# str_pred = [labels[i] for i in Y_pred]\n# sub[\"label\"] = pd.DataFrame(str_pred)","metadata":{"execution":{"iopub.status.busy":"2021-05-21T11:07:36.694233Z","iopub.execute_input":"2021-05-21T11:07:36.694661Z","iopub.status.idle":"2021-05-21T11:07:36.700005Z","shell.execute_reply.started":"2021-05-21T11:07:36.694622Z","shell.execute_reply":"2021-05-21T11:07:36.698942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('========================================================')","metadata":{"execution":{"iopub.status.busy":"2021-05-21T04:18:37.176045Z","iopub.execute_input":"2021-05-21T04:18:37.176424Z","iopub.status.idle":"2021-05-21T04:18:37.181558Z","shell.execute_reply.started":"2021-05-21T04:18:37.176391Z","shell.execute_reply":"2021-05-21T04:18:37.180605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(type(X_train))\nprint(X_train.shape)\nprint(Y_train)","metadata":{"execution":{"iopub.status.busy":"2021-05-21T01:55:20.576408Z","iopub.execute_input":"2021-05-21T01:55:20.576773Z","iopub.status.idle":"2021-05-21T01:55:20.583689Z","shell.execute_reply.started":"2021-05-21T01:55:20.576736Z","shell.execute_reply":"2021-05-21T01:55:20.582346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Drawing sample . \nplt.imshow(X_train[65])","metadata":{"execution":{"iopub.status.busy":"2021-05-21T11:07:40.526232Z","iopub.execute_input":"2021-05-21T11:07:40.526611Z","iopub.status.idle":"2021-05-21T11:07:40.674903Z","shell.execute_reply.started":"2021-05-21T11:07:40.526578Z","shell.execute_reply":"2021-05-21T11:07:40.673857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Normalize the data.\nX_train = X_train.astype('float32')\nX_test = X_test.astype('float32')\nX_train /= 255.0\nX_test /= 255.0","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size = 0.2,shuffle = True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import OneHotEncoder\nencoder = OneHotEncoder()\nencoder.fit(Y_train.tolist())\nY_train = encoder.transform(Y_train.tolist()).toarray()\nY_test = encoder.transform(Y_test.tolist()).toarray()\nY_val =  encoder.transform(Y_val.tolist()).toarray()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(Y_test.shape)\nprint(type(Y_test))\nprint(Y_test)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## data augmentation","metadata":{}},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\naug = ImageDataGenerator(horizontal_flip=True, width_shift_range=0.05,\n                             height_shift_range=0.05)\naug.fit(X_train)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Implement ResNet-18 model","metadata":{}},{"cell_type":"markdown","source":"Codes below are taken from my [Github](https://github.com/songrise/CNN_Keras)","metadata":{}},{"cell_type":"code","source":"\"\"\"\nResNet-18\nReference:\n[1] K. He et al. Deep Residual Learning for Image Recognition. CVPR, 2016\n[2] K. He, X. Zhang, S. Ren, and J. Sun. Delving deep into rectifiers:\nSurpassing human-level performance on imagenet classification. In\nICCV, 2015.\n\"\"\"\n\n\nfrom keras.callbacks import EarlyStopping\nfrom keras.layers import Dense, Conv2D,  MaxPool2D, Flatten, GlobalAveragePooling2D,  BatchNormalization, Layer, Add\nfrom keras.models import Sequential\nfrom keras.models import Model\nimport tensorflow as tf\n\n\nclass ResnetBlock(Model):\n    \"\"\"\n    A standard resnet block.\n    \"\"\"\n\n    def __init__(self, channels: int, down_sample=False):\n        \"\"\"\n        channels: same as number of convolution kernels\n        \"\"\"\n        super().__init__()\n\n        self.__channels = channels\n        self.__down_sample = down_sample\n        self.__strides = [2, 1] if down_sample else [1, 1]\n\n        KERNEL_SIZE = (3, 3)\n        # use He initialization, instead of Xavier (a.k.a 'glorot_uniform' in Keras), as suggested in [2]\n        INIT_SCHEME = \"he_normal\"\n\n        self.conv_1 = Conv2D(self.__channels, strides=self.__strides[0],\n                             kernel_size=KERNEL_SIZE, padding=\"same\", kernel_initializer=INIT_SCHEME)\n        self.bn_1 = BatchNormalization()\n        self.conv_2 = Conv2D(self.__channels, strides=self.__strides[1],\n                             kernel_size=KERNEL_SIZE, padding=\"same\", kernel_initializer=INIT_SCHEME)\n        self.bn_2 = BatchNormalization()\n        self.merge = Add()\n\n        if self.__down_sample:\n            # perform down sampling using stride of 2, according to [1].\n            self.res_conv = Conv2D(\n                self.__channels, strides=2, kernel_size=(1, 1), kernel_initializer=INIT_SCHEME, padding=\"same\")\n            self.res_bn = BatchNormalization()\n\n    def call(self, inputs):\n        res = inputs\n\n        x = self.conv_1(inputs)\n        x = self.bn_1(x)\n        x = tf.nn.relu(x)\n        x = self.conv_2(x)\n        x = self.bn_2(x)\n\n        if self.__down_sample:\n            res = self.res_conv(res)\n            res = self.res_bn(res)\n\n        # if not perform down sample, then add a shortcut directly\n        x = self.merge([x, res])\n        out = tf.nn.relu(x)\n        return out\n\n\nclass ResNet18(Model):\n\n    def __init__(self, num_classes, **kwargs):\n        \"\"\"\n            num_classes: number of classes in specific classification task.\n        \"\"\"\n        super().__init__(**kwargs)\n        self.conv_1 = Conv2D(64, (7, 7), strides=2,\n                             padding=\"same\", kernel_initializer=\"he_normal\")\n        self.init_bn = BatchNormalization()\n        self.pool_2 = MaxPool2D(pool_size=(2, 2), strides=2, padding=\"same\")\n        self.res_1_1 = ResnetBlock(64)\n        self.res_1_2 = ResnetBlock(64)\n        self.res_2_1 = ResnetBlock(128, down_sample=True)\n        self.res_2_2 = ResnetBlock(128)\n        self.res_3_1 = ResnetBlock(256, down_sample=True)\n        self.res_3_2 = ResnetBlock(256)\n        self.res_4_1 = ResnetBlock(512, down_sample=True)\n        self.res_4_2 = ResnetBlock(512)\n        self.avg_pool = GlobalAveragePooling2D()\n        self.flat = Flatten()\n        self.fc = Dense(num_classes, activation=\"softmax\")\n\n    def call(self, inputs):\n        out = self.conv_1(inputs)\n        out = self.init_bn(out)\n        out = tf.nn.relu(out)\n        out = self.pool_2(out)\n        for res_block in [self.res_1_1, self.res_1_2, self.res_2_1, self.res_2_2, self.res_3_1, self.res_3_2, self.res_4_1, self.res_4_2]:\n            out = res_block(out)\n        out = self.avg_pool(out)\n        out = self.flat(out)\n        out = self.fc(out)\n        return out\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = ResNet18(12)\nmodel.build(input_shape = (None,32,32,3))\n#use categorical_crossentropy since the label is one-hot encoded\nfrom keras.optimizers import SGD\n# opt = SGD(learning_rate=0.1,momentum=0.9,decay = 1e-04) #parameters suggested by He [1]\nmodel.compile(optimizer = \"adam\",loss='categorical_crossentropy', metrics=[\"accuracy\"]) \nmodel.summary()\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping\n\nes = EarlyStopping(patience= 8, restore_best_weights=True, monitor=\"val_acc\")\n#I did not use crosSSs validation, so the validate performance is not accurate.\nSTEPS = len(X_train) / 256\n#history = model.fit(aug.flow(X_train,Y_train,batch_size = 256), steps_per_epoch=STEPS, batch_size = 256, epochs=50, validation_data=(X_train, Y_train),callbacks=[es])\nhistory = model.fit(X_train,Y_train,epochs=100,validation_data=(X_val, Y_val))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## train curve","metadata":{}},{"cell_type":"code","source":"\n\ndef plotmodelhistory(history): \n    fig, axs = plt.subplots(1,2,figsize=(15,5)) \n    # summarize history for accuracy\n    axs[0].plot(history.history['accuracy']) \n    axs[0].plot(history.history['val_accuracy']) \n    axs[0].set_title('Model Accuracy')\n    axs[0].set_ylabel('Accuracy') \n    axs[0].set_xlabel('Epoch')\n    \n    axs[0].legend(['train', 'validate'], loc='upper left')\n    # summarize history for loss\n    axs[1].plot(history.history['loss']) \n    axs[1].plot(history.history['val_loss']) \n    axs[1].set_title('Model Loss')\n    axs[1].set_ylabel('Loss') \n    axs[1].set_xlabel('Epoch')\n    axs[1].legend(['train', 'validate'], loc='upper left')\n    plt.show()\n\n# list all data in history\n#print(history.history.keys())\n#plotmodelhistory(history)\nprint(history.history)\n\nprint(type(history.history))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\ndictionary_data = history.history\na_file = open(\"data.json\", \"w\")\njson. dump(dictionary_data, a_file)\na_file. close()\na_file = open(\"data.json\", \"r\")\noutput = a_file. read()\nprint(output)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##  Prediction","metadata":{}},{"cell_type":"code","source":"## Evaluation\n\nModelLoss, ModelAccuracy = model.evaluate(X_train, Y_train)\n\nprint('Model Loss is {}'.format(ModelLoss))\nprint('Model Accuracy is {}'.format(ModelAccuracy))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(model.predict(X_train[3:5,:,:,:]))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"model\")\nmodel_test = keras.models.load_model(\"model\")\nprint(model_test.predict(X_train))","metadata":{"execution":{"iopub.status.busy":"2021-05-21T03:43:32.263516Z","iopub.execute_input":"2021-05-21T03:43:32.263827Z","iopub.status.idle":"2021-05-21T03:43:32.293466Z","shell.execute_reply.started":"2021-05-21T03:43:32.263797Z","shell.execute_reply":"2021-05-21T03:43:32.292199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nshutil.make_archive(\"./model.zip\", 'zip', \"./model\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ModelLoss, ModelAccuracy = model_test.evaluate(X_train, Y_train)\n\nprint('Model Loss is {}'.format(ModelLoss))\nprint('Model Accuracy is {}'.format(ModelAccuracy))\n\nModelLoss, ModelAccuracy =model_test.evaluate(X_val, Y_val)\n\nprint('Model Loss is {}'.format(ModelLoss))\nprint('Model Accuracy is {}'.format(ModelAccuracy))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_val)\nprint(Y_val)\nprint(model_test.predict(X_val))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## load model\nimport tensorflow as tf\nimport keras\n#model = tf.saved_model.load(\"../input/test-model-data\")\nmodel_test = keras.models.load_model(\"../input/model-test-1\")\nprint(\"OK\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(model_test.predict(X_train))\nprint(\"===========================\")\nprint(Y_train)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sub = pd.read_csv(\"../input/cifar-10/trainLabels.csv\")\n\n# Y_pred = np.argmax(model.predict(X_test),axis = 1) \n# #convert to string label\n# labels = ['Airplane', 'Automobile', 'Bird', 'Cat', 'Deer', 'Dog', 'Frog', 'Horse', 'Ship', 'Truck']\n# str_pred = [labels[i] for i in Y_pred]\n# sub[\"label\"] = pd.DataFrame(str_pred)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}