{"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":"# CNN 101 for Image Classifications","metadata":{}},{"cell_type":"markdown","source":"## Basic Concepts\n\n### - Padding (Reduce 'Edge Effect')\n![](https://images.deepai.org/django-summernote/2019-05-27/c3f24854-5584-4feb-81d7-3bcc5800a689.png)\n### - Depth\n![](https://i.stack.imgur.com/XBWc3.png)\n### - Pooling (Reduce the Data Size)\n![](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ8aVgrPlLe87daYz-T-UWTOvRKBscJDpJoCQ&usqp=CAU)","metadata":{}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport tensorflow as tf\nfrom keras.datasets import cifar10\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Activation, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D\nimport matplotlib.pyplot as plt\n","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:18:40.587961Z","iopub.execute_input":"2022-07-19T05:18:40.588637Z","iopub.status.idle":"2022-07-19T05:18:46.737041Z","shell.execute_reply.started":"2022-07-19T05:18:40.588202Z","shell.execute_reply":"2022-07-19T05:18:46.736064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Read Train Test Data","metadata":{}},{"cell_type":"code","source":"# The data, shuffled and split between train and test sets:\n(x_train, y_train), (x_test, y_test) = cifar10.load_data()\nprint('x_train shape:', x_train.shape)\nprint(x_train.shape[0], 'train samples')\nprint(x_test.shape[0], 'test samples')\nnum_classes=len(np.unique(y_train))\nprint(f'num of classes = {num_classes}')","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:24:34.343585Z","iopub.execute_input":"2022-07-19T05:24:34.344288Z","iopub.status.idle":"2022-07-19T05:24:35.134537Z","shell.execute_reply.started":"2022-07-19T05:24:34.344252Z","shell.execute_reply":"2022-07-19T05:24:35.133546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Let's look at one of the images\nprint(y_train[999])\nplt.imshow(x_train[999]);","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:24:45.214415Z","iopub.execute_input":"2022-07-19T05:24:45.214772Z","iopub.status.idle":"2022-07-19T05:24:45.385465Z","shell.execute_reply.started":"2022-07-19T05:24:45.214743Z","shell.execute_reply":"2022-07-19T05:24:45.384521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Converts a class vector (integers) to binary class matrix.\ndef y_cate_encode(y_train,y_test):\n    print(y_train.shape)\n    y_train = tf.keras.utils.to_categorical(y_train, num_classes)\n    y_test = tf.keras.utils.to_categorical(y_test, num_classes)\n    print(y_train.shape)\n    return y_train, y_test\n\ny_train, y_test = y_cate_encode(y_train,y_test)","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:24:45.498276Z","iopub.execute_input":"2022-07-19T05:24:45.498571Z","iopub.status.idle":"2022-07-19T05:24:45.873750Z","shell.execute_reply.started":"2022-07-19T05:24:45.498545Z","shell.execute_reply":"2022-07-19T05:24:45.872670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# As before, let's make everything float and scale\ndef float_scale(x_train,x_test):\n    x_train = x_train.astype('float32')\n    x_test = x_test.astype('float32')\n    # normalizer\n    x_train /= 255\n    x_test /= 255\n    return x_train, x_test\n\nx_train, x_test=float_scale(x_train,x_test)","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:24:46.549261Z","iopub.execute_input":"2022-07-19T05:24:46.549816Z","iopub.status.idle":"2022-07-19T05:24:46.798650Z","shell.execute_reply.started":"2022-07-19T05:24:46.549780Z","shell.execute_reply":"2022-07-19T05:24:46.797537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# the size of single image\nx_train.shape[1:]","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:24:59.289486Z","iopub.execute_input":"2022-07-19T05:24:59.290061Z","iopub.status.idle":"2022-07-19T05:24:59.298038Z","shell.execute_reply.started":"2022-07-19T05:24:59.290016Z","shell.execute_reply":"2022-07-19T05:24:59.296814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Keras CNN Layer\n\n```python\nkeras.layers.convolutional.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)\n```\n\nA few parameters explained:\n- `filters`: the number of filter used per location.  In other words, the depth of the output.\n- `kernel_size`: an (x,y) tuple giving the height and width of the kernel to be used\n- `strides`: and (x,y) tuple giving the stride in each dimension.  Default is `(1,1)`\n- `input_shape`: required only for the first layer\n\nNote, the size of the output will be determined by the kernel_size, strides\n\n### MaxPooling2D\n`keras.layers.pooling.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)`\n\n- `pool_size`: the (x,y) size of the grid to be pooled.\n- `strides`: Assumed to be the `pool_size` unless otherwise specified\n\n### Flatten\nTurns its input into a one-dimensional vector (per instance).  Usually used when transitioning between convolutional layers and fully connected layers.","metadata":{}},{"cell_type":"markdown","source":"# CNN Model Structure\n\n","metadata":{}},{"cell_type":"code","source":"# Let's build a CNN using Keras' Sequential capabilities\n\nmodel_1 = Sequential()\nnum_classes=10\n\n\n## 5x5 convolution with 1x1 stride and 32 filters\nmodel_1.add(Conv2D(32, (5, 5), strides = (1,1), padding='same',\n                 input_shape=x_train.shape[1:]))\nmodel_1.add(Activation('relu'))\n\n## Another 5x5 convolution with 1x1 stride and 64 filters\nmodel_1.add(Conv2D(64, (5, 5), strides = (1,1)))\nmodel_1.add(Activation('relu'))\n\n## 2x2 max pooling reduces to 3 x 3 x 32\nmodel_1.add(MaxPooling2D(pool_size=(2, 2)))\nmodel_1.add(Dropout(0.25))\n\n## Flatten turns 3x3x32 into 288x1\nmodel_1.add(Flatten())\nmodel_1.add(Dense(512))\nmodel_1.add(Activation('relu'))\nmodel_1.add(Dropout(0.5))\nmodel_1.add(Dense(num_classes))\nmodel_1.add(Activation('softmax'))\n\nmodel_1.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:25:19.165440Z","iopub.execute_input":"2022-07-19T05:25:19.166043Z","iopub.status.idle":"2022-07-19T05:25:22.085872Z","shell.execute_reply.started":"2022-07-19T05:25:19.166008Z","shell.execute_reply":"2022-07-19T05:25:22.084141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 32\n\n# initiate Adam optimizer\nopt = tf.keras.optimizers.Adam(learning_rate=0.002)\n\n# Let's train the model using Adam\nmodel_1.compile(loss='categorical_crossentropy',\n              optimizer=opt,\n              metrics=['accuracy'])\n\nhistory=model_1.fit(x_train, y_train,\n              batch_size=batch_size,\n              epochs=7,\n              validation_data=(x_test, y_test),\n              shuffle=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:25:29.435901Z","iopub.execute_input":"2022-07-19T05:25:29.436317Z","iopub.status.idle":"2022-07-19T05:26:53.433383Z","shell.execute_reply.started":"2022-07-19T05:25:29.436284Z","shell.execute_reply":"2022-07-19T05:26:53.432390Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Training History","metadata":{}},{"cell_type":"code","source":"def plot_model_history(history):\n    # list all data in history\n    print(history.history.keys())\n    # summarize history for accuracy\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.title('Model Accuracy')\n    plt.ylabel('accuracy')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'val'], loc='upper left')\n    plt.show()\n\nplot_model_history(history)","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:26:53.435756Z","iopub.execute_input":"2022-07-19T05:26:53.436125Z","iopub.status.idle":"2022-07-19T05:26:53.621375Z","shell.execute_reply.started":"2022-07-19T05:26:53.436090Z","shell.execute_reply":"2022-07-19T05:26:53.620463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Look into 1 Test set Prediction","metadata":{}},{"cell_type":"code","source":"## Let's look at one of the images prediction\nindex=95\nactual=y_test[index].argmax()\nplt.imshow(x_test[index])\npred=model_1.predict(x_test)[index].argmax()\nprint(f'Actual Label = {actual}')\nprint(f'Prediction Label = {pred}')","metadata":{"execution":{"iopub.status.busy":"2022-07-19T05:27:10.015184Z","iopub.execute_input":"2022-07-19T05:27:10.015525Z","iopub.status.idle":"2022-07-19T05:27:10.903801Z","shell.execute_reply.started":"2022-07-19T05:27:10.015497Z","shell.execute_reply":"2022-07-19T05:27:10.902821Z"},"trusted":true},"execution_count":null,"outputs":[]}]}