{"cells":[{"metadata":{"_uuid":"6bbc4acea2b05a587b89f903db2e82b93ddc2cc9"},"cell_type":"markdown","source":"# Dogs v/s Cats Redux\n### This notebook is for classification of photos into dogs and cats\n\nBelow are the python packages needed. As 2 convolutional layers did really bad, let's see whats the impact of adding more layers to it. Let's make it 6."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"collapsed":true},"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport random\nfrom tqdm import tqdm\n\nTRAIN_DIR = \"../input/train\"\nTEST_DIR = \"../input/test\"\nIMG_SIZE = 50\nLR = 1e-3\n\nMODEL_NAME = \"dogsvscats-{}-{}.model\".format(LR, \"6conv-basic\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0d978f48304517a396844c16312e94d7c6cc9d1c"},"cell_type":"markdown","source":"I've taken one-hot classification labels based on closeness to the features of cat or dog. That means a vector of 2 dimensions `[x, y]`, where `x` is how close to be a cat in that photo and `y` is how close to be a dog it is. So, for to be classified as cat `[1, 0]` and to be dog `[0, 1]`"},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"71a5897a097dad05efe2ec7f52c1530a5baf9684"},"cell_type":"code","source":"def label_img(img):\n    word_label = img.split(\".\")[0]\n    if word_label == \"cat\":\n        return [1, 0]\n    elif word_label == \"dog\":\n        return [0, 1]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4b8b671c584820b7a846969cd23276977c260033"},"cell_type":"markdown","source":"Let's create training data."},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"67d8bc5fdf76cfeff72ae321f910904251be758e"},"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_resized = cv2.resize(cv2.imread(path, cv2.IMREAD_GRAYSCALE), (IMG_SIZE, IMG_SIZE))\n        training_data.append([np.array(img_resized), np.array(label)])\n    random.shuffle(training_data)\n    np.save(\"training_data.npy\", training_data)\n    return training_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"3000a7d7d648e455ebb87e2b8721d870f6e87677"},"cell_type":"markdown","source":"Then let's process test data."},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"af812df0575c07887f03644e6ab65019e9d3b154"},"cell_type":"code","source":"def process_test_data():\n    testing_data = []\n    for img in tqdm(os.listdir(TEST_DIR)):\n        path = os.path.join(TEST_DIR, img)\n        img_num = img.split(\".\")[0]\n        img_resized = cv2.resize(cv2.imread(path, cv2.IMREAD_GRAYSCALE), (IMG_SIZE, IMG_SIZE))\n        testing_data.append([np.array(img_resized), img_num])\n    np.save(\"testing_data.npy\", testing_data)\n    return testing_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"d4723a396a55dc00dbfdf773242a10ca062d8452"},"cell_type":"markdown","source":"If we saved already, we can just load from the saved numpy file."},{"metadata":{"trusted":true,"_uuid":"def98ddab19eb25a70e16bcc14706d165b755533"},"cell_type":"code","source":"train_data = create_train_data()\n# train_data = np.load(\"training_data.npy\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"bf0a388cec15155a173927b1925a20df59470d4f"},"cell_type":"markdown","source":"Now, I've defined a convolutional network model created in tflearn, with tensorflow backend framework. \n\n**Two convolutional layers with ReLU activation, optimized by AdamOptimizer,  Categorical Cross-entropy loss function, and with the learnng rate of 0.001**"},{"metadata":{"trusted":true,"_uuid":"113eb6c566016b9b888ca98546c4b62ed25ba673","collapsed":true},"cell_type":"code","source":"import tflearn\nimport tensorflow as tf\nfrom tflearn.layers.conv import conv_2d, max_pool_2d\nfrom tflearn.layers.core import input_data, dropout, fully_connected\nfrom tflearn.layers.estimator import regression\n\ntf.reset_default_graph()\n\nconvnet = input_data(shape=[None, IMG_SIZE, IMG_SIZE, 1], name='input')\n\nconvnet = conv_2d(convnet, 32, 2, activation='relu')\nconvnet = max_pool_2d(convnet, 2)\n\nconvnet = conv_2d(convnet, 64, 2, activation='relu')\nconvnet = max_pool_2d(convnet, 2)\n\nconvnet = conv_2d(convnet, 32, 2, activation='relu')\nconvnet = max_pool_2d(convnet, 2)\n\nconvnet = conv_2d(convnet, 64, 2, activation='relu')\nconvnet = max_pool_2d(convnet, 2)\n\nconvnet = conv_2d(convnet, 32, 2, activation='relu')\nconvnet = max_pool_2d(convnet, 2)\n\nconvnet = conv_2d(convnet, 64, 2, activation='relu')\nconvnet = max_pool_2d(convnet, 2)\n\nconvnet = fully_connected(convnet, 1024, activation='relu')\nconvnet = dropout(convnet, 0.8)\n\nconvnet = fully_connected(convnet, 2, activation='softmax')\nconvnet = regression(convnet, optimizer='adam', learning_rate=LR, loss='categorical_crossentropy', name='targets')\n\nmodel = tflearn.DNN(convnet, tensorboard_dir='log')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d1cf858d98b013b6dce9b0d4d6354011b31e0ca4"},"cell_type":"markdown","source":"Let's quickly check what we have saved. We can see metadata of our notebooks and also other saved files."},{"metadata":{"trusted":true,"_uuid":"a17a8464a317a8c3cc58ebf2c7e8aa0d3ab7f9f3"},"cell_type":"code","source":"print(os.listdir(\".\"))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dce56df3dcea7efaad6e3aade5591c1827973987"},"cell_type":"markdown","source":"If we have already saved the model as checkpoint, then we can just simply load it up and keep working. "},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"d340763b287e9427675bf18e47156848cc44a48a"},"cell_type":"code","source":"if os.path.exists(\"{}.meta\".format(MODEL_NAME)):\n    model.load(MODEL_NAME)\n    print(\"Model loaded\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1835def71d712d020c29a6585eeb13351ae494ad"},"cell_type":"markdown","source":"Let's split for validation stats."},{"metadata":{"trusted":true,"_uuid":"895c0d1798f6c25e3b88a4573750ad40e7a28ba9","collapsed":true},"cell_type":"code","source":"train = train_data[:-500]\ntest = train_data[-500:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"08173c35ac3b98c8d9a219d8aef1740877fc22c8"},"cell_type":"code","source":"X = np.array([i[0] for i in train]).reshape(-1, IMG_SIZE, IMG_SIZE , 1)\ny = [i[1] for i in train]\ntest_X = np.array([i[0] for i in test]).reshape(-1, IMG_SIZE, IMG_SIZE , 1)\ntest_y = [i[1] for i in test]\nX.shape, test_X.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7f37a56beb2ea2c541eea980a6b1e3cf847b3b63"},"cell_type":"markdown","source":"Now, let's fit the model and see our validation scores and accuracies w.r.t each epoch as well as overall."},{"metadata":{"trusted":true,"_uuid":"2bfa1ef6e4941a770c41523f6009372d3e409687"},"cell_type":"code","source":"model.fit({\"input\": X}, \n          {\"targets\": y}, \n          n_epoch = 5, \n          validation_set = ({\"input\": test_X}, {\"targets\": test_y}),\n          snapshot_step = 500, \n          show_metric = True, \n          run_id = MODEL_NAME)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","collapsed":true,"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":false},"cell_type":"markdown","source":"Resulting accuracy touching high 70's (78%) by just adding few more convolutional layers. "}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}