{"cells":[{"metadata":{"id":"vXUed3x_ROCm"},"cell_type":"markdown","source":"# Import Libraries"},{"metadata":{"id":"3iIKvXgjjCn-"},"cell_type":"markdown","source":"\n## Install TensorFlow 2\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install tensorflow-gpu -q","execution_count":null,"outputs":[]},{"metadata":{"id":"NOPPPUZXi5EX","outputId":"910e46e1-0c69-4484-ad12-f3a7dd719b59","trusted":true},"cell_type":"code","source":"import tensorflow as tf\ntf.__version__","execution_count":null,"outputs":[]},{"metadata":{"id":"QCtpZMqgVevt"},"cell_type":"markdown","source":"\n## Import other libraries\n"},{"metadata":{"id":"JLQflrey92oM","trusted":true},"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport cv2 as cv\n\nnp.set_printoptions(precision=7)\n%matplotlib inline\n\nimport tensorflow_datasets as tfds\n\nfrom tensorflow.keras import Model\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nfrom collections import Counter\nfrom tensorflow.keras.utils import to_categorical, plot_model\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.preprocessing import image\n\nfrom PIL import Image","execution_count":null,"outputs":[]},{"metadata":{"id":"WudbjGbRKtkm"},"cell_type":"markdown","source":"## Create Directory for Dataset"},{"metadata":{"id":"Cse5dJMVKhtC","trusted":true},"cell_type":"code","source":"import os\nimport errno\n\n\ntry:\n    data_dir = 'dataset'\n    os.mkdir(data_dir)\nexcept OSError as e:\n    if e.errno == errno.EEXIST:\n        print('Directory  created.')\n    else:\n        raise","execution_count":null,"outputs":[]},{"metadata":{"id":"zmQ7qknjMxn3"},"cell_type":"markdown","source":"---\n# TFDS Datasets\n"},{"metadata":{"id":"2dZdD1gGK2Oe"},"cell_type":"markdown","source":"## Choose Dataset Cifar10"},{"metadata":{"id":"ij2opdRk-ewl","trusted":true},"cell_type":"code","source":"dataset_name = \"cifar10\"\n","execution_count":null,"outputs":[]},{"metadata":{"id":"QfO4wRKVJLmA"},"cell_type":"markdown","source":"\n## Download Dataset\n"},{"metadata":{"id":"OxUXKmEY-Ol_","trusted":true},"cell_type":"code","source":"(train_set, test_set), dataset_info =  tfds.load( \n              name=dataset_name, \n              split=[\"train\", \"test\"], \n              with_info=True, \n              data_dir=data_dir\n          )","execution_count":null,"outputs":[]},{"metadata":{"id":"TQ3bpnBXLINW"},"cell_type":"markdown","source":"## Dataset Information"},{"metadata":{"id":"36i05Arn-OjO","outputId":"e33ca675-c795-47a3-bd1a-67a6a690d1fb","trusted":true},"cell_type":"code","source":"print(dataset_info)","execution_count":null,"outputs":[]},{"metadata":{"id":"708VwPzwM_HP"},"cell_type":"markdown","source":"### Detailed Information"},{"metadata":{"id":"lnLcUXJ4LNm4","outputId":"538e6852-95ef-4efc-a563-3cbc1789acf7","trusted":true},"cell_type":"code","source":"class_names =  dataset_info.features[\"label\"].names\n\nprint('image shape    :', dataset_info.features['image'].shape)\nprint('image dtype    :', dataset_info.features['image'].dtype)\nprint()\nprint('num class      : ',dataset_info.features[\"label\"].num_classes)\nprint('class label    :', dataset_info.features[\"label\"].names)\nprint()\nprint('num train data :', dataset_info.splits[\"train\"].num_examples)\nprint('num test data  :', dataset_info.splits[\"test\"].num_examples)","execution_count":null,"outputs":[]},{"metadata":{"id":"MPNr62rbMEQg"},"cell_type":"markdown","source":"## Show Images"},{"metadata":{"id":"DQ26eh1bK4FL","outputId":"3ccfe12c-6805-48ae-be44-9fad6e1c4e08","trusted":true},"cell_type":"code","source":"fig = tfds.show_examples(train_set, dataset_info)","execution_count":null,"outputs":[]},{"metadata":{"id":"-g-uvLzaOFex"},"cell_type":"markdown","source":"# Preprocess Image\n\nConvert and Resize Dataset to Numpy"},{"metadata":{"id":"6CtwzB8aOJ1o","trusted":true},"cell_type":"code","source":"input_shape = (80, 80, 3)","execution_count":null,"outputs":[]},{"metadata":{"id":"OvpUB5orPMxG"},"cell_type":"markdown","source":"### Convert Data Train"},{"metadata":{"id":"R4oDsNX3DvgI","trusted":true},"cell_type":"code","source":"X_train = []\ny_train = []\n\nfor example in tfds.as_numpy(train_set):\n    new_img = example['image']\n    new_img = cv.resize(new_img, input_shape[:2],interpolation = cv.INTER_AREA) \n    X_train.append(new_img)\n    y_train.append(example['label'])\n\ndel train_set","execution_count":null,"outputs":[]},{"metadata":{"id":"k7otV0KuO1ai","outputId":"be2d3f8f-1404-4b88-b37b-308eabc40275","trusted":true},"cell_type":"code","source":"X_train = np.asarray(X_train)\ny_train = np.asarray(y_train)\n\nprint('X_train.shape =',X_train.shape)\nprint('y_train.shape =',y_train.shape)","execution_count":null,"outputs":[]},{"metadata":{"id":"iBom4ufgPKpw"},"cell_type":"markdown","source":"### Convert Data Test"},{"metadata":{"id":"Wa7NxpiIO9oA","trusted":true},"cell_type":"code","source":"X_test = []\ny_test = []\n\nfor example in tfds.as_numpy(test_set):\n    new_img = example['image']\n    new_img = cv.resize(new_img, input_shape[:2],interpolation = cv.INTER_AREA) \n    X_test.append(new_img)\n    y_test.append(example['label'])\n\ndel test_set","execution_count":null,"outputs":[]},{"metadata":{"id":"q9yUF0PnO9oG","outputId":"898dde67-c09b-481a-aadd-4c264fe4fb40","trusted":true},"cell_type":"code","source":"X_test = np.asarray(X_test)\ny_test = np.asarray(y_test)\n\nprint('X_test.shape =',X_test.shape)\nprint('y_test.shape =',y_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"id":"VhXsSGsff8DF"},"cell_type":"markdown","source":"## Split Data Train into Train and Val"},{"metadata":{"id":"OX8aYbPTPU7I","trusted":true},"cell_type":"code","source":"X_val   = X_train[-300:]\ny_val   = y_train[-300:]\n\nX_train = X_train[:-300]\ny_train = y_train[:-300]","execution_count":null,"outputs":[]},{"metadata":{"id":"gXp-9MiACjKC","outputId":"57234601-6f5d-4524-9061-8ffc72f0bd43","trusted":true},"cell_type":"code","source":"print('X_train.shape =',X_train.shape)\nprint('y_train.shape =',y_train.shape)\n\nprint('\\nX_val.shape  =',X_val.shape)\nprint('y_val.shape  =',y_val.shape)\n\nprint('\\nX_test.shape  =',X_test.shape)\nprint('y_test.shape  =',y_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"id":"uCth0VqQgKrv"},"cell_type":"markdown","source":"# One hot y labels"},{"metadata":{"id":"k_YwRi7LcQ-Z","outputId":"167586fa-e08a-4e91-db30-3c97d98b9e48","trusted":true},"cell_type":"code","source":"y_train_hot = to_categorical(y_train, 102)\ny_val_hot   = to_categorical(y_val, 102)\ny_test_hot  = to_categorical(y_test, 102)\n\nprint('y_train_hot.shape =',y_train_hot.shape)\nprint('y_val_hot.shape   =',y_val_hot.shape)\nprint('y_test_hot.shape  =',y_test_hot.shape)","execution_count":null,"outputs":[]},{"metadata":{"id":"pAQ6ToaNIPkp"},"cell_type":"markdown","source":"---\n# Classification Model"},{"metadata":{"id":"7iCiF6K_exEJ"},"cell_type":"markdown","source":"## Create Model\n\n Using inception-resnet-v2"},{"metadata":{"id":"b4qO7Yy8Ydi6","trusted":true},"cell_type":"code","source":"model = tf.keras.applications.inception_resnet_v2.InceptionResNetV2(weights='imagenet', include_top=False, input_shape=(80, 80, 3))","execution_count":null,"outputs":[]},{"metadata":{"id":"pt9KtIlvYdiy","trusted":true},"cell_type":"code","source":"x = model.layers[-1].output\nx = GlobalAveragePooling2D() (x)\npredictions = Dense(102, activation='softmax') (x)\n\nmyModel = Model(inputs=model.input, outputs=predictions)","execution_count":null,"outputs":[]},{"metadata":{"id":"mXIVniKSVMk6"},"cell_type":"markdown","source":"## Visualize Model"},{"metadata":{"id":"I857GpI0VKBl","outputId":"d2d6a89f-b5ad-41a4-cee2-ce838785230d","trusted":true},"cell_type":"code","source":"myModel.summary()","execution_count":null,"outputs":[]},{"metadata":{"id":"L0PLc3WWQHRz","outputId":"fec67675-a99e-43f8-f3d1-9635b98d77df","trusted":true},"cell_type":"code","source":"plot_model(model, show_shapes=True,\n    show_layer_names=False,\n    rankdir='LR',\n    expand_nested=False,\n    dpi=60\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"Ts7C2Q6-eqkc"},"cell_type":"markdown","source":"## Compile Model\n\n"},{"metadata":{"id":"3T0kqQFSYdiv","trusted":true},"cell_type":"code","source":"myModel.compile(\n      loss='categorical_crossentropy',\n      optimizer=tf.keras.optimizers.Adam(), \n      metrics=['accuracy']\n  )","execution_count":null,"outputs":[]},{"metadata":{"id":"vuSAtshgIcDZ"},"cell_type":"markdown","source":"---\n# Data Augmentation"},{"metadata":{"id":"sTO9Y0cBciBq","trusted":true},"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(\n    rotation_range=15,\n    width_shift_range=0.1,\n    height_shift_range=0.1,\n    shear_range=0.1,\n    zoom_range=0.1,\n    channel_shift_range=0.1,\n    horizontal_flip=True\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"lIeAVaflemPn"},"cell_type":"markdown","source":"#  Callbacks\n* Checkpoint\n* Learning Rate Annealing"},{"metadata":{"id":"rg1BjBlUUk8D","trusted":true},"cell_type":"code","source":"from tensorflow.keras.callbacks import ModelCheckpoint, LearningRateScheduler\n\ndef lr_schedule(epoch):\n    lr = 1e-3\n    if (epoch > 30):\n        lr *= 0.01\n    elif (epoch > 20):\n        lr *= 0.1\n    return lr\n\nlr_callback = LearningRateScheduler(lr_schedule)\n\nmyCheckpoint = ModelCheckpoint(filepath='./dataset/my_model.h5', \n                               monitor='val_accuracy',\n                               save_best_only=True,\n                              )","execution_count":null,"outputs":[]},{"metadata":{"id":"Zzd6TLORJN4V"},"cell_type":"markdown","source":"# Train the Model"},{"metadata":{"id":"AHQGTDNKGaPD","trusted":true},"cell_type":"code","source":"history_all = []","execution_count":null,"outputs":[]},{"metadata":{"id":"_WOpRsOvcuTu","trusted":true},"cell_type":"code","source":"batch_size = 64\nepochs = 12","execution_count":null,"outputs":[]},{"metadata":{"id":"thhXcVAhcjpS","outputId":"09be8ee9-fa66-40df-e858-dad1d40aaef5","trusted":true},"cell_type":"code","source":"augmented_train = datagen.flow(\n    X_train, y_train_hot, batch_size\n)\n\nhistory = myModel.fit(\n    augmented_train,\n    validation_data=(X_val, y_val_hot),\n    epochs=epochs, \n    steps_per_epoch=len(X_train)/64,\n    callbacks=[lr_callback, myCheckpoint],\n    verbose=2)\n\nhistory_all.append(history)","execution_count":null,"outputs":[]},{"metadata":{"id":"bxcRw7jjeZyQ"},"cell_type":"markdown","source":"## Plot Current History Training"},{"metadata":{"id":"UggWSFRVcjmh","outputId":"40c03558-68ed-4188-f819-0d5d4341cea3","trusted":true},"cell_type":"code","source":"plt.rcParams['figure.figsize'] = [7, 5]\n\nplt.plot(history.history['accuracy'], label='train')\nplt.plot(history.history['val_accuracy'], label='val')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\n","execution_count":null,"outputs":[]},{"metadata":{"id":"ZMkyAKpsG524"},"cell_type":"markdown","source":"## Plot All History Training"},{"metadata":{"id":"ZPHNIgmCG9NR","trusted":true},"cell_type":"code","source":"hist_train = []\nhist_val = []\n\nfor h in history_all:\n    hist_train.append(h.history['accuracy'][1:])\n    hist_val.append(h.history['val_accuracy'][1:])","execution_count":null,"outputs":[]},{"metadata":{"id":"SJSKCoxZIufX","trusted":true},"cell_type":"code","source":"hist_train = np.array(hist_train).reshape(-1)\nhist_val = np.array(hist_val).reshape(-1)","execution_count":null,"outputs":[]},{"metadata":{"id":"eY6zx3SwG527","outputId":"be1d662a-84c6-428a-ff1e-c2c7e1e07937","trusted":true},"cell_type":"code","source":"plt.rcParams['figure.figsize'] = [7, 5] \n\nplt.plot(hist_train, label='train')\nplt.plot(hist_val, label='val')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\n","execution_count":null,"outputs":[]},{"metadata":{"id":"XmrH2R-6eXXJ"},"cell_type":"markdown","source":"# Evaluate Model\n"},{"metadata":{"id":"qqlxMhbiczyi","outputId":"6988c1c8-bf8a-40b8-c5bb-1f49d9c3563b","trusted":true},"cell_type":"code","source":"myModel.load_weights('./dataset/my_model.h5')\nscores = myModel.evaluate(X_test, y_test_hot)","execution_count":null,"outputs":[]},{"metadata":{"id":"vruBMuSHc1oI","outputId":"6a87f5f8-a543-4cbc-f47f-faf9d8cf09ce","trusted":true},"cell_type":"code","source":"print('Test loss    :', scores[0])\nprint('Test accuracy: %.2f%%' % (scores[1]*100))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Re-Evaluate Model\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_scores = myModel.evaluate(X_train, y_train_hot)\ntest_scores  = myModel.evaluate(X_test, y_test_hot)\nval_scores   = myModel.evaluate(X_val, y_val_hot)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Train Loss: %.5f with Accuracy: %.1f%%' % (train_scores[0], (train_scores[1]*100)))\nprint('Test  Loss: %.5f with Accuracy: %.1f%%' % (test_scores[0], (test_scores[1]*100)))\nprint('Val   Loss: %.5f with Accuracy: %.1f%%' % (val_scores[0], (val_scores[1]*100)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"---\n# Test the image from the internet \n"},{"metadata":{"trusted":true},"cell_type":"code","source":"!wget -O 'data_test_0.jpg' 'https://scx1.b-cdn.net/csz/news/800/2018/2-dog.jpg' \n!wget -O 'data_test_1.jpg' 'https://static.toiimg.com/thumb/msid-67586673,width-800,height-600,resizemode-75,imgsize-3918697,pt-32,y_pad-40/67586673.jpg'\n!wget -O 'data_test_2.jpg' 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Green_tree_frog.jpg/799px-Green_tree_frog.jpg'\n!wget -O 'data_test_3.jpg' 'https://bsmedia.business-standard.com/_media/bs/img/article/2019-10/15/full/1571086349-8577.jpg'\n!wget -O 'data_test_4.jpg' 'https://www.om.org/img/h55955_42-62.jpg'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(5):\n  new_img = Image.open('data_test_'+str(i)+'.jpg')\n  new_img = np.array(new_img)\n  new_img2 = cv.resize(new_img, input_shape[:2], interpolation=cv.INTER_AREA)\n  plt.imshow(new_img2)\n  plt.axis('off')\n  plt.show()\n\n  new_img2 = np.expand_dims(new_img2,0).astype(np.float64)\n  pred = myModel.predict(new_img2)\n  class_id = np.argmax(pred)\n  print('predicted id',class_id)\n  print('class prediction', class_names[class_id])","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}