{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport cv2\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport skimage\nfrom skimage import io\nfrom tqdm import tqdm\nimport imgaug as ia\nfrom imgaug import augmenters as iaa\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\nimport random\nimport os,shutil\n\nsrc_path=\"../input\"\n\nprint(os.listdir(src_path))\n#print(os.listdir(\"../input/test1/test1\"))\n#constant value\nVALID_SPIT=0.2\nIMAGE_SIZE=224\nBATCH_SIZE=64\nCHANNEL_SIZE=3\nSHAPE = (IMAGE_SIZE, IMAGE_SIZE, CHANNEL_SIZE)\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3e294df9149462b2a0842d3297d4bd598cca0df9"},"cell_type":"code","source":"label=[]\ndata=[]\ncounter=0\npath=\"../input/train/train\"\nfor file in os.listdir(path):\n    data.append(os.path.join(path,file))\n    if file.startswith(\"cat\"):\n        label.append(0)\n    elif file.startswith(\"dog\"):\n        label.append(1)\n        \n    counter+=1\n    if counter%1000==0:\n        print (counter,\" image data retreived\")\n\ndata=np.array(data)\nlabel=np.array(label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"40e508ead2435aa8fab5aea457d5d8ffa776e76e"},"cell_type":"code","source":"img_dir=\"../input/train/train\"\nimg_list=os.listdir(img_dir)\nimg_size=IMAGE_SIZE\nsum_r=0\nsum_g=0\nsum_b=0\ncount=0\n\nfor img_name in img_list:\n    img_path=os.path.join(img_dir,img_name)\n    img=cv2.imread(img_path)\n    img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n    img=cv2.resize(img,(img_size,img_size))\n    sum_r=sum_r+img[:,:,0].mean()\n    sum_g=sum_g+img[:,:,1].mean()\n    sum_b=sum_b+img[:,:,2].mean()\n    count=count+1\n    if count%1000==0:\n        print (count,\" image data count\")\n        \nsum_r=sum_r/count\nsum_g=sum_g/count\nsum_b=sum_b/count\nimg_mean=[sum_r,sum_g,sum_b]\nprint (img_mean)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6d991bf9323f19239c0b35629002b222a573cb74"},"cell_type":"code","source":"img_mean = [124.40483277264002, 115.92854629783018, 106.20628246173563]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ea098e5ffd3cc7c0d6279e1459727dbb3ef6b342"},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_data, valid_data, train_label, valid_label = train_test_split(\n    data, label, test_size=0.2, random_state=42)\nprint(train_data.shape)\nprint(train_label.shape)\nprint(valid_data.shape)\nprint(valid_label.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"981bdd7ca7b65bf1a0fdd099a134dee10239caef"},"cell_type":"code","source":"import seaborn as sns\n\nsns.countplot(train_label)\npd.Series(train_label).value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1ae401c9cb665ea33c9fbb0a5db3ef986236b60c"},"cell_type":"code","source":"sns.countplot(valid_label)\npd.Series(valid_label).value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"867392a9c0369b44fe194e4f8b9e46f2d5191613"},"cell_type":"code","source":"import keras\nfrom keras import Sequential\nfrom keras.layers import *\nimport keras.optimizers as optimizers\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import *\nfrom keras.applications import *\nfrom keras import Model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a69fa850cdfa5bb06fc72d3e28724f25fc5027bd"},"cell_type":"code","source":"# credits: https://github.com/keras-team/keras/blob/master/keras/utils/data_utils.py#L302\n# credits: https://stanford.edu/~shervine/blog/keras-how-to-generate-data-on-the-fly\n\nclass CacheDataGenerator(keras.utils.Sequence):\n    def __init__(self, paths, labels, batch_size, shape, shuffle = False, use_cache = False, augment = False):\n        self.paths, self.labels = paths, labels\n        self.batch_size = batch_size\n        self.shape = shape\n        self.shuffle = shuffle\n        self.use_cache = use_cache\n        self.augment = augment\n        if use_cache == True:\n            self.cache = np.zeros((paths.shape[0], shape[0], shape[1], shape[2]), dtype=np.float16)\n            self.is_cached = np.zeros((paths.shape[0]))\n        self.on_epoch_end()\n    \n    def __len__(self):\n        return int(np.ceil(len(self.paths) / float(self.batch_size)))\n    \n    def __getitem__(self, idx):\n        indexes = self.indexes[idx * self.batch_size : (idx+1) * self.batch_size]\n\n        paths = self.paths[indexes]\n        X = np.zeros((paths.shape[0], self.shape[0], self.shape[1], self.shape[2]))\n        # Generate data\n        if self.use_cache == True:\n            X = self.cache[indexes]\n            for i, path in enumerate(paths[np.where(self.is_cached[indexes] == 0)]):\n                image = self.__load_image(path)\n                self.is_cached[indexes[i]] = 1\n                self.cache[indexes[i]] = image\n                X[i] = image\n        else:\n            for i, path in enumerate(paths):\n                X[i] = self.__load_image(path)\n\n        y = self.labels[indexes]\n                \n        if self.augment == True:\n            seq = iaa.Sequential([\n                iaa.OneOf([\n                    iaa.Fliplr(0.5), # horizontal flips\n                    iaa.Crop(percent=(0, 0.1)), # random crops\n                    # Small gaussian blur with random sigma between 0 and 0.5.\n                    # But we only blur about 50% of all images.\n                    iaa.Sometimes(0.5,\n                        iaa.GaussianBlur(sigma=(0, 0.5))\n                    ),\n                    # Strengthen or weaken the contrast in each image.\n                    iaa.ContrastNormalization((0.75, 1.5)),\n                    # Add gaussian noise.\n                    # For 50% of all images, we sample the noise once per pixel.\n                    # For the other 50% of all images, we sample the noise per pixel AND\n                    # channel. This can change the color (not only brightness) of the\n                    # pixels.\n                    iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05*255), per_channel=0.5),\n                    # Make some images brighter and some darker.\n                    # In 20% of all cases, we sample the multiplier once per channel,\n                    # which can end up changing the color of the images.\n                    iaa.Multiply((0.8, 1.2), per_channel=0.2),\n                    # Apply affine transformations to each image.\n                    # Scale/zoom them, translate/move them, rotate them and shear them.\n                    iaa.Affine(\n                        scale={\"x\": (0.8, 1.2), \"y\": (0.8, 1.2)},\n                        translate_percent={\"x\": (-0.2, 0.2), \"y\": (-0.2, 0.2)},\n                        rotate=(-180, 180),\n                        shear=(-8, 8)\n                    )\n                ])], random_order=True)\n\n            X = np.concatenate((X, seq.augment_images(X), seq.augment_images(X), seq.augment_images(X)), 0)\n            y = np.concatenate((y, y, y, y), 0)\n        \n        return X, y\n    \n    def on_epoch_end(self):\n        \n        # Updates indexes after each epoch\n        self.indexes = np.arange(len(self.paths))\n        if self.shuffle == True:\n            np.random.shuffle(self.indexes)\n\n    def __iter__(self):\n        \"\"\"Create a generator that iterate over the Sequence.\"\"\"\n        for item in (self[i] for i in range(len(self))):\n            yield item\n            \n    def __load_image(self, path):\n        im = np.array(Image.open(path))\n        im = cv2.resize(im, (SHAPE[0], SHAPE[1]))\n        \n        #for dim in range(3):\n        #    im[:,:,dim] = im[:,:,dim] - img_mean[dim] \n        #im = np.divide(im, 255)\n        return im","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0a3be3c49cf57fa01140530665da92292fadc49e"},"cell_type":"code","source":"base_model = resnet50.ResNet50(input_shape=(IMAGE_SIZE, IMAGE_SIZE, CHANNEL_SIZE),\n                                           include_top=False, pooling='avg')\n\nx = base_model.output\nx = Dropout(0.5)(x)\nx = Dense(100, activation='relu')(x)\nx = Dropout(0.5)(x)\npredictions = Dense(1, activation='sigmoid')(x)\n\nmodel = Model(inputs=base_model.input, outputs=predictions)\n\nfor layer in base_model.layers:\n    layer.trainable = False\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b44aaffee17347bc0529085ea0ab593c3f650e71"},"cell_type":"code","source":"#optimizers.SGD(lr=1e-3, momentum=0.9)\nmodel.compile(optimizer='adam',loss=\"binary_crossentropy\",metrics=[\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"08d548c83ab9cdf1fe8db71b318214ec4688d602"},"cell_type":"code","source":"train_generator = CacheDataGenerator(train_data, train_label, BATCH_SIZE, SHAPE, use_cache=True, augment = False, shuffle = False)\nvalid_generator = CacheDataGenerator(valid_data, valid_label, BATCH_SIZE, SHAPE, use_cache=True, shuffle = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d67b5ed70c7ad2042ad51bfcf0b1fd27773741b0"},"cell_type":"code","source":"callack_saver = ModelCheckpoint(\n            \"model.h5\"\n            , monitor='val_acc'\n            , verbose=0\n            , save_weights_only=True\n            , mode='auto'\n            , save_best_only=True\n        )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cdca602d510f098ae5ddfd32b77a2e49850dc414"},"cell_type":"code","source":"train_history=model.fit_generator(\n        train_generator,\n        steps_per_epoch=len(train_generator),\n        epochs=2,\n        validation_data=valid_generator,\n        validation_steps=len(valid_generator),\n        callbacks=[callack_saver])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2bc8dfafb99e4ecabe460e460af27650cbdc27fa"},"cell_type":"code","source":"for layer in base_model.layers:\n    layer.trainable = True\nmodel.summary()\n\nopt_sgd = optimizers.SGD(lr=1e-4, momentum=0.9)\nmodel.compile(optimizer=opt_sgd,loss=\"binary_crossentropy\",metrics=[\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a1e1d62fbff933e9a512fc8b80749d3508e5a27e"},"cell_type":"code","source":"train_history=model.fit_generator(\n        train_generator,\n        steps_per_epoch=100,#len(train_generator),\n        epochs=10,\n        validation_data=valid_generator,\n        validation_steps=len(valid_generator),\n        callbacks=[callack_saver])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3423f3404655ad90c8ad8a5798053c55afa7da48"},"cell_type":"code","source":"def show_train_history(train_history, train, validation):\n    plt.plot(train_history.history[train])\n    plt.plot(train_history.history[validation])\n    plt.title('Train History')\n    plt.ylabel(train)\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"80f470fff03ab59fb97c4d681c14fd7893438d05"},"cell_type":"code","source":"show_train_history(train_history, 'loss', 'val_loss')\nshow_train_history(train_history, 'acc', 'val_acc')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"275ee24fffaa7152e4ddb9f66b8bcbedd40a8617","_kg_hide-output":true},"cell_type":"code","source":"test_datagen = ImageDataGenerator()\n\ntest_generator = test_datagen.flow_from_directory(\n            \"../input/test1\"\n            , target_size=(IMAGE_SIZE, IMAGE_SIZE)\n            , batch_size=100\n            , shuffle=False\n        )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8d1e188744e90d0cdad53469322375153e75e040"},"cell_type":"code","source":"predicted_labels=model.predict_generator(test_generator, steps=125)\npredicted_labels=np.round(predicted_labels,decimals=2)\nlabels=[1 if value>0.5 else 0 for value in predicted_labels]\n\n#print(len(labels))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d072c5357840cca7b4846dd2786da2f751766b85"},"cell_type":"code","source":"id=[os.path.splitext(os.path.basename(filename))[0] for filename in test_generator.filenames]\ndataframe_output=pd.DataFrame({\"id\":id})\ndataframe_output[\"label\"]=labels\nprint(dataframe_output)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5be17382af31459070c165811e1e54f87675d18f"},"cell_type":"code","source":"dataframe_output.to_csv(\"submission.csv\",index=False)","execution_count":null,"outputs":[]}],"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}