327 lines
8.9 KiB
Plaintext
327 lines
8.9 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Dogs vs. Cats"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"from tensorflow import keras\n",
|
||
"from tensorflow.keras.models import Model\n",
|
||
"from tensorflow.keras.applications.vgg16 import VGG16\n",
|
||
"from tensorflow.keras.applications.vgg16 import preprocess_input\n",
|
||
"from tensorflow.keras.preprocessing.image import load_img, img_to_array"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"IMG_SIZE = (224, 224) # размер входного изображения сети"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Функции загрузки данных"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"<>:24: SyntaxWarning: invalid escape sequence '\\.'\n",
|
||
"<>:24: SyntaxWarning: invalid escape sequence '\\.'\n",
|
||
"C:\\Users\\dimae\\AppData\\Local\\Temp\\ipykernel_8920\\2072963477.py:24: SyntaxWarning: invalid escape sequence '\\.'\n",
|
||
" y = np.array([1. if re.match('.*/dog\\.\\d', path) else 0. for path in files[i:j]])\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import re\n",
|
||
"from random import shuffle\n",
|
||
"from glob import glob\n",
|
||
"\n",
|
||
"train_files = glob('../input/train/*.jpg')\n",
|
||
"test_files = glob('../input/test/*.jpg')\n",
|
||
"\n",
|
||
"# загружаем входное изображение и предобрабатываем\n",
|
||
"def 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",
|
||
"# генератор для последовательного чтения обучающих данных с диска\n",
|
||
"def 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",
|
||
"# генератор последовательного чтения тестовых данных с диска\n",
|
||
"def predict_generator(files):\n",
|
||
" while True:\n",
|
||
" for path in files:\n",
|
||
" yield np.array([load_image(path)])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Визуализируем примеры для обучения"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%matplotlib inline\n",
|
||
"from matplotlib import pyplot as plt\n",
|
||
"fig = plt.figure(figsize=(20, 20))\n",
|
||
"for 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]);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Загружаем предобученную модель"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# base_model - объект класса keras.models.Model (Functional Model)\n",
|
||
"base_model = VGG16(include_top = False,\n",
|
||
" weights = 'imagenet',\n",
|
||
" input_shape = (IMG_SIZE[0], IMG_SIZE[1], 3))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# фиксируем все веса предобученной сети\n",
|
||
"for layer in base_model.layers:\n",
|
||
" layer.trainable = False"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"base_model.summary()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Добавляем полносвязный слой"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = base_model.layers[-5].output\n",
|
||
"x = keras.layers.Flatten()(x)\n",
|
||
"x = keras.layers.Dense(1, # один выход\n",
|
||
" activation='sigmoid', # функция активации \n",
|
||
" kernel_regularizer=keras.regularizers.l1(1e-4))(x)\n",
|
||
"model = Model(inputs=base_model.input, outputs=x)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Выводим архитектуру модели"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"model.summary()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Компилируем модель и запускаем обучение"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"model.compile(optimizer='adam', \n",
|
||
" loss='binary_crossentropy', # функция потерь binary_crossentropy (log loss\n",
|
||
" metrics=['accuracy'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"shuffle(train_files) # перемешиваем обучающую выборку\n",
|
||
"\n",
|
||
"train_val_split = 100 # число изображений в валидационной выборке\n",
|
||
"\n",
|
||
"validation_data = next(fit_generator(train_files[:train_val_split], train_val_split))\n",
|
||
"\n",
|
||
"# запускаем процесс обучения\n",
|
||
"model.fit_generator(fit_generator(train_files[train_val_split:]), # данные читаем функцией-генератором\n",
|
||
" steps_per_epoch=10, # число вызовов генератора за эпоху\n",
|
||
" epochs=100, # число эпох обучения\n",
|
||
" validation_data=validation_data)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"model.save('cats-dogs-vgg16.hdf5')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Предсказания на проверочной выборке"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"pred = model.predict_generator(predict_generator(test_files), len(test_files), max_queue_size=500)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%matplotlib inline\n",
|
||
"from matplotlib import pyplot as plt\n",
|
||
"fig = plt.figure(figsize=(20, 20))\n",
|
||
"for 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);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Готовим данные для сабмита"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"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))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# LogLoss = 1.04979"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.12.4"
|
||
},
|
||
"widgets": {
|
||
"state": {},
|
||
"version": "1.1.2"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
}
|