{"cells":[{"metadata":{"_uuid":"85c59f1397cf759384520c3388db5cb50b0d4dd7"},"cell_type":"markdown","source":"# Dogs vs. Cats"},{"metadata":{"_uuid":"85f475ac51d628b64a394b0579e0205f0b2ccc4a"},"cell_type":"markdown","source":"https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition"},{"metadata":{"trusted":true,"_uuid":"30c7085b3ec08a6dcdd684f8538091b484312529","collapsed":true},"cell_type":"code","source":"import os\nimport numpy as np\nimport keras\nfrom keras.models import Model\nfrom keras.applications.mobilenet import MobileNet\nfrom keras.applications.mobilenet import preprocess_input\nfrom keras.preprocessing.image import load_img, img_to_array\nfrom keras.callbacks import LearningRateScheduler, ModelCheckpoint","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"217c1eb055a7402fcce5cc4c58d3792720f35e45","collapsed":true},"cell_type":"code","source":"TRAIN_DIR = '../input/train/'\nTEST_DIR = '../input/test/'\n\ntrain_files = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)] \ntest_files = [TEST_DIR+i for i in os.listdir(TEST_DIR)] ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e02405d519dda8f3fa6f0b484107c30d2d6a0138"},"cell_type":"markdown","source":"## Функции загрузки данных"},{"metadata":{"trusted":true,"_uuid":"6a37200b8d7c5186a95243bb850c5a242fb3d1f7","collapsed":true},"cell_type":"code","source":"import re\nfrom random import shuffle\nfrom glob import glob\n\nIMG_SIZE = (224, 224)  # размер входного изображения сети\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":"eb169c72a3020f86c107f474bb7c00053fc405e3"},"cell_type":"markdown","source":"## Визуализируем примеры для обучения"},{"metadata":{"trusted":true,"_uuid":"e0917aa7de0670d7e3bd576e4315f94c8ae81b12","collapsed":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]);\n      ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5bbc6123c8d2631a7560d29ea76b784e09c744b0"},"cell_type":"markdown","source":"## Загружаем предобученную модель"},{"metadata":{"trusted":true,"_uuid":"975398bb1d7b127fd6913dec06394efb9e39bec2","collapsed":true},"cell_type":"code","source":"# base_model -  объект класса keras.models.Model (Functional Model)\nbase_model = MobileNet(include_top = False,\n                   weights = 'imagenet',\n                   input_shape = (IMG_SIZE[0], IMG_SIZE[1], 3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"06901dc13da96443e432010aad615836f9c39baa","collapsed":true},"cell_type":"code","source":"# фиксируем все веса предобученной сети\nfor layer in base_model.layers:\n    layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b44577b3c985fd9390c447c3c3c9dbbd1466f1be","scrolled":false,"collapsed":true},"cell_type":"code","source":"base_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b6ab9c6aa9979441191c7800cb1b8171dca952b5"},"cell_type":"markdown","source":"## Добавляем полносвязный слой"},{"metadata":{"trusted":true,"_uuid":"883cd4cd1894f0692486067741fe901bd4f49578","collapsed":true},"cell_type":"code","source":"reg = 1e-7\n\nx = base_model.layers[-1].output\nx = keras.layers.Flatten()(x)\nx = keras.layers.Dense(128, activation='relu',\n                       kernel_regularizer=keras.regularizers.l2(reg))(x)\nx = keras.layers.Dropout(rate=0.2)(x)\nx = keras.layers.Dense(1,  # один выход\n                activation='sigmoid',  # функция активации  \n                kernel_regularizer=keras.regularizers.l1(1e-7))(x)\nmodel = Model(inputs=base_model.input, outputs=x)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3256c831a8cd9a112022db2f9fac6a7fc3bc3809"},"cell_type":"markdown","source":"## Выводим архитектуру модели"},{"metadata":{"trusted":true,"_uuid":"bd2654b44bc0e8830c466a237618d5ffdb3f6855","collapsed":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c6a26bc5026f3a529e4b70206518899874d69a99"},"cell_type":"markdown","source":"## Компилируем модель и запускаем обучение"},{"metadata":{"trusted":true,"_uuid":"59bc9b02b97eb4901134c3435fc41b9f7681550d","collapsed":true},"cell_type":"code","source":"epochs = 30\n\ndef step_decay(epoch):\n    lr = 0.000005\n    step = 12\n    return lr/10**int(epoch/step)\n\nlrate = LearningRateScheduler(step_decay)\ncheckpointer = ModelCheckpoint(filepath=\"weights1.hdf5\", verbose=1, save_best_only=True)\n\ncallbacks_list = [lrate, checkpointer]\n\nopt = keras.optimizers.Adam()#, decay=decay_rate)\nmodel.compile(optimizer=opt, \n              loss='binary_crossentropy', \n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"trusted":true,"_uuid":"809605eb98e708aa3b7ee91b1393e6bc1bb82027","collapsed":true},"cell_type":"code","source":"shuffle(train_files)  # перемешиваем обучающую выборку\n\ntrain_val_split = 4000  # число изображений в валидационной выборке\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=150,  # число вызовов генератора за эпоху\n        epochs=epochs,  # число эпох обучения\n        validation_data=validation_data, callbacks=callbacks_list)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e938a18c061926286f53dd9366c5ee667f80ea0f"},"cell_type":"markdown","source":"## Предсказания на проверочной выборке"},{"metadata":{"trusted":true,"_uuid":"4ff3e6613439f8fc96c9b4b2cab0f0fb1cc67b1e","scrolled":true,"collapsed":true},"cell_type":"code","source":"from sklearn.metrics import log_loss\n\n#model.load_weights('weights1.hdf5')\n#pr = model.predict(validation_data[0])\n#print(log_loss(validation_data[1] , np.clip(pr, 0.00001, 0.9999)))\n\npred_ = model.predict_generator(predict_generator(test_files), len(test_files), max_queue_size=500)\npred = np.clip(pred_, 0.0000001, 0.9999999)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5be65aa067d6dd914045737d5f6b75484783de8b","collapsed":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:][15:25], pred[80:][15:25]), 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":"e0df13fdeef7dffdbaa301ef96d5ba171d11c3ad"},"cell_type":"markdown","source":"## Готовим данные для сабмита"},{"metadata":{"trusted":true,"_uuid":"ad8314a0225ff5aacb1222d573069e522efd5bfe","collapsed":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":{"trusted":true,"_uuid":"ef40380ba12c3794262295a214756c3595f57ae3","collapsed":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"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"},"widgets":{"state":{},"version":"1.1.2"}},"nbformat":4,"nbformat_minor":1}