{"cells":[{"metadata":{"_uuid":"d48aa416989aae68bdbc7181cfaab2c245de91d3"},"cell_type":"markdown","source":"# Dogs vs. Cats"},{"metadata":{"trusted":true,"_uuid":"3d00341c4dfc7609202ed272880f45c3bd359a85"},"cell_type":"code","source":"#~/.keras/models","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9c2965c74f694cdeab4f5975f9d1770f8a2fa321"},"cell_type":"markdown","source":"https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition"},{"metadata":{"trusted":true,"_uuid":"98f7ebf01d158828b2451d3b4446ade33af44219"},"cell_type":"code","source":"import numpy as np\nimport keras\nfrom keras.models import Model\nfrom keras.applications.vgg16 import VGG16\nfrom keras.applications.vgg16 import preprocess_input\nfrom keras.preprocessing.image import load_img, img_to_array","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7844b6ce9b9581ae9ac6f7e23bd01ba05e013714"},"cell_type":"code","source":"IMG_SIZE = (224, 224)  # размер входного изображения сети","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"af93d2ff9e4797e85c1c2f8b0c0114460cf34743"},"cell_type":"markdown","source":"## Функции загрузки данных"},{"metadata":{"trusted":true,"_uuid":"c3e634c03c2bbcf7288bfdf598041af959068b83"},"cell_type":"code","source":"import re\nfrom random import shuffle\nfrom glob import glob\n\ntrain_files = glob('../input/train/*.jpg')\ntest_files = glob('../input/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":{"_uuid":"cc9b65b9186d8da22d156ad593be68e4b0c21c67"},"cell_type":"markdown","source":"## Визуализируем примеры для обучения"},{"metadata":{"trusted":true,"_uuid":"f6ffa3307955bc05d2e1734c024fbcda7d26dde4"},"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":{"_uuid":"6921a86a9df70f9758512f40b5441584d2a1922b"},"cell_type":"markdown","source":"## Загружаем предобученную модель"},{"metadata":{"trusted":true,"_uuid":"87470554ee11675e501539b28687098fe32a025e"},"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,"_uuid":"17167988e1bf94b0263e7543e9297f4008991fd2"},"cell_type":"code","source":"# фиксируем все веса предобученной сети\nfor layer in base_model.layers:\n    layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c4ccceb99d2acdc3fe67a55fec1b88bd7c84a239"},"cell_type":"code","source":"#base_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ffc3b01992a83347f4d65cf7fb7c91dd27a4ffff"},"cell_type":"markdown","source":"## Добавляем полносвязный слой"},{"metadata":{"trusted":true,"_uuid":"3120855f19225f3d1b516b794a10caa6962b40b4"},"cell_type":"code","source":"x = base_model.layers[-5].output\nx = keras.layers.Flatten()(x)\nx = keras.layers.Dense(256, activation='relu')(x)\nx = keras.layers.normalization.BatchNormalization(axis=1)(x)\nx = keras.layers.Dropout(0.5)(x)\nx = keras.layers.Dense(256, activation='relu')(x)\nx = keras.layers.normalization.BatchNormalization(axis=1)(x)\nx = keras.layers.Dropout(0.5)(x)\nx = keras.layers.Dense(1,  # один выход\n                activation='sigmoid',  # функция активации  \n                kernel_regularizer=keras.regularizers.l1(1e-4))(x)\nmodel = Model(inputs=base_model.input, outputs=x)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c566572a8af11e31699b8aa0744c3b346658cfe4"},"cell_type":"markdown","source":"## Выводим архитектуру модели"},{"metadata":{"trusted":true,"_uuid":"cbfcbb5b314654fa6b99a3450245b464834ba3d7"},"cell_type":"code","source":"#model.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b2ec4f4850e6bc5060c6ce77fcdc3e211e3481a1"},"cell_type":"markdown","source":"## Компилируем модель и запускаем обучение"},{"metadata":{"trusted":true,"_uuid":"5864915afb11dd82f5d8895573b6361b283ec193"},"cell_type":"code","source":"model.compile(optimizer='adam', \n              loss='binary_crossentropy',  # функция потерь binary_crossentropy (log loss\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"trusted":true,"_uuid":"c71777f78138c6f1a39652f74c6b720a2f03b0bf"},"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# запускаем процесс обучения\nmodel.fit_generator(fit_generator(train_files[train_val_split:]),  # данные читаем функцией-генератором\n        steps_per_epoch=10,  # число вызовов генератора за эпоху\n        epochs=100,  # число эпох обучения\n        validation_data=validation_data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2f956809753809ec7a54c6c4fea9fed7d62a4d76"},"cell_type":"code","source":"#model.save('cats-vs-dogs_vgg-16.hdf5')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ef1c1ad5c68c70880c3e584e73e53a53d05abbca"},"cell_type":"markdown","source":"## Предсказания на проверочной выборке"},{"metadata":{"trusted":true,"_uuid":"747836bf3efc56b4d02c0d52685155ea81744c6c"},"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,"_uuid":"d1e977e394ce658d353464d8e5aa3eb110b8ed9d"},"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":{"_uuid":"902e6604b3d8ef922aaf055f4b5ef5b0d4a0ba52"},"cell_type":"markdown","source":"## Готовим данные для сабмита"},{"metadata":{"trusted":true,"_uuid":"da90810b53eace52d9adfd6a5fb88da3c383950c","_kg_hide-output":false,"_kg_hide-input":false},"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":{"trusted":true,"_uuid":"80d26c5b6690a1743acfc760b4ccfc0630cbc50e"},"cell_type":"code","source":"#","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"e4e1575df3f395de035ec2475d407e0003cc000a"},"cell_type":"code","source":"# LogLoss = 1.04979","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"},"widgets":{"state":{},"version":"1.1.2"}},"nbformat":4,"nbformat_minor":1}