{"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":"**Transfer Learning**\n\nDo Transfer Learning using VGG16 to classify a cat vs. dog.","metadata":{}},{"cell_type":"markdown","source":"**Inspiration**\n\n* https://www.kaggle.com/jeffd23/catdognet-keras-convnet-starter/notebook\n* https://www.kaggle.com/inoryy/api-for-keras-models-pre-trained-angles/notebook\n* https://gist.github.com/carlos-aguayo/7786f6150ee6702a7416d5dd4e925fb9\n* https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html","metadata":{"_uuid":"40921f7803fd74605cdbbbfc31d594545197f56a","_cell_guid":"56be40b0-dfb8-408b-be59-fc5a22e2d210"}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport os, cv2\nfrom keras.models import Sequential\nfrom keras.layers import Dropout, Flatten, Dense\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Model\nimport matplotlib.pyplot as plt\n%matplotlib inline ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-09T01:43:08.330290Z","iopub.execute_input":"2022-01-09T01:43:08.330632Z","iopub.status.idle":"2022-01-09T01:43:11.564905Z","shell.execute_reply.started":"2022-01-09T01:43:08.330557Z","shell.execute_reply":"2022-01-09T01:43:11.563986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(os.listdir(\"../input\"))\nprint(os.listdir(\"../input/c/dogs-vs-cats-redux-kernels-edition\"))","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:11.565840Z","iopub.execute_input":"2022-01-09T01:43:11.566194Z","iopub.status.idle":"2022-01-09T01:43:11.574282Z","shell.execute_reply.started":"2022-01-09T01:43:11.566158Z","shell.execute_reply":"2022-01-09T01:43:11.572779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip \"../input/c/dogs-vs-cats-redux-kernels-edition/train.zip\" >> /dev/null\n!unzip \"../input/c/dogs-vs-cats-redux-kernels-edition/test.zip\" >> /dev/null","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:11.575498Z","iopub.execute_input":"2022-01-09T01:43:11.575760Z","iopub.status.idle":"2022-01-09T01:43:30.015898Z","shell.execute_reply.started":"2022-01-09T01:43:11.575707Z","shell.execute_reply":"2022-01-09T01:43:30.014939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg16_weights = \"../input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5\"","metadata":{"_uuid":"fc30eba4750e28f28b63a306131116262c16e611","_cell_guid":"7b836cab-016b-4412-9732-7f845a83af11","execution":{"iopub.status.busy":"2022-01-09T01:43:30.017152Z","iopub.execute_input":"2022-01-09T01:43:30.017427Z","iopub.status.idle":"2022-01-09T01:43:30.024682Z","shell.execute_reply.started":"2022-01-09T01:43:30.017389Z","shell.execute_reply":"2022-01-09T01:43:30.023715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications import VGG16","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2022-01-09T01:43:30.026278Z","iopub.execute_input":"2022-01-09T01:43:30.026789Z","iopub.status.idle":"2022-01-09T01:43:30.040611Z","shell.execute_reply.started":"2022-01-09T01:43:30.026730Z","shell.execute_reply":"2022-01-09T01:43:30.039730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROWS, COLS = 150, 150\nimg_width, img_height = 150, 150\nCHANNELS = 3","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:30.042117Z","iopub.execute_input":"2022-01-09T01:43:30.042766Z","iopub.status.idle":"2022-01-09T01:43:30.054742Z","shell.execute_reply.started":"2022-01-09T01:43:30.042706Z","shell.execute_reply":"2022-01-09T01:43:30.053945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg16_model = VGG16(include_top=False, weights=vgg16_weights, input_shape=(img_width, img_height, CHANNELS))\nprint (vgg16_model.summary())","metadata":{"_uuid":"4bd62c15321aa3d68b6832d6dfe034376f14bd6d","_cell_guid":"8ca444d7-02b6-44d7-b559-55c37bd6cc96","execution":{"iopub.status.busy":"2022-01-09T01:43:30.056213Z","iopub.execute_input":"2022-01-09T01:43:30.056860Z","iopub.status.idle":"2022-01-09T01:43:31.360851Z","shell.execute_reply.started":"2022-01-09T01:43:30.056798Z","shell.execute_reply":"2022-01-09T01:43:31.360031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# TRAIN_DIR = '../input/c/dogs-vs-cats-redux-kernels-edition/train/'\n# TEST_DIR = '../input/c/dogs-vs-cats-redux-kernels-edition/test/'\n\nTRAIN_DIR = 'train/'\nTEST_DIR = 'test/'","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:31.362125Z","iopub.execute_input":"2022-01-09T01:43:31.362431Z","iopub.status.idle":"2022-01-09T01:43:31.366125Z","shell.execute_reply.started":"2022-01-09T01:43:31.362384Z","shell.execute_reply":"2022-01-09T01:43:31.365346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# os.listdir(TRAIN_DIR)\n# is something like:\n# ['cat.9491.jpg', 'cat.11613.jpg', 'cat.11841.jpg', 'dog.423.jpg', 'cat.11501.jpg', ...]\n\ntrain_images = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)] # use this for full dataset\ntrain_dogs =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'dog' in i]\ntrain_cats =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'cat' in i]\n\ntest_images =  [TEST_DIR+i for i in os.listdir(TEST_DIR)]\n\nprint(\"Total training images: {:,}\".format(len(train_images)))\nprint(\"Total test images: {:,}\".format(len(test_images)))","metadata":{"_uuid":"1f52374dcfa53481de6df48612b2c172873452ce","_cell_guid":"4000fb77-3ac7-4432-9a70-e4b3697f6509","execution":{"iopub.status.busy":"2022-01-09T01:43:31.367194Z","iopub.execute_input":"2022-01-09T01:43:31.367474Z","iopub.status.idle":"2022-01-09T01:43:31.444377Z","shell.execute_reply.started":"2022-01-09T01:43:31.367427Z","shell.execute_reply":"2022-01-09T01:43:31.443600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# slice datasets for memory efficiency on Kaggle Kernels, delete if using full dataset\ntrain_images = train_dogs[:1000] + train_cats[:1000]\ntest_images =  test_images[:25]","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:31.445536Z","iopub.execute_input":"2022-01-09T01:43:31.445794Z","iopub.status.idle":"2022-01-09T01:43:31.451243Z","shell.execute_reply.started":"2022-01-09T01:43:31.445743Z","shell.execute_reply":"2022-01-09T01:43:31.450395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = []\nfor i in train_images:\n    if 'dog' in i.replace('dogs-vs-cats-redux-kernels-edition', ''):\n        labels.append(1)\n    else:\n        labels.append(0)\n        \nprint (\"len labels: {:,}\".format(len(labels)))\nprint (\"number of dogs: {:,}\".format(np.array(labels).sum()))","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:31.452642Z","iopub.execute_input":"2022-01-09T01:43:31.452969Z","iopub.status.idle":"2022-01-09T01:43:31.465947Z","shell.execute_reply.started":"2022-01-09T01:43:31.452902Z","shell.execute_reply":"2022-01-09T01:43:31.465072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time \n\ndef read_image(file_path):\n    img = cv2.imread(file_path, cv2.IMREAD_COLOR) #cv2.IMREAD_GRAYSCALE\n    return cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)\n\ndef prep_data(images):\n    count = len(images)\n    data = np.ndarray((count, ROWS, COLS, CHANNELS), dtype=np.uint8)\n\n    for i, image_file in enumerate(images):\n        image = read_image(image_file)\n        data[i] = image\n        if i%250 == 0: print('Processed {} of {}'.format(i, count))\n    \n    return data\n\ntrain = prep_data(train_images)\ntest = prep_data(test_images)","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:31.467115Z","iopub.execute_input":"2022-01-09T01:43:31.467513Z","iopub.status.idle":"2022-01-09T01:43:36.171683Z","shell.execute_reply.started":"2022-01-09T01:43:31.467459Z","shell.execute_reply":"2022-01-09T01:43:36.170817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Train shape: {}\".format(train.shape))\nprint(\"Test shape: {}\".format(test.shape))","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:36.172788Z","iopub.execute_input":"2022-01-09T01:43:36.173096Z","iopub.status.idle":"2022-01-09T01:43:36.178393Z","shell.execute_reply.started":"2022-01-09T01:43:36.173036Z","shell.execute_reply":"2022-01-09T01:43:36.177626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_cats_and_dogs(idx):\n    cat = read_image(train_cats[idx])\n    dog = read_image(train_dogs[idx])\n    pair = np.concatenate((cat, dog), axis=1)\n    plt.axis(\"off\")\n    plt.figure(figsize=(10,5))\n    plt.imshow(cv2.cvtColor(pair, cv2.COLOR_BGR2RGB))\n    plt.show()\n    \nfor idx in range(0,5):\n    show_cats_and_dogs(idx)","metadata":{"_uuid":"ef11669dfb82d661022af4b627e3e91fe5ac2837","_cell_guid":"3993dd5a-7843-43cb-ac58-4cc4187c77d4","execution":{"iopub.status.busy":"2022-01-09T01:43:36.179473Z","iopub.execute_input":"2022-01-09T01:43:36.179716Z","iopub.status.idle":"2022-01-09T01:43:37.502857Z","shell.execute_reply.started":"2022-01-09T01:43:36.179671Z","shell.execute_reply":"2022-01-09T01:43:37.501843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = ImageDataGenerator(rescale=1. / 255)\ngenerator = datagen.flow(train,\n                         labels,\n                         shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:43:37.504333Z","iopub.execute_input":"2022-01-09T01:43:37.504656Z","iopub.status.idle":"2022-01-09T01:43:37.903932Z","shell.execute_reply.started":"2022-01-09T01:43:37.504592Z","shell.execute_reply":"2022-01-09T01:43:37.902967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nbottleneck_features_train = vgg16_model.predict_generator(generator)","metadata":{"_uuid":"dc0d6645a3de01c2243fdab6be0c1e2a3d8a69f8","_cell_guid":"ad146c3a-0db7-461d-a404-5abf23bd74b4","execution":{"iopub.status.busy":"2022-01-09T01:43:37.905100Z","iopub.execute_input":"2022-01-09T01:43:37.905342Z","iopub.status.idle":"2022-01-09T01:48:39.981650Z","shell.execute_reply.started":"2022-01-09T01:43:37.905299Z","shell.execute_reply":"2022-01-09T01:48:39.978339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nb_train_samples = bottleneck_features_train.shape[0]\nepochs = 50\nbatch_size = 16\n\ntrain_data = bottleneck_features_train\ntrain_labels = np.array([0] * int(nb_train_samples / 2) + [1] * int(nb_train_samples / 2))","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:48:39.983778Z","iopub.execute_input":"2022-01-09T01:48:39.984059Z","iopub.status.idle":"2022-01-09T01:48:39.991776Z","shell.execute_reply.started":"2022-01-09T01:48:39.984011Z","shell.execute_reply":"2022-01-09T01:48:39.990793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential()\nmodel.add(Flatten(input_shape=train_data.shape[1:]))\nmodel.add(Dense(256, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1, activation='sigmoid'))\nmodel.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])\nprint (model.summary())","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:48:39.992972Z","iopub.execute_input":"2022-01-09T01:48:39.993206Z","iopub.status.idle":"2022-01-09T01:48:40.092879Z","shell.execute_reply.started":"2022-01-09T01:48:39.993166Z","shell.execute_reply":"2022-01-09T01:48:40.092003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nmodel.fit(train_data, \n          train_labels,\n          epochs=epochs,\n          batch_size=batch_size,\n          verbose=2)","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:48:40.094488Z","iopub.execute_input":"2022-01-09T01:48:40.094908Z","iopub.status.idle":"2022-01-09T01:51:19.966100Z","shell.execute_reply.started":"2022-01-09T01:48:40.094760Z","shell.execute_reply":"2022-01-09T01:51:19.965348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"complete_model = Model(inputs=vgg16_model.input, outputs=model(vgg16_model.output))","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:51:19.967514Z","iopub.execute_input":"2022-01-09T01:51:19.970504Z","iopub.status.idle":"2022-01-09T01:51:20.004733Z","shell.execute_reply.started":"2022-01-09T01:51:19.970413Z","shell.execute_reply":"2022-01-09T01:51:20.004034Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\npredictions = complete_model.predict(test)","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:51:20.005651Z","iopub.execute_input":"2022-01-09T01:51:20.006001Z","iopub.status.idle":"2022-01-09T01:51:23.737469Z","shell.execute_reply.started":"2022-01-09T01:51:20.005962Z","shell.execute_reply":"2022-01-09T01:51:23.736615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(0,10):\n    if predictions[i, 0] >= 0.5: \n        print('I am {:.2%} sure this is a Cat'.format(predictions[i][0]))\n    else: \n        print('I am {:.2%} sure this is a Dog'.format(1-predictions[i][0]))\n        \n    plt.imshow(cv2.cvtColor(test[i], cv2.COLOR_BGR2RGB))  \n    plt.axis(\"off\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:51:23.738646Z","iopub.execute_input":"2022-01-09T01:51:23.738875Z","iopub.status.idle":"2022-01-09T01:51:24.903652Z","shell.execute_reply.started":"2022-01-09T01:51:23.738833Z","shell.execute_reply":"2022-01-09T01:51:24.902777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from skimage import io\n\nimg_url = 'https://yt3.ggpht.com/ytc/AKedOLRvxGYSdEHqu0X4EYcJ2kq7BttRKBNpfwdHJf3FSg=s900-c-k-c0x00ffffff-no-rj'\n\nimg = io.imread(img_url)\nimg = cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)\nimg = img / 255.0\nimg = img.reshape(1,ROWS,COLS,3)\n\nprediction = complete_model.predict(img)[0][0]\nif prediction >= 0.5:\n    print('I am {:.2%} sure this is a Cat'.format(prediction))\nelse: \n    print('I am {:.2%} sure this is a Dog'.format(1-prediction))\n        \nplt.imshow(img[0], 'Blues')\nplt.axis(\"off\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-09T01:51:24.904887Z","iopub.execute_input":"2022-01-09T01:51:24.905126Z","iopub.status.idle":"2022-01-09T01:51:25.682185Z","shell.execute_reply.started":"2022-01-09T01:51:24.905085Z","shell.execute_reply":"2022-01-09T01:51:25.681445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}