{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30673,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport keras\nimport tensorflow as tf\nimport random\n\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D, MaxPool2D, Flatten, Input, Rescaling\nfrom keras.preprocessing import image_dataset_from_directory\n\nimport numpy as np\nfrom os import path\nimport shutil\n\nimport matplotlib.pyplot as plt\nfrom PIL import Image","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-04-06T17:43:00.189432Z","iopub.execute_input":"2024-04-06T17:43:00.189862Z","iopub.status.idle":"2024-04-06T17:43:13.182679Z","shell.execute_reply.started":"2024-04-06T17:43:00.189801Z","shell.execute_reply":"2024-04-06T17:43:13.181850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip /kaggle/input/dogs-vs-cats/train.zip","metadata":{"_kg_hide-input":false,"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_path = '/kaggle/working/train'","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:43:24.605831Z","iopub.execute_input":"2024-04-06T17:43:24.606147Z","iopub.status.idle":"2024-04-06T17:43:24.610888Z","shell.execute_reply.started":"2024-04-06T17:43:24.606120Z","shell.execute_reply":"2024-04-06T17:43:24.609885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# кол-во изображений в датасете\nimg_list = os.listdir(data_path)\nlen(img_list)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:43:24.612028Z","iopub.execute_input":"2024-04-06T17:43:24.612287Z","iopub.status.idle":"2024-04-06T17:43:24.645009Z","shell.execute_reply.started":"2024-04-06T17:43:24.612265Z","shell.execute_reply":"2024-04-06T17:43:24.644196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# кол-во собак и кол-во кошек\ncats_images = [img for img in img_list if img.startswith('cat')]\ndogs_images = [img for img in img_list if img.startswith('dog')]\nlen(cats_images), len(dogs_images)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:43:24.647067Z","iopub.execute_input":"2024-04-06T17:43:24.647331Z","iopub.status.idle":"2024-04-06T17:43:24.661883Z","shell.execute_reply.started":"2024-04-06T17:43:24.647309Z","shell.execute_reply":"2024-04-06T17:43:24.661007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# перемешиваем кошек и собак\nnp.random.shuffle(cats_images)\nnp.random.shuffle(dogs_images)\n\n# делим на выборки\nthreshold = int(0.8 * len(cats_images))\ntrain_cats, test_cats = np.split(cats_images, [threshold])\ntrain_dogs, test_dogs = np.split(dogs_images, [threshold])\nprint(len(train_cats), len(test_cats), len(train_dogs), len(test_dogs))","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:43:24.663070Z","iopub.execute_input":"2024-04-06T17:43:24.663463Z","iopub.status.idle":"2024-04-06T17:43:24.682061Z","shell.execute_reply.started":"2024-04-06T17:43:24.663430Z","shell.execute_reply":"2024-04-06T17:43:24.681110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# структура \nbase_dir = f\"/kaggle/working/dogs_vs_cats_dataset\"\nif not path.exists(base_dir): \n    os.mkdir(base_dir)\n\ntrain_dir = path.join(base_dir, 'train')\ntest_dir = path.join(base_dir, 'test')\nfor d in [train_dir, test_dir]:\n    if not path.exists(d): \n        os.mkdir(d)\n\ntrain_dog_dir = path.join(train_dir, 'dog')\ntrain_cat_dir = path.join(train_dir, 'cat')\ntest_dog_dir = path.join(test_dir, \"dog\")\ntest_cat_dir = path.join(test_dir, \"cat\")\nfor d in [train_dog_dir, train_cat_dir, test_dog_dir, test_cat_dir]:\n    if not path.exists(d): \n        os.mkdir(d)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:06.485308Z","iopub.execute_input":"2024-04-06T17:45:06.486177Z","iopub.status.idle":"2024-04-06T17:45:06.494692Z","shell.execute_reply.started":"2024-04-06T17:45:06.486141Z","shell.execute_reply":"2024-04-06T17:45:06.493618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# перемещение изображений для обучения\nfor i in range(threshold):\n    src_path_cats = path.join(data_path, train_cats[i])\n    src_path_dogs = path.join(data_path, train_dogs[i])\n    \n    dest_path_cats = path.join(train_cat_dir, train_cats[i])\n    dest_path_dogs = path.join(train_dog_dir, train_dogs[i])\n    \n    shutil.move(src_path_cats, dest_path_cats)\n    shutil.move(src_path_dogs, dest_path_dogs)\n    \n# перемещение изображений для тестирования\nfor i in range(threshold, len(cats_images)):\n    src_path_cats = path.join(data_path, test_cats[i - threshold])\n    src_path_dogs = path.join(data_path, test_dogs[i - threshold])\n    \n    dest_path_cats = path.join(test_cat_dir, test_cats[i - threshold])\n    dest_path_dogs = path.join(test_dog_dir, test_dogs[i - threshold])\n    \n    shutil.move(src_path_cats, dest_path_cats)\n    shutil.move(src_path_dogs, dest_path_dogs)\n\nprint(f'Number of cats in {train_cat_dir}: ', len(os.listdir(train_cat_dir)))\nprint(f'Number of cats in {test_cat_dir}: ', len(os.listdir(test_cat_dir)))\nprint(f'Number of dogs in {train_dog_dir}: ', len(os.listdir(train_dog_dir)))\nprint(f'Number of dogs in {test_cat_dir}: ', len(os.listdir(test_cat_dir)))","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:06.497126Z","iopub.execute_input":"2024-04-06T17:45:06.497639Z","iopub.status.idle":"2024-04-06T17:45:07.424585Z","shell.execute_reply.started":"2024-04-06T17:45:06.497601Z","shell.execute_reply":"2024-04-06T17:45:07.423586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# примеры изображений кошек\nfig, ax = plt.subplots(2,4,figsize=(20,12))\nfor i in range(8):\n    img_filename = random.choice(train_cats)\n    img_path = os.path.join(train_cat_dir, img_filename)\n    img = Image.open(img_path)\n    ax[i//4, i%4].imshow(img)\n    ax[i//4, i%4].axis('off')","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:07.426217Z","iopub.execute_input":"2024-04-06T17:45:07.426655Z","iopub.status.idle":"2024-04-06T17:45:08.633223Z","shell.execute_reply.started":"2024-04-06T17:45:07.426619Z","shell.execute_reply":"2024-04-06T17:45:08.632265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# примеры изображений кошек\nfig, ax = plt.subplots(2,4,figsize=(20,12))\nfor i in range(8):\n    img_filename = random.choice(train_dogs)\n    img_path = os.path.join(train_dog_dir, img_filename)\n    img = Image.open(img_path)\n    ax[i//4, i%4].imshow(img)\n    ax[i//4, i%4].axis('off')","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:08.634421Z","iopub.execute_input":"2024-04-06T17:45:08.634788Z","iopub.status.idle":"2024-04-06T17:45:09.869312Z","shell.execute_reply.started":"2024-04-06T17:45:08.634762Z","shell.execute_reply":"2024-04-06T17:45:09.867938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 64\nWIDTH = 224\nHEIGHT = 224\nCHANNELS = 3\n\n# training data generator\ntrain_ds = image_dataset_from_directory(\n    train_dir,\n    labels='inferred',\n    label_mode='binary',\n    color_mode='rgb',\n    image_size=(HEIGHT,WIDTH),\n    batch_size=BATCH_SIZE\n)\n\n# validation data generator\ntest_ds = image_dataset_from_directory(\n    test_dir,\n    labels='inferred',\n    label_mode='binary',\n    color_mode='rgb',\n    image_size=(HEIGHT,WIDTH),\n    batch_size=BATCH_SIZE\n)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:09.872340Z","iopub.execute_input":"2024-04-06T17:45:09.872708Z","iopub.status.idle":"2024-04-06T17:45:13.906866Z","shell.execute_reply.started":"2024-04-06T17:45:09.872678Z","shell.execute_reply":"2024-04-06T17:45:13.905780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = keras.Sequential(\n    [        \n        Rescaling(1./255, input_shape=(HEIGHT, WIDTH, CHANNELS)),\n        \n        Conv2D(64, (3,3), activation='relu'),\n        MaxPool2D(2,2),\n        \n        Conv2D(128, (3,3), activation='relu'),\n        MaxPool2D(2,2),\n        \n        Conv2D(256, (3,3), activation='relu'),\n        Conv2D(256, (3,3), activation='relu'),\n        MaxPool2D(2,2),\n        \n        Flatten(),\n        Dense(256, activation='relu'),\n        Dense(256, activation='relu'),\n        Dense(1, activation='sigmoid')\n    ]\n)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:13.908099Z","iopub.execute_input":"2024-04-06T17:45:13.908400Z","iopub.status.idle":"2024-04-06T17:45:14.015538Z","shell.execute_reply.started":"2024-04-06T17:45:13.908352Z","shell.execute_reply":"2024-04-06T17:45:14.014629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"AUTOTUNE = tf.data.experimental.AUTOTUNE\ntrain_ds = train_ds.prefetch(buffer_size=AUTOTUNE)\ntest_ds = test_ds.prefetch(buffer_size=AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:14.016825Z","iopub.execute_input":"2024-04-06T17:45:14.017136Z","iopub.status.idle":"2024-04-06T17:45:14.023647Z","shell.execute_reply.started":"2024-04-06T17:45:14.017111Z","shell.execute_reply":"2024-04-06T17:45:14.022775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.optimizers import Adam\n\nmodel.compile(optimizer=Adam(learning_rate=0.001), \n              loss='binary_crossentropy', \n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:14.024748Z","iopub.execute_input":"2024-04-06T17:45:14.025050Z","iopub.status.idle":"2024-04-06T17:45:14.041923Z","shell.execute_reply.started":"2024-04-06T17:45:14.025009Z","shell.execute_reply":"2024-04-06T17:45:14.041145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:14.043007Z","iopub.execute_input":"2024-04-06T17:45:14.043263Z","iopub.status.idle":"2024-04-06T17:45:14.072149Z","shell.execute_reply.started":"2024-04-06T17:45:14.043240Z","shell.execute_reply":"2024-04-06T17:45:14.071353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_ds, validation_data=test_ds, epochs=30)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T17:45:14.073319Z","iopub.execute_input":"2024-04-06T17:45:14.073926Z","iopub.status.idle":"2024-04-06T18:08:29.767874Z","shell.execute_reply.started":"2024-04-06T17:45:14.073893Z","shell.execute_reply":"2024-04-06T18:08:29.766954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history[\"accuracy\"])\nplt.plot(history.history['val_accuracy'])\nplt.plot(history.history['loss'])\n\nplt.title(\"Точность модели\")\nplt.ylabel(\"Точность\")\nplt.xlabel(\"Эпоха\")\nplt.legend([\"accuracy\", \"val_accuracy\", \"loss\"])\nprint(history.history.keys())\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-06T18:14:37.934152Z","iopub.execute_input":"2024-04-06T18:14:37.935004Z","iopub.status.idle":"2024-04-06T18:14:38.185597Z","shell.execute_reply.started":"2024-04-06T18:14:37.934968Z","shell.execute_reply":"2024-04-06T18:14:38.184429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Training Accuracy: \", model.evaluate(train_ds, verbose=None)[1])\nprint(\"Validation Accuracy: \", model.evaluate(test_ds, verbose=None)[1])","metadata":{"execution":{"iopub.status.busy":"2024-04-06T19:19:52.222838Z","iopub.execute_input":"2024-04-06T19:19:52.223228Z","iopub.status.idle":"2024-04-06T19:20:14.412253Z","shell.execute_reply.started":"2024-04-06T19:19:52.223197Z","shell.execute_reply":"2024-04-06T19:20:14.411265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Прогноз","metadata":{}},{"cell_type":"markdown","source":"Возьмем случайную картинку и попробуем определить, кто на ней находится","metadata":{}},{"cell_type":"code","source":"from keras.preprocessing import image\n\nprediction_img_paths = []\nprediction_img_paths.extend(path.join(train_cat_dir, random.choice(train_cats)) for _ in range(4))\nprediction_img_paths.extend(path.join(train_dog_dir, random.choice(train_dogs)) for _ in range(4))\n\nprediction_imgs = []\n\nfor img in prediction_img_paths:\n    img = image.load_img(img, target_size=(224,224))\n    img = np.asarray(img)\n    prediction_imgs.append(img)\n    \nprint(prediction_img_paths)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T19:18:44.054817Z","iopub.execute_input":"2024-04-06T19:18:44.055716Z","iopub.status.idle":"2024-04-06T19:18:44.075143Z","shell.execute_reply.started":"2024-04-06T19:18:44.055682Z","shell.execute_reply":"2024-04-06T19:18:44.074276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = {0: 'dog', 1: 'cat'}\n\nfig, ax = plt.subplots(2,4,figsize=(20,12))\n\nfor i, img in enumerate(prediction_imgs):\n    img = tf.expand_dims(img, 0)\n    output = model.predict(img)\n    print(output)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T19:40:11.598232Z","iopub.execute_input":"2024-04-06T19:40:11.598999Z","iopub.status.idle":"2024-04-06T19:40:13.340839Z","shell.execute_reply.started":"2024-04-06T19:40:11.598966Z","shell.execute_reply":"2024-04-06T19:40:13.339742Z"},"trusted":true},"execution_count":null,"outputs":[]}]}