{"cells":[{"metadata":{"_uuid":"505d7b01-8f35-4948-946f-f457df7a03d2","_cell_guid":"0bf99c0d-d381-46ec-8238-72f73453220f","trusted":true},"cell_type":"markdown","source":"### Tutorial CNN in TensorFlow for classify dogs and cats\n\nReference materials\n+ Loading data https://pythonprogramming.net/convolutional-neural-network-kats-vs-dogs-machine-learning-tutorial/\n+ CNN reference https://www.datacamp.com/community/tutorials/cnn-tensorflow-python"},{"metadata":{"_uuid":"8f4f2109-045b-4a3c-9d28-817ca24c74db","_cell_guid":"22cc3f80-178a-417b-bda4-33bf322abcd8","trusted":true},"cell_type":"code","source":"import os\nimport cv2 \nimport pandas as pd \nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg \nimport numpy as np\nimport tensorflow as tf\nfrom tqdm import tqdm  \nfrom tensorflow.python.framework import ops\nfrom sklearn.utils import shuffle\nfrom sklearn.model_selection import train_test_split","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7ac3304a-20ac-455c-ae6f-a78759f4071d","_cell_guid":"e84628f6-4367-4508-832a-79653c692afc","trusted":true},"cell_type":"code","source":"TRAIN_DIR = 'train/'\nIMG_SIZE = 32\nCHANNEL_NUMBER = 1\nLR = 1e-3","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"66ffabe3-9255-445f-95dc-f53646c3f31a","_cell_guid":"e9ee92d3-e64e-4fe8-af61-643d45caa95d","trusted":true},"cell_type":"markdown","source":"### Function for conversion to one-hot-array"},{"metadata":{"_uuid":"6c2ec174-37cc-4f04-b7e1-f2ed358fb1fa","_cell_guid":"b3f88e2d-ccd4-4a55-bcde-ba8138dc9af1","trusted":true},"cell_type":"code","source":"def label_img(img):\n    word_label = img.split('.')[-3]            \n    if word_label == 'cat': return [1,0] #[much cat, no dog]\n    elif word_label == 'dog': return [0,1]  #[no cat, very doggo]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ff2beb69-fb59-494c-8d3a-c7d8adea58cd","_cell_guid":"700a8ead-4ff0-4a0f-840c-8b936cf28d03","trusted":true},"cell_type":"markdown","source":"### Function to get the images for training"},{"metadata":{"_uuid":"c22ca4c3-710a-4be2-9b9f-33fa125c8368","_cell_guid":"8153076b-da18-491e-ad0e-965148f631b7","trusted":true},"cell_type":"code","source":"def create_train_data():\n    training_data = []\n    for img in tqdm(os.listdir(TRAIN_DIR)):\n        label = label_img(img)\n        path = os.path.join(TRAIN_DIR,img)\n        img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)\n        img = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n        training_data.append([np.array(img),np.array(label)])\n    shuffle(training_data)\n    return training_data","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"edc290c0-4843-477d-92a8-980ffd213295","_cell_guid":"a5016534-2939-48ef-99fc-faf10a8431c9","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"train_data = create_train_data()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dadcc0d7-1167-4df1-b2ea-19317c579bf4","_cell_guid":"6bad6669-e914-4157-9b4f-22d94846ac3f","trusted":true},"cell_type":"markdown","source":"### Create training and test"},{"metadata":{"_uuid":"cb70a752-0bb9-4fb3-96d7-68ecaed5ec40","_cell_guid":"8aeaeb2d-3034-4b23-a11b-6baafc752822","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain,test  = train_test_split(train_data,test_size = 0.3)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"cc459f18-4cc0-416f-9576-245c598a0581","_cell_guid":"a187d6b1-b5e4-4177-b8ad-aaa726027566","trusted":true},"cell_type":"markdown","source":"### Prepare Data for layer"},{"metadata":{"_uuid":"c359a185-e671-4ab8-9b63-50aa694f7109","_cell_guid":"fac88e4c-4c4a-456c-8595-aad2fd62cbf5","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"# The -1 in the reshape() function means that it will infer the first dimension on its own \n#but the rest of the dimension are fixed, that is, IMG_SIZE x IMG_SIZE x CHANNEL_NUMBER.\ntrain_X = np.array([i[0] for i in train]).reshape(-1,IMG_SIZE,IMG_SIZE,CHANNEL_NUMBER)\ntrain_Y = [i[1] for i in train]\n\ntest_X = np.array([i[0] for i in test]).reshape(-1,IMG_SIZE,IMG_SIZE,CHANNEL_NUMBER)\ntest_Y = [i[1] for i in test]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1e4b2c7e-1434-4960-add7-66c367ae1d85","_cell_guid":"52253e9a-575b-494b-9688-ec4022ca095c","trusted":true},"cell_type":"markdown","source":"### Hyper-parameters"},{"metadata":{"_uuid":"9cb2da2d-6652-413c-b9ff-07dd5fc65c76","_cell_guid":"b9658ff8-1e8e-4b27-8413-66c948daed7c","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"TRAINING_ITERS = 50\nBATCH_SIZE = 128\nN_CLASSES = 2","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e4a72219-8ca8-4fe6-9b90-d6915c7b21da","_cell_guid":"e628c62c-17ee-4a86-9b8b-b236c4f3a15a","trusted":true},"cell_type":"markdown","source":"# Create CNN"},{"metadata":{"_uuid":"c75086be-f18b-400a-8890-77f0dc9c4dbf","_cell_guid":"f9a55d3e-4a4f-4cdf-9989-bdca1357c679","trusted":true},"cell_type":"markdown","source":"### Define Inputs"},{"metadata":{"_uuid":"068bd319-9d24-45df-809a-5ef5d5979e8b","_cell_guid":"eaf70961-a5d4-424b-bab9-aa161024391d","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"X = tf.placeholder(\"float\", [None, IMG_SIZE,IMG_SIZE,CHANNEL_NUMBER])\nY = tf.placeholder(\"float\", [None, N_CLASSES])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"594dd300-00e5-4ef9-b0ba-0fc01ab4a2df","_cell_guid":"3634d086-2181-4079-9c8b-ab95a094776d","trusted":true},"cell_type":"markdown","source":"### Creating convolutional and maxpool layers functions"},{"metadata":{"_uuid":"1c70d697-bcd9-4ea2-8eef-db58debae1c6","_cell_guid":"fe652a59-367f-4480-ba34-d0de21acedca","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"def conv2d(x, W, b, strides=1):\n    # Conv2D wrapper, with bias and relu activation\n    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')\n    x = tf.nn.bias_add(x, b)\n    return tf.nn.relu(x) \n\ndef maxpool2d(x, k=2):\n    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],padding='SAME')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7f034df6-1917-44fd-8211-907547a6fd67","_cell_guid":"72ff0fb3-e391-48e7-a59e-8cb877b0a151","trusted":true},"cell_type":"markdown","source":"### Define Weights and Biases for each layer"},{"metadata":{"_uuid":"9c25d9f1-129d-4f79-972d-2b2a1acccb8c","_cell_guid":"6b479f6f-b3d9-4788-b6ae-5def861bd8d6","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"weights = {\n    'wc1': tf.get_variable('W0', shape=(3,3,1,32), initializer=tf.contrib.layers.xavier_initializer()), \n    'wc2': tf.get_variable('W1', shape=(3,3,32,64), initializer=tf.contrib.layers.xavier_initializer()), \n    'wc3': tf.get_variable('W2', shape=(3,3,64,128), initializer=tf.contrib.layers.xavier_initializer()), \n    'wd1': tf.get_variable('W3', shape=(4*4*128,128), initializer=tf.contrib.layers.xavier_initializer()), \n    'out': tf.get_variable('W6', shape=(128,N_CLASSES), initializer=tf.contrib.layers.xavier_initializer()), \n}\nbiases = {\n    'bc1': tf.get_variable('B0', shape=(32), initializer=tf.contrib.layers.xavier_initializer()),\n    'bc2': tf.get_variable('B1', shape=(64), initializer=tf.contrib.layers.xavier_initializer()),\n    'bc3': tf.get_variable('B2', shape=(128), initializer=tf.contrib.layers.xavier_initializer()),\n    'bd1': tf.get_variable('B3', shape=(128), initializer=tf.contrib.layers.xavier_initializer()),\n    'out': tf.get_variable('B4', shape=(N_CLASSES), initializer=tf.contrib.layers.xavier_initializer()),\n}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6429c535-9f09-45e5-ba1f-72dcd84e6259","_cell_guid":"28ee1453-5bfa-485b-aca9-4b67e489548e","trusted":true},"cell_type":"markdown","source":"### Create CNN (connect all layers)"},{"metadata":{"_uuid":"933aab01-f783-4c46-9b7b-93eaa1a557d9","_cell_guid":"4a1c260f-f538-4082-a154-d219aa5b1675","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"def conv_net(x, weights, biases):  \n\n    # here we call the conv2d function we had defined above and pass the input image x, weights wc1 and bias bc1.\n    conv1 = conv2d(x, weights['wc1'], biases['bc1'])\n    # Max Pooling (down-sampling), this chooses the max value from a 2*2 matrix window and outputs a 14*14 matrix.\n    conv1 = maxpool2d(conv1, k=2)\n\n    # Convolution Layer\n    # here we call the conv2d function we had defined above and pass the input image x, weights wc2 and bias bc2.\n    conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])\n    # Max Pooling (down-sampling), this chooses the max value from a 2*2 matrix window and outputs a 7*7 matrix.\n    conv2 = maxpool2d(conv2, k=2)\n\n    conv3 = conv2d(conv2, weights['wc3'], biases['bc3'])\n    # Max Pooling (down-sampling), this chooses the max value from a 2*2 matrix window and outputs a 4*4.\n    conv3 = maxpool2d(conv3, k=2)\n\n    # Fully connected layer\n    # Reshape conv2 output to fit fully connected layer input\n    fc1 = tf.reshape(conv3, [-1, weights['wd1'].get_shape().as_list()[0]])\n    fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])\n    fc1 = tf.nn.relu(fc1)\n    # Output, class prediction\n    # finally we multiply the fully connected layer with the weights and add a bias term. \n    out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])\n    return out","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f16b759-ff87-4660-9681-0fa8c7a927fd","_cell_guid":"cb0dd765-365b-42f9-9e2b-365dd3d6807e","trusted":true},"cell_type":"markdown","source":"### Loss and Optimizer"},{"metadata":{"_uuid":"abe80dcf-f02f-4708-92db-fe5a87417898","_cell_guid":"fc914c73-4f1b-4a5e-ba75-1c2fd1d75489","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"pred = conv_net(X, weights, biases)\ncost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=Y))\noptimizer = tf.train.AdamOptimizer(learning_rate=LR).minimize(cost)\n# Here you check whether the index of the maximum value of the predicted image is equal \n# to the actual labelled image. and both will be a column vector.\ncorrect_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(Y, 1))\n# Calculate accuracy across all the given images and average them out. \naccuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9b67ee98-e8bd-4839-b325-8f277e98926f","_cell_guid":"44e92d27-6a6c-4b2d-b2a2-f6aa4747f35e","trusted":true},"cell_type":"markdown","source":"### Training"},{"metadata":{"_uuid":"35b0d011-6253-43f1-b7ed-56c65091ea88","_cell_guid":"4b0351db-b85d-476d-a799-58f8e570834c","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"init = tf.global_variables_initializer()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b1c596ee-d540-45d0-ba1a-ceb3ea4d3ad0","_cell_guid":"84cf12de-3338-402b-aa71-a2987a775605","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"with tf.Session() as sess:\n    sess.run(init) \n    train_loss = []\n    test_loss = []\n    train_accuracy = []\n    test_accuracy = []\n   \n    for i in range(TRAINING_ITERS):\n        for batch in range(len(train_X)//BATCH_SIZE):\n            batch_x = train_X[batch*BATCH_SIZE:min((batch+1)*BATCH_SIZE,len(train_X))]\n            batch_y = train_Y[batch*BATCH_SIZE:min((batch+1)*BATCH_SIZE,len(train_Y))]    \n            # Calculate batch loss and accuracy\n            opt = sess.run(optimizer, feed_dict={X:batch_x,Y:batch_y})\n            loss, acc = sess.run([cost, accuracy], feed_dict={X: batch_x, Y: batch_y})\n            \n        print(\"Iter \" + str(i) + \", Loss= \" + \\\n                      \"{:.6f}\".format(loss) + \", Training Accuracy= \" + \\\n                      \"{:.5f}\".format(acc))\n        \n        print(\"Optimization Finished!\")\n\n        test_acc,valid_loss = sess.run([accuracy,cost], feed_dict={X:test_X,Y:test_Y})\n        train_loss.append(loss)\n        test_loss.append(valid_loss)\n        train_accuracy.append(acc)\n        test_accuracy.append(test_acc)\n        \n        print(\"Testing Accuracy:\",\"{:.5f}\".format(test_acc))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9ba9ba5d-f32f-48fb-9999-5055960ff1ab","_cell_guid":"63395b42-59c8-4222-9999-35274cea2282","trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.4"}},"nbformat":4,"nbformat_minor":1}