{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Dogs vs. Cats Keras CNN\nhttps://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition"},{"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)\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 all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nfrom tensorflow import keras\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.applications.vgg16 import VGG16\nfrom tensorflow.keras.applications.vgg16 import preprocess_input\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_SIZE = (224, 224)  # размер входного изображения сети","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import re\nfrom random import shuffle\nfrom glob import glob\n\ntrain_files = glob('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train/*.jpg')\ntest_files = glob('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test/*.jpg')\n\n# загружаем входное изображение и предобрабатываем\ndef load_image(path, target_size=IMG_SIZE):\n    img = load_img(path, target_size=target_size)  # загрузка и масштабирование изображения\n    array = img_to_array(img)\n    return preprocess_input(array)  # предобработка для VGG16\n\n# генератор для последовательного чтения обучающих данных с диска\ndef fit_generator(files, batch_size=32):\n    while True:\n        shuffle(files)\n        for k in range(len(files) // batch_size):\n            i = k * batch_size\n            j = i + batch_size\n            if j > len(files):\n                j = - j % len(files)\n            x = np.array([load_image(path) for path in files[i:j]])\n            y = np.array([1. if re.match('.*/dog\\.\\d', path) else 0. for path in files[i:j]])\n            yield (x, y)\n\n# генератор последовательного чтения тестовых данных с диска\ndef predict_generator(files):\n    while True:\n        for path in files:\n            yield np.array([load_image(path)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\nfrom matplotlib import pyplot as plt\nfig = plt.figure(figsize=(20, 20))\nfor i, path in enumerate(train_files[:10], 1):\n    subplot = fig.add_subplot(i // 5 + 1, 5, i)\n    plt.imshow(plt.imread(path));\n    subplot.set_title('%s' % path.split('/')[-1]);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### load pretrained model"},{"metadata":{"trusted":true},"cell_type":"code","source":"# base_model -  объект класса keras.models.Model (Functional Model)\nbase_model = VGG16(include_top = False,\n                   weights = 'imagenet',\n                   input_shape = (IMG_SIZE[0], IMG_SIZE[1], 3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# фиксируем все веса предобученной сети\nfor layer in base_model.layers:\n    layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base_model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Add some layers"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = base_model.layers[-5].output\nx = keras.layers.Flatten()(x)\nx = keras.layers.Dense(512, activation='relu')(x)\nx = keras.layers.BatchNormalization()(x)\nx = keras.layers.Dense(64, activation='relu')(x)\nx = keras.layers.BatchNormalization()(x)\nx = keras.layers.Dense(1,  # один выход\n                        activation='sigmoid',  # функция активации  \n                        kernel_regularizer=keras.regularizers.l1(1e-4)\n                                   #keras.regularizers.l1_l2(l1=1e-4, l2=1e-5)\n                      )(x)\nmodel = Model(inputs=base_model.input, outputs=x)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Check summary"},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer='adam', \n              loss='binary_crossentropy',  # функция потерь binary_crossentropy (log loss\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"shuffle(train_files)  # перемешиваем обучающую выборку\n\ntrain_val_split = 100  # число изображений в валидационной выборке\n\nvalidation_data = next(fit_generator(train_files[:train_val_split], train_val_split))\n\n# запускаем процесс обучения\nhistory = model.fit_generator(fit_generator(train_files[train_val_split:]),  # данные читаем функцией-генератором\n        steps_per_epoch=10,  # число вызовов генератора за эпоху\n        epochs=100,  # число эпох обучения\n        validation_data=validation_data\n        #,callbacks=[keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)]\n        )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n# Plot training & validation accuracy values\nplt.plot(history.history['acc'])\nplt.plot(history.history['val_acc'])\nplt.title('Model accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()\n\n# Plot training & validation loss values\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save('cats-dogs-vgg16.hdf5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = model.predict_generator(predict_generator(test_files), len(test_files), max_queue_size=500)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\nfrom matplotlib import pyplot as plt\nfig = plt.figure(figsize=(20, 20))\nfor i, (path, score) in enumerate(zip(test_files[80:][:10], pred[80:][:10]), 1):\n    subplot = fig.add_subplot(i // 5 + 1, 5, i)\n    plt.imshow(plt.imread(path));\n    subplot.set_title('%.3f' % score);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('submit.txt', 'w') as dst:\n    dst.write('id,label\\n')\n    for path, score in zip(test_files, pred):\n        dst.write('%s,%f\\n' % (re.search('(\\d+)', path).group(0), score))","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":1}