{"cells":[{"metadata":{"_uuid":"5763d0d4182e62d067b53dfdcd27e676a6c3b8bc"},"cell_type":"markdown","source":"## Introduction\nReusing pre-trained models is a powerful tool in machine learning.  [Keras Applications](https://keras.io/applications/) is one good source of pre-trained CNN models.  This kernel  reuses pre-trained models from [Pre-Trained Keras CNN Models](https://www.kaggle.com/kanwalinder/pretrained-keras-cnn-models) to translate [Dogs vs Cats Redux Input Images](https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition/data) to features."},{"metadata":{"_uuid":"5d800d0211bb339fb7b0df76ce23c883ae9f6f81"},"cell_type":"markdown","source":"## Installs\nThe following need to be installed for the  sample code to work."},{"metadata":{"trusted":true,"_uuid":"54eba20479f2cdb370a5e0cf411f90942d88aaa1","collapsed":true},"cell_type":"code","source":"# keras(python, tensorflow, numpy), Ipython, pydot, graphviz, and h5py","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"796b683ec717bc3a732db4f1705207ef58d8f794"},"cell_type":"markdown","source":"## Imports\nThe following need to be imported for the sample code to work."},{"metadata":{"trusted":true,"_uuid":"f40fcc2077633db3e01609769a1cb96f315ed432","scrolled":true,"collapsed":true},"cell_type":"code","source":"import keras as K\nprint(\"Keras Version is: \", K.__version__)\nimport tensorflow as tf\nprint(\"Tensorflow Version is: \", tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"89815549c8d117a8e8adaf012565de0569cc7ffb","collapsed":true},"cell_type":"code","source":"from keras.utils.vis_utils import model_to_dot, plot_model\nfrom IPython.display import SVG\nimport os, random, re, h5py\nimport numpy as np\n# keras utility to load saved models\nfrom keras.models import load_model\n# keras imports to load images and to convert them to arrays\nfrom keras.preprocessing.image import load_img\nfrom keras.preprocessing.image import img_to_array\n# to convert numeric to categorical labels\nfrom keras.utils import to_categorical","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"30537ee0e88fe64601070bbe25f14122bd12751d"},"cell_type":"markdown","source":"## Sample Code\nThe sample code below shows how the feature files were created."},{"metadata":{"trusted":true,"_uuid":"369683c85c4866eddde404ca4dbdb2b62b37b782","collapsed":true},"cell_type":"code","source":"# global variables\n# transfer models we want to use\nTRANSFER_MODELS=['xception', 'inception_v3', 'resnet50', 'inception_resnet_v2', 'mobilenet']\n#TRANSFER_MODELS=['inception_v3']\n# classes we are interested in\nCLASSES=np.array([['cat'.encode(\"utf-8\")], ['dog'.encode(\"utf-8\")]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"97b4391f826037d8525a2281323ccff08e66ca48","collapsed":true},"cell_type":"code","source":"print(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4a58adf56f4e9c960dd5e1e850406a62aba3ef5c","collapsed":true},"cell_type":"code","source":"#PRETRAINED_MODELS_DIRECTORY=os.listdir(\"../input\")[0]\n#print (PRETRAINED_MODELS_DIRECTORY)\n\nDOGSVSCATS_DATA_DIRECTORY=\"../input\"\nprint (DOGSVSCATS_DATA_DIRECTORY)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"34ff57e013dda38ae6dc24a259a2ff1bc1ec2ddd","collapsed":true},"cell_type":"code","source":"TRAIN_IMAGELIST=os.listdir(os.path.join(DOGSVSCATS_DATA_DIRECTORY, \"train\"))\nrandom.shuffle(TRAIN_IMAGELIST)\nTEST_IMAGELIST=os.listdir(os.path.join(DOGSVSCATS_DATA_DIRECTORY, \"test\"))\nrandom.shuffle(TEST_IMAGELIST)\nprint (\"{} training samples\".format(len(TRAIN_IMAGELIST)))\nprint (\"{} test samples\".format(len(TEST_IMAGELIST)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4fdc5377df55884621e7e0cd1b9117fb26a9035c","collapsed":true},"cell_type":"code","source":"\"\"\"select model and make model-specific keras imports\"\"\"\ndef SelectTransferModel(modelidentifier='inception_v3'):\n    print(\"=====================================================\")\n    print(\"Selected Model: {}...\".format(modelidentifier.title()))\n    print(\"=====================================================\")\n    if modelidentifier=='xception':\n        # each transfer model has a method to preprocess inputs\n        from keras.applications.xception import Xception, preprocess_input\n        transfermodelmethod=Xception\n        # xception expects images of size 299x299\n        resize=(299, 299)\n    if modelidentifier=='inception_v3':\n        # each transfer model has a method to preprocess inputs\n        from keras.applications.inception_v3 import InceptionV3, preprocess_input\n        transfermodelmethod=InceptionV3\n        # inception_v3 expects images of size 299x299\n        resize=(299, 299)\n    if modelidentifier=='resnet50':\n        from keras.applications.resnet50 import ResNet50, preprocess_input\n        # resnet50 expects images of size 224x224\n        transfermodelmethod=ResNet50\n        resize=(224, 224)\n    if modelidentifier=='inception_resnet_v2':\n        from keras.applications.inception_resnet_v2 import InceptionResNetV2, preprocess_input\n        # inception_resnet_v2 expects images of size 224x224\n        transfermodelmethod=InceptionResNetV2\n        resize=(299, 299)\n    if modelidentifier=='mobilenet':\n        from keras.applications.mobilenet import MobileNet, preprocess_input\n        transfermodelmethod=MobileNet\n        # mobilenetv2 expects images of size 224x224\n        resize=(224, 224)\n    return transfermodelmethod, resize, preprocess_input","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ce60bc454852a61720f2817c47ce3cf9b57c8a7e","collapsed":true},"cell_type":"code","source":"def ProcessImagebatch (transfermodel, modelidentifier, resize, preprocessmethod, imagebatch, mode=\"train\"):\n    examples=len(imagebatch)\n    inputids=np.zeros((examples,), dtype=int)\n    inputimages=np.zeros((examples, resize[0], resize[1], 3))\n    inputlabels=np.zeros((examples, 1))\n    print(\">>Loading {} images...\".format(examples), end=\"\")\n    for i, filename in enumerate(imagebatch):\n        # record the corresponding id from filename\n        if mode==\"train\":\n            id=filename.split(\".\")[1]\n        elif mode==\"test\":\n            id=filename.split(\".\")[0]\n        inputids[i]=id\n        #print (id)\n        # load image\n        filenamepath=os.path.join(DOGSVSCATS_DATA_DIRECTORY, mode, filename)\n        image = load_img(filenamepath, target_size=resize)\n        # convert image to array and append to inputimages array\n        inputimages[i]=img_to_array(image)\n        # record the corresponding label from filename\n        if mode==\"train\":\n            #label=os.path.split(filename)[1].split(\".\")[0]\n            label=filename.split(\".\")[0]\n            #print (label)\n            if str(label) == \"cat\":\n                inputlabels[i]=0\n            elif str(label) == \"dog\":\n                inputlabels[i]=1\n    print(\"done\")\n    # preprocess images to transfer model requirements\n    print (\">>Preprocessing {} loaded images for {}...\".format(inputimages.shape[0], modelidentifier.title()), end=\"\")\n    preprocessedinputimages = preprocessmethod(inputimages.copy())\n    print (\"done\")\n    print (\">>Converting {} preprocessed images to features...\".format(preprocessedinputimages.shape[0]))\n    featuresbatch=transfermodel.predict(preprocessedinputimages, verbose=1)\n    # to keep the function reusable, the function creates (spurious) labels for test inputs too,\n    # but the returned labels will be discarded\n    labelsbatch = to_categorical(inputlabels, num_classes=CLASSES.shape[0])\n    idsbatch=inputids\n    return featuresbatch, labelsbatch, idsbatch, preprocessedinputimages","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"737dc0d74221f42726e453abbdfa5a8bcfb3f833","collapsed":true},"cell_type":"code","source":"def Images2Features(transfermodel, modelidentifier, resize, preprocessmethod, imagelist, batchsize=1024, mode=\"train\"):\n    examples=len(imagelist)\n    ids=np.zeros((examples,), dtype=int)\n    features=np.zeros((examples, transfermodel.output.shape[1]))\n    labels=np.zeros((examples, CLASSES.shape[0]))\n    batches, leftover=divmod(examples,batchsize)\n    #print (batches, leftover)\n    # process all batches\n    for batch in range(batches):\n        startindex=batch*batchsize\n        endindex=batch*batchsize+batchsize\n        print (\">>Converting input images {}-{}...\".format(startindex, endindex))\n        imagebatch=imagelist[startindex:endindex]\n        featuresbatch, labelsbatch, idsbatch, _ = ProcessImagebatch(transfermodel, modelidentifier, resize, preprocessmethod, imagebatch, mode=mode)\n        features[startindex:endindex]=featuresbatch\n        labels[startindex:endindex]=labelsbatch\n        ids[startindex:endindex]=idsbatch\n    # process leftover\n    if leftover:\n        startindex=batches*batchsize\n        endindex=batches*batchsize+leftover\n        print (\">>Converting input images {}-{}...\".format(startindex, endindex))\n        imagebatch=imagelist[startindex:endindex]\n        featuresbatch, labelsbatch, idsbatch, _ = ProcessImagebatch(transfermodel, modelidentifier, resize, preprocessmethod, imagebatch, mode=mode)\n        features[startindex:endindex]=featuresbatch\n        labels[startindex:endindex]=labelsbatch\n        ids[startindex:endindex]=idsbatch\n    return features, labels, ids","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"97ade87358625d9fea800174a54ddd9d9bfc5a78","collapsed":true},"cell_type":"code","source":"for modelidentifier in TRANSFER_MODELS:\n    savedtrainfeaturesfilename=\"kaggledogsvscatsredux-{}-features-trainsamples-{}.h5\".format(modelidentifier,\n                                                                                             len(TRAIN_IMAGELIST))\n    savedtestfeaturesfilename=\"kaggledogsvscatsredux-{}-features-testsamples-{}.h5\".format(modelidentifier,\n                                                                                          len(TEST_IMAGELIST))\n    #print (savedtrainfeaturesfilename)\n    #print (savedtestfeaturesfilename)\n    transfermodelmethod, resize, preprocessmethod = SelectTransferModel(modelidentifier)\n    transfermodel = transfermodelmethod(weights='imagenet', include_top=False, pooling='avg')\n    # create training features\n    print(\"****************************************************************************\")\n    print (\"...Creating {} Training Features and Labels...\".format(len(TRAIN_IMAGELIST)))\n    print(\"****************************************************************************\")\n    train_x, train_y, train_ids = Images2Features(transfermodel, modelidentifier, resize, preprocessmethod, TRAIN_IMAGELIST,  mode=\"train\")\n    # save training feature inputs\n    with h5py.File(savedtrainfeaturesfilename, \"w\") as file:\n        file.create_dataset(\"train_x\", data=train_x)\n        file.create_dataset(\"train_y\", data=train_y)\n        file.create_dataset(\"train_ids\", data=train_ids)\n        file.create_dataset(\"classes\", data=CLASSES)\n        file.close()\n    print (\">>>Saved {} training features to {}\".format(train_x.shape[0],\n                                                        savedtrainfeaturesfilename))\n    print(\"****************************************************************************\")\n    print (\"...Creating {} Test Features...\".format(len(TEST_IMAGELIST)))\n    print(\"****************************************************************************\")\n    test_x, _, test_ids = Images2Features(transfermodel, modelidentifier, resize, preprocessmethod, TEST_IMAGELIST,  mode=\"test\")\n    with h5py.File(savedtestfeaturesfilename, \"w\") as file:\n        file.create_dataset(\"test_x\", data=test_x)\n        file.create_dataset(\"test_ids\", data=test_ids)\n        file.create_dataset(\"classes\", data=CLASSES)\n        file.close()\n    print (\">>>Saved {} test features to {}\".format(test_x.shape[0],\n                                                    savedtestfeaturesfilename))\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"75292ff20c44d16850703b280ffa524cc7171ab1"},"cell_type":"markdown","source":"## Conclusion\nNow you have access to features files for dogs vs cats from common CNN models.  You can define classifiers that use these features to classify dogs and cats.\n\nIf you feel inspired, click the blue \"Fork Notebook\" button at the top of this kernel. This will create a copy of the code and environment for you to edit. Delete, modify, and add code as you please. Happy Dogging and Catting!"}],"metadata":{"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}},"nbformat":4,"nbformat_minor":1}