{"cells":[{"metadata":{},"cell_type":"markdown","source":" # **Preparing directories / Splitting data**"},{"metadata":{"trusted":true},"cell_type":"code","source":"import zipfile\n\n\nzip_files = ['test1', 'train']\n# Will unzip the files so that you can see them..\nfor zip_file in zip_files:\n    with zipfile.ZipFile(\"../input/dogs-vs-cats/{}.zip\".format(zip_file),\"r\") as z:\n        z.extractall(\".\")\n        print(\"{} unzipped\".format(zip_file))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport pandas as pd\n\nfilenames = os.listdir(\"/kaggle/working/train\")\ncategories = []\nfor filename in filenames:\n    category = filename.split('.')[0]\n    if category == 'dog':\n        categories.append(1)\n    else:\n        categories.append(0)\n\ndf = pd.DataFrame({\n    'filename': filenames,\n    'category': categories\n})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_valid, y_train, y_valid = train_test_split(df['filename'], df['category'], test_size=0.20)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import shutil\n\ncurrent_dir = os.path.abspath(os.getcwd())\ntraining_dir = os.path.join(current_dir, \"training\")\nos.mkdir(training_dir)\ncats_dir = os.path.join(training_dir, \"cats\")\ndogs_dir = os.path.join(training_dir, \"dogs\")\nos.mkdir(cats_dir)\nos.mkdir(dogs_dir)\n\nfor i in range(len(X_train)):\n    filename = X_train.iloc[i]\n    folder = cats_dir if y_train.iloc[i] == 0 else dogs_dir\n    dst = os.path.join(folder,filename)\n    os.rename(\"/kaggle/working/train/{}\".format(filename), dst)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_dir = training_dir = os.path.join(current_dir, \"validation\")\nos.mkdir(validation_dir)\ncats_dir_v = os.path.join(validation_dir, \"cats\")\ndogs_dir_v = os.path.join(validation_dir, \"dogs\")\nos.mkdir(cats_dir_v)\nos.mkdir(dogs_dir_v)\n\nfor i in range(len(X_valid)):\n    filename = X_valid.iloc[i]\n    folder = cats_dir_v if y_valid.iloc[i] == 0 else dogs_dir_v\n    dst = os.path.join(folder,filename)\n    os.rename(\"/kaggle/working/train/{}\".format(filename), dst)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"shutil.rmtree(\"train\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Model**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import layers \nfrom keras import models\nfrom keras import optimizers \n\nmodel = models.Sequential() \nmodel.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) \nmodel.add(layers.MaxPooling2D((2, 2))) \nmodel.add(layers.Conv2D(64, (3, 3), activation='relu')) \nmodel.add(layers.MaxPooling2D((2, 2))) \nmodel.add(layers.Conv2D(128, (3, 3), activation='relu')) \nmodel.add(layers.MaxPooling2D((2, 2))) \nmodel.add(layers.Conv2D(128, (3, 3), activation='relu')) \nmodel.add(layers.MaxPooling2D((2, 2))) \nmodel.add(layers.Flatten()) \nmodel.add(layers.Dropout(0.5)) \nmodel.add(layers.Dense(512, activation='relu')) \nmodel.add(layers.Dense(1, activation='sigmoid'))\nmodel.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc'])\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Data pre-processing steps**\n1.  Read the picture files. \n2. Decode the JPEG content to RGB grids of pixels. \n3. Convert these into floating-point tensors. \n4. Rescale the pixel values (between 0 and 255) to the [0, 1] interval (neural networks prefer to deal with small input values)"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ntrain_datagen = ImageDataGenerator(rescale=1./255) \ntest_datagen = ImageDataGenerator(rescale=1./255)\ntrain_generator = train_datagen.flow_from_directory( training_dir, target_size=(150, 150),batch_size=20, class_mode='binary')\nvalidation_generator = test_datagen.flow_from_directory( validation_dir,target_size=(150, 150), batch_size=20, class_mode='binary')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"***ImageGenerator***\n\nfit_generator method, the equivalent of fit for data generators like this one. It expects as its first argument a Python generator that will yield batches of inputs and targets indefinitely. Because the data is being generated endlessly, the Keras model needs to know how many samples to draw from the generator before declaring an epoch over. \n\nThis is the role of the steps_per_epoch argument: after having drawn **steps_per_epoch** batches from the generator—that is, after having run for **steps_per_epoch** gradient descent steps—the fitting process will go to the next epoch. \nIn this case, batches are 20 samples, so it will take 100 batches until you see your target of 2,000 samples.\n\nWhen using **fit_generator**, you can pass a **validation_data** argument, much as with the fit method. It’s important to note that this argument is allowed to be a *data generator*, but it could also be a *tuple of Numpy arrays*. \n \n !!! If you pass a generator as validation_data, then this generator is expected to yield batches of validation data *endlessly*; thus you should also specify the **validation_steps** argument, which tells the process how many batches to draw from the validation generator for evaluation."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator( rescale=1./255, rotation_range=40, width_shift_range=0.2, \n                                   height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True,)\ntest_datagen = ImageDataGenerator(rescale=1./255) #validation data shouldn't be augmented!!!\ntrain_generator = train_datagen.flow_from_directory( training_dir, target_size=(150, 150), batch_size=32, class_mode='binary') \n#Because you use binary_crossentropy loss, you need binary labels.\nvalidation_generator = test_datagen.flow_from_directory( validation_dir, target_size=(150, 150), batch_size=32, class_mode='binary')\nhistory = model.fit_generator( train_generator, steps_per_epoch=100, epochs=100, validation_data=validation_generator, validation_steps=50)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save_weights(\"model.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dir = os.path.join(current_dir, 'test1')\ntest_gen = ImageDataGenerator(rescale=1./255)\ntest_filenames = os.listdir(test_dir)\ndst_dir = os.path.join(test_dir,'sub')\nos.mkdir(dst_dir)\n#flowfromdirectory treats the sub-folder as the label of the images it contains. So it only search images in sub-folders.\nfor filename in test_filenames:\n    dst = os.path.join(dst_dir,filename)\n    src = os.path.join(test_dir,filename)\n    os.rename(src, dst)\n\n\ntest_generator = test_gen.flow_from_directory(directory=test_dir, target_size=(150, 150), batch_size=32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predict = model.predict_generator(test_generator, 100)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = test_df.copy()\nsubmission_df['id'] = submission_df['filename'].str.split('.').str[0]\nsubmission_df['label'] = pd.DataFrame(predict)\nsubmission_df.drop(['filename'], axis=1, inplace=True)\nsubmission_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}