{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import zipfile\nimport os\nfrom keras.preprocessing import image\nfrom keras.applications.imagenet_utils import preprocess_input\nimport keras\nimport numpy as np\nimport copy","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:21:03.768749Z","iopub.execute_input":"2021-06-06T08:21:03.769116Z","iopub.status.idle":"2021-06-06T08:21:03.776296Z","shell.execute_reply.started":"2021-06-06T08:21:03.769081Z","shell.execute_reply":"2021-06-06T08:21:03.775334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# распаковка архивов\nzip = zipfile.ZipFile('/kaggle/input/dogs-vs-cats/train.zip', 'r')\nzip.extractall(\"/kaggle/working/train_extracted\")","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:13:38.933505Z","iopub.execute_input":"2021-06-06T08:13:38.933856Z","iopub.status.idle":"2021-06-06T08:13:50.109784Z","shell.execute_reply.started":"2021-06-06T08:13:38.933825Z","shell.execute_reply":"2021-06-06T08:13:50.108926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"zip = zipfile.ZipFile('/kaggle/input/dogs-vs-cats/test1.zip', 'r')\nzip.extractall(\"/kaggle/working/test_extracted\")","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:13:52.119482Z","iopub.execute_input":"2021-06-06T08:13:52.119831Z","iopub.status.idle":"2021-06-06T08:13:56.991768Z","shell.execute_reply.started":"2021-06-06T08:13:52.119800Z","shell.execute_reply":"2021-06-06T08:13:56.990901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# функция для представления картинки в нужном формате\ndef get_image(path):\n    img = image.load_img(path, target_size=(224, 224))\n    x = image.img_to_array(img)\n    x = np.expand_dims(x, axis=0)\n    x = preprocess_input(x)\n    return img, x   ","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:14:05.827746Z","iopub.execute_input":"2021-06-06T08:14:05.828307Z","iopub.status.idle":"2021-06-06T08:14:05.854525Z","shell.execute_reply.started":"2021-06-06T08:14:05.828236Z","shell.execute_reply":"2021-06-06T08:14:05.843198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# получаем имена всех файлов\nwalk = os.walk(\"/kaggle/working/train_extracted\")\nfor f in walk:\n   filenames = f[2]\nfilenames[:10]","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:14:08.796592Z","iopub.execute_input":"2021-06-06T08:14:08.796919Z","iopub.status.idle":"2021-06-06T08:14:08.844768Z","shell.execute_reply.started":"2021-06-06T08:14:08.796889Z","shell.execute_reply":"2021-06-06T08:14:08.843388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(filenames)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T11:34:51.656331Z","iopub.execute_input":"2021-06-06T11:34:51.656654Z","iopub.status.idle":"2021-06-06T11:34:51.664248Z","shell.execute_reply.started":"2021-06-06T11:34:51.656623Z","shell.execute_reply":"2021-06-06T11:34:51.663209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# важные настройки для обучения\ncategory_encoding = {\"cat\": 0, \"dog\": 1}","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:14:17.905184Z","iopub.execute_input":"2021-06-06T08:14:17.905508Z","iopub.status.idle":"2021-06-06T08:14:17.909142Z","shell.execute_reply.started":"2021-06-06T08:14:17.905478Z","shell.execute_reply":"2021-06-06T08:14:17.908343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# разделяем имена файлов с котиками и пёсиками\ncategories = {\"cat\": [], \"dog\": []}\nfor filename in filenames:\n    if \"cat\" in filename:\n        categories[\"cat\"].append(filename)\n    else:\n        categories[\"dog\"].append(filename)\n        \nprint(len(categories[\"cat\"]), len(categories[\"dog\"]))","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:26:13.045861Z","iopub.execute_input":"2021-06-06T08:26:13.046214Z","iopub.status.idle":"2021-06-06T08:26:13.059919Z","shell.execute_reply.started":"2021-06-06T08:26:13.046180Z","shell.execute_reply":"2021-06-06T08:26:13.056470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# перемешиваем\nnp.random.shuffle(categories[\"cat\"])\nnp.random.shuffle(categories[\"dog\"])","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:26:23.909788Z","iopub.execute_input":"2021-06-06T08:26:23.910158Z","iopub.status.idle":"2021-06-06T08:26:23.918781Z","shell.execute_reply.started":"2021-06-06T08:26:23.910124Z","shell.execute_reply":"2021-06-06T08:26:23.917869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# соединяем по 500 картинок для обучающей выборки\nwork_filenames = copy.copy(categories[\"cat\"][:500])\nwork_filenames.extend(categories[\"dog\"][:500])\nnp.random.shuffle(work_filenames)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:26:25.964947Z","iopub.execute_input":"2021-06-06T08:26:25.965297Z","iopub.status.idle":"2021-06-06T08:26:25.970098Z","shell.execute_reply.started":"2021-06-06T08:26:25.965266Z","shell.execute_reply":"2021-06-06T08:26:25.968871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# таким же образом получаем и тестовую выборку\ntest_filenames = copy.copy(categories[\"cat\"][500:1500])\ntest_filenames.extend(categories[\"dog\"][500:1500])\nnp.random.shuffle(test_filenames)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T10:33:17.114556Z","iopub.execute_input":"2021-06-06T10:33:17.114929Z","iopub.status.idle":"2021-06-06T10:33:17.121335Z","shell.execute_reply.started":"2021-06-06T10:33:17.114897Z","shell.execute_reply":"2021-06-06T10:33:17.120464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# получаем непосредственно тренировочную выборку\ndata = []\nanswers = []\nfor filename in work_filenames:\n    data.append(get_image(\"/kaggle/working/train_extracted/train/\" + filename)[1][0])\n    answers.append(np.array(category_encoding[filename.split(\".\")[0]]))\n\ndata = np.array(data).astype('float32')\nanswers = np.array(answers)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T08:49:01.584823Z","iopub.execute_input":"2021-06-06T08:49:01.585165Z","iopub.status.idle":"2021-06-06T08:49:04.800814Z","shell.execute_reply.started":"2021-06-06T08:49:01.585131Z","shell.execute_reply":"2021-06-06T08:49:04.799926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# то же самое и для теста\ntest_data = []\ntest_answers = []\nfor filename in test_filenames:\n    test_data.append(get_image(\"/kaggle/working/train_extracted/train/\" + filename)[1][0])\n    test_answers.append(np.array(category_encoding[filename.split(\".\")[0]]))\n\ntest_data = np.array(test_data).astype('float32')\ntest_answers = np.array(test_answers)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T10:34:36.753572Z","iopub.execute_input":"2021-06-06T10:34:36.753901Z","iopub.status.idle":"2021-06-06T10:34:45.184244Z","shell.execute_reply.started":"2021-06-06T10:34:36.753870Z","shell.execute_reply":"2021-06-06T10:34:45.183375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# достаём vgg\nvgg = keras.applications.VGG16(weights='imagenet', include_top=True)\nvgg.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-06T10:37:29.376479Z","iopub.execute_input":"2021-06-06T10:37:29.376789Z","iopub.status.idle":"2021-06-06T10:37:31.215936Z","shell.execute_reply.started":"2021-06-06T10:37:29.376760Z","shell.execute_reply":"2021-06-06T10:37:31.215134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# накручиваем сверху слой\nclass_layer = keras.layers.Dense(1, activation=\"sigmoid\")\nout = class_layer(vgg.layers[-2].output)\nmodel = keras.Model(vgg.input, out)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-06T10:40:51.095830Z","iopub.execute_input":"2021-06-06T10:40:51.096167Z","iopub.status.idle":"2021-06-06T10:40:51.125629Z","shell.execute_reply.started":"2021-06-06T10:40:51.096136Z","shell.execute_reply":"2021-06-06T10:40:51.124860Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# замораживаем слои\nfor l, layer in enumerate(model.layers[:-1]):\n    layer.trainable = False\n\n# размораживаем последний слой\nfor l, layer in enumerate(model.layers[-1:]):\n    layer.trainable = True","metadata":{"execution":{"iopub.status.busy":"2021-06-06T10:41:00.126356Z","iopub.execute_input":"2021-06-06T10:41:00.126676Z","iopub.status.idle":"2021-06-06T10:41:00.133464Z","shell.execute_reply.started":"2021-06-06T10:41:00.126646Z","shell.execute_reply":"2021-06-06T10:41:00.131259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# компилируем\nmodel.compile(loss='binary_crossentropy',\n              optimizer='adam',\n              metrics=['accuracy'])\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-06T10:41:02.097528Z","iopub.execute_input":"2021-06-06T10:41:02.097846Z","iopub.status.idle":"2021-06-06T10:41:02.122137Z","shell.execute_reply.started":"2021-06-06T10:41:02.097816Z","shell.execute_reply":"2021-06-06T10:41:02.120544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n# обучаем\nmodel.fit(data, answers, epochs=3)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T10:41:05.780536Z","iopub.execute_input":"2021-06-06T10:41:05.780858Z","iopub.status.idle":"2021-06-06T10:50:04.997041Z","shell.execute_reply.started":"2021-06-06T10:41:05.780827Z","shell.execute_reply":"2021-06-06T10:50:04.996291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# смотрим точность\nloss, accuracy = model.evaluate(test_data, test_answers)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T11:12:16.624245Z","iopub.execute_input":"2021-06-06T11:12:16.624577Z","iopub.status.idle":"2021-06-06T11:15:52.801987Z","shell.execute_reply.started":"2021-06-06T11:12:16.624548Z","shell.execute_reply":"2021-06-06T11:15:52.801239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(accuracy)","metadata":{"execution":{"iopub.status.busy":"2021-06-06T11:15:54.456792Z","iopub.execute_input":"2021-06-06T11:15:54.457150Z","iopub.status.idle":"2021-06-06T11:15:54.461447Z","shell.execute_reply.started":"2021-06-06T11:15:54.457112Z","shell.execute_reply":"2021-06-06T11:15:54.460606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Как видно, VGG16 позволяет достаточно быстро дообучить нейросеть для какой-то конкретной задачи и получить высокую точность.","metadata":{}}]}