{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"def get_data_and_label(image_path):\n    labels = []\n    datas = []\n    files = []\n    for path in os.listdir(image_path):\n        if 'dog' in path:\n            labels.append(1)\n        else:\n            labels.append(0)\n\n        feature = data.imread(f'{image_path}/{path}')\n        feature = transform.resize(feature, (100, 100), mode='reflect')    \n        datas.append(convert_image(feature))\n        files.append(path)\n    return datas, labels,files\n","metadata":{"_uuid":"70676085-b9f1-4b74-bd15-4469cac32113","_cell_guid":"61620465-23be-413f-86c4-d23b4e081354","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport random\nimport shutil\n\n# ディレクトリ設定（あなたの実際のパスに変更してください）\nSOURCE_DIR = \"/path/to/source\"  # 元のファイルが入っているディレクトリ\nTRAINING_DIR = \"/path/to/train\"\nVALIDATION_DIR = \"/path/to/val\"\n\nSPLIT_SIZE = 0.9  # 90%を学習用に\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:45.373641Z","iopub.execute_input":"2025-07-18T06:13:45.374816Z","iopub.status.idle":"2025-07-18T06:13:45.396658Z","shell.execute_reply.started":"2025-07-18T06:13:45.374768Z","shell.execute_reply":"2025-07-18T06:13:45.395368Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\n# 入力ディレクトリの中身を確認する\nprint(os.listdir(\"/kaggle/input\"))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:45.397596Z","iopub.execute_input":"2025-07-18T06:13:45.397896Z","iopub.status.idle":"2025-07-18T06:13:45.423192Z","shell.execute_reply.started":"2025-07-18T06:13:45.397871Z","shell.execute_reply":"2025-07-18T06:13:45.422062Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nprint(os.listdir(\"/kaggle/input/dogs-vs-cats-redux-kernels-edition\"))\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:45.424727Z","iopub.execute_input":"2025-07-18T06:13:45.425525Z","iopub.status.idle":"2025-07-18T06:13:45.453314Z","shell.execute_reply.started":"2025-07-18T06:13:45.425486Z","shell.execute_reply":"2025-07-18T06:13:45.452261Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(os.listdir(\"/kaggle/input\"))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:45.454857Z","iopub.execute_input":"2025-07-18T06:13:45.455913Z","iopub.status.idle":"2025-07-18T06:13:45.469354Z","shell.execute_reply.started":"2025-07-18T06:13:45.455871Z","shell.execute_reply":"2025-07-18T06:13:45.46837Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\nimport os\n\nzip_path = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip\"\nextract_path = \"/kaggle/working/train\"\n\n# 解凍\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall(extract_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:45.470344Z","iopub.execute_input":"2025-07-18T06:13:45.470575Z","iopub.status.idle":"2025-07-18T06:13:57.013357Z","shell.execute_reply.started":"2025-07-18T06:13:45.470557Z","shell.execute_reply":"2025-07-18T06:13:57.012538Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"SOURCE_DIR = \"/kaggle/working/train/train\"  # ZIP解凍後の正しい画像フォルダ\nTRAINING_DIR = \"/kaggle/working/split/train\"\nVALIDATION_DIR = \"/kaggle/working/split/val\"\nSPLIT_SIZE = 0.9\n\nfile_list = [os.path.join(SOURCE_DIR, f) for f in os.listdir(SOURCE_DIR)\n             if os.path.isfile(os.path.join(SOURCE_DIR, f)) and os.path.getsize(os.path.join(SOURCE_DIR, f)) > 0]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:57.014269Z","iopub.execute_input":"2025-07-18T06:13:57.014541Z","iopub.status.idle":"2025-07-18T06:13:57.295391Z","shell.execute_reply.started":"2025-07-18T06:13:57.014513Z","shell.execute_reply":"2025-07-18T06:13:57.294613Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom glob import glob\nfrom shutil import copyfile\n\nSOURCE_DIR = \"/path/to/source/images/\"\nTRAINING_DIR = \"/path/to/train/\"\nVALIDATION_DIR = \"/path/to/val/\"\n\n# すべての画像ファイルを取得\nall_files = glob(SOURCE_DIR + \"*.jpg\")\n\n# 8:2で分割（例）\nsplit_idx = int(len(all_files) * 0.8)\ntrain_list = all_files[:split_idx]\nval_list = all_files[split_idx:]\n\n# ファイルをコピー\nfor f in train_list:\n    copyfile(f, os.path.join(TRAINING_DIR, os.path.basename(f)))\n\nfor f in val_list:\n    copyfile(f, os.path.join(VALIDATION_DIR, os.path.basename(f)))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:57.29804Z","iopub.execute_input":"2025-07-18T06:13:57.29832Z","iopub.status.idle":"2025-07-18T06:13:57.305858Z","shell.execute_reply.started":"2025-07-18T06:13:57.298299Z","shell.execute_reply":"2025-07-18T06:13:57.304595Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nTRAINING_DIR = \"/content/data/train\"  # ←ここを実際のパスに合わせて修正\n\n# 存在チェック\nif not os.path.exists(TRAINING_DIR):\n    print(\"エラー: TRAINING_DIR が存在しません\")\nelse:\n    datagen = ImageDataGenerator(rescale=1./255)\n\n    train_generator = datagen.flow_from_directory(\n        directory=TRAINING_DIR,\n        target_size=(256, 256),\n        class_mode='categorical',\n        batch_size=32\n    )\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:13:57.306824Z","iopub.execute_input":"2025-07-18T06:13:57.307062Z","iopub.status.idle":"2025-07-18T06:14:23.081708Z","shell.execute_reply.started":"2025-07-18T06:13:57.307042Z","shell.execute_reply":"2025-07-18T06:14:23.080372Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\n# /content 以下のフォルダ一覧を見る\nprint(\"現在のディレクトリ:\", os.getcwd())\nprint(\"content直下:\", os.listdir(\"/content\"))\n\n# dataディレクトリがあるならその中も見る\nif os.path.exists(\"/content/data\"):\n    print(\"dataの中:\", os.listdir(\"/content/data\"))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:23.082997Z","iopub.execute_input":"2025-07-18T06:14:23.08379Z","iopub.status.idle":"2025-07-18T06:14:23.091616Z","shell.execute_reply.started":"2025-07-18T06:14:23.083755Z","shell.execute_reply":"2025-07-18T06:14:23.090223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"SOURCE_DIR = \"/kaggle/input/my-dataset/\"\nTRAINING_DIR = \"/kaggle/working/train/\"\nVALIDATION_DIR = \"/kaggle/working/val/\"\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:23.09277Z","iopub.execute_input":"2025-07-18T06:14:23.093066Z","iopub.status.idle":"2025-07-18T06:14:23.123896Z","shell.execute_reply.started":"2025-07-18T06:14:23.093044Z","shell.execute_reply":"2025-07-18T06:14:23.12258Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nos.makedirs(TRAINING_DIR, exist_ok=True)\nos.makedirs(VALIDATION_DIR, exist_ok=True)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:23.125199Z","iopub.execute_input":"2025-07-18T06:14:23.125497Z","iopub.status.idle":"2025-07-18T06:14:23.151497Z","shell.execute_reply.started":"2025-07-18T06:14:23.125475Z","shell.execute_reply":"2025-07-18T06:14:23.150234Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nprint(\"inputフォルダの中身:\", os.listdir(\"/kaggle/input\"))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:23.15281Z","iopub.execute_input":"2025-07-18T06:14:23.153238Z","iopub.status.idle":"2025-07-18T06:14:23.176112Z","shell.execute_reply.started":"2025-07-18T06:14:23.153205Z","shell.execute_reply":"2025-07-18T06:14:23.175118Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.listdir(\"/kaggle/input\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:23.177113Z","iopub.execute_input":"2025-07-18T06:14:23.177446Z","iopub.status.idle":"2025-07-18T06:14:23.19926Z","shell.execute_reply.started":"2025-07-18T06:14:23.177422Z","shell.execute_reply":"2025-07-18T06:14:23.198056Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\npath = os.path.join(\"/kaggle/input\", \"dogs-vs-cats-redux-kernels-edition\")\nprint(os.listdir(path))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:23.200406Z","iopub.execute_input":"2025-07-18T06:14:23.201017Z","iopub.status.idle":"2025-07-18T06:14:23.226403Z","shell.execute_reply.started":"2025-07-18T06:14:23.20096Z","shell.execute_reply":"2025-07-18T06:14:23.225394Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\nimport os\n\nzip_path = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip\"\nextract_dir = \"/kaggle/working/train\"\n\n# 解凍処理\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall(extract_dir)\n\n# 解凍したフォルダの中身を確認\nprint(\"解凍後のファイル例:\", os.listdir(extract_dir)[:10])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:23.227434Z","iopub.execute_input":"2025-07-18T06:14:23.227928Z","iopub.status.idle":"2025-07-18T06:14:31.438112Z","shell.execute_reply.started":"2025-07-18T06:14:23.227881Z","shell.execute_reply":"2025-07-18T06:14:31.437244Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\n# 分類先のフォルダ\ncat_dir = \"/kaggle/working/sorted/train/cat\"\ndog_dir = \"/kaggle/working/sorted/train/dog\"\n\nos.makedirs(cat_dir, exist_ok=True)\nos.makedirs(dog_dir, exist_ok=True)\n\n# trainディレクトリ内の画像を取得\nfor filename in os.listdir(extract_dir):\n    if filename.startswith(\"cat\"):\n        shutil.copy(os.path.join(extract_dir, filename), os.path.join(cat_dir, filename))\n    elif filename.startswith(\"dog\"):\n        shutil.copy(os.path.join(extract_dir, filename), os.path.join(dog_dir, filename))\n\nprint(\"分類完了\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.439168Z","iopub.execute_input":"2025-07-18T06:14:31.43948Z","iopub.status.idle":"2025-07-18T06:14:31.447116Z","shell.execute_reply.started":"2025-07-18T06:14:31.439454Z","shell.execute_reply":"2025-07-18T06:14:31.446301Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)\n\ntrain_generator = datagen.flow_from_directory(\n    directory=\"/kaggle/working/sorted/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode=\"binary\",\n    subset=\"training\"\n)\n\nval_generator = datagen.flow_from_directory(\n    directory=\"/kaggle/working/sorted/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode=\"binary\",\n    subset=\"validation\"\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.448043Z","iopub.execute_input":"2025-07-18T06:14:31.448443Z","iopub.status.idle":"2025-07-18T06:14:31.478609Z","shell.execute_reply.started":"2025-07-18T06:14:31.44842Z","shell.execute_reply":"2025-07-18T06:14:31.477728Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# データジェネレータの定義（前処理込み）\ndatagen = ImageDataGenerator(rescale=1./255)\n\n# flow_from_directory を datagen から呼び出す\ntrain_generator = datagen.flow_from_directory(\n    directory=\"/kaggle/working/sorted/train\",\n    target_size=(256, 256),\n    class_mode='categorical',  # 2クラスなら 'binary' でもOK\n    batch_size=32\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.47959Z","iopub.execute_input":"2025-07-18T06:14:31.479889Z","iopub.status.idle":"2025-07-18T06:14:31.498106Z","shell.execute_reply.started":"2025-07-18T06:14:31.479863Z","shell.execute_reply":"2025-07-18T06:14:31.497331Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# GRADED FUNCTION: train_val_generators\ndef train_val_generators(TRAINING_DIR, VALIDATION_DIR):\n  \"\"\"\n  Creates the training and validation data generators\n  \n  Args:\n    TRAINING_DIR (string): directory path containing the training images\n    VALIDATION_DIR (string): directory path containing the testing/validation images\n    \n  Returns:\n    train_generator, validation_generator - tuple containing the generators\n  \"\"\"\n  ### START CODE HERE\n\n  # Instantiate the ImageDataGenerator class (don't forget to set the rescale argument)\n  train_datagen = ImageDataGenerator( rescale = 1.0/255. )\n\n  # Pass in the appropiate arguments to the flow_from_directory method\n  train_generator = train_datagen.flow_from_directory(directory=TRAINING_DIR,\n                                                      batch_size=50,\n                                                      class_mode='binary',\n                                                      target_size=(150, 150))\n\n  # Instantiate the ImageDataGenerator class (don't forget to set the rescale argument)\n  validation_datagen = ImageDataGenerator( rescale = 1.0/255. )\n\n  # Pass in the appropiate arguments to the flow_from_directory method\n  validation_generator = validation_datagen.flow_from_directory(directory=VALIDATION_DIR,\n                                                                batch_size=50,\n                                                                class_mode='binary',\n                                                                target_size=(150, 150))\n  ### END CODE HERE\n  return train_generator, validation_generator","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.499065Z","iopub.execute_input":"2025-07-18T06:14:31.499374Z","iopub.status.idle":"2025-07-18T06:14:31.517793Z","shell.execute_reply.started":"2025-07-18T06:14:31.499346Z","shell.execute_reply":"2025-07-18T06:14:31.516867Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.optimizers import RMSprop\n# GRADED FUNCTION: create_model\ndef create_model():\n  # DEFINE A KERAS MODEL TO CLASSIFY CATS V DOGS\n  # USE AT LEAST 3 CONVOLUTION LAYERS\n\n  ### START CODE HERE\n\n  model = tf.keras.models.Sequential([ \n    # Note the input shape is the desired size of the image 150x150 with 3 bytes color\n    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    tf.keras.layers.MaxPooling2D(2,2),\n    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2), \n    tf.keras.layers.Conv2D(64, (3,3), activation='relu'), \n    tf.keras.layers.MaxPooling2D(2,2),\n    tf.keras.layers.Conv2D(128, (3,3), activation='relu'), \n    tf.keras.layers.MaxPooling2D(2,2),\n    # Flatten the results to feed into a DNN\n    tf.keras.layers.Flatten(), \n    # 512 neuron hidden layer\n    tf.keras.layers.Dense(512, activation='relu'), \n    # Only 1 output neuron. It will contain a value from 0-1 where 0 for 1 class ('cats') and 1 for the other ('dogs')\n    tf.keras.layers.Dense(1, activation='sigmoid')  \n  ])\n\n  \n  model.compile(optimizer=RMSprop(learning_rate=0.001),\n                loss='binary_crossentropy',\n                metrics=['accuracy']) \n    \n  ### END CODE HERE\n\n  return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.518783Z","iopub.execute_input":"2025-07-18T06:14:31.51912Z","iopub.status.idle":"2025-07-18T06:14:31.554027Z","shell.execute_reply.started":"2025-07-18T06:14:31.519077Z","shell.execute_reply":"2025-07-18T06:14:31.553077Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)\n\ntrain_generator = datagen.flow_from_directory(\n    directory=\"/kaggle/working/sorted/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode='binary',\n    subset='training'\n)\n\nvalidation_generator = datagen.flow_from_directory(\n    directory=\"/kaggle/working/sorted/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode='binary',\n    subset='validation'\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.555008Z","iopub.execute_input":"2025-07-18T06:14:31.555898Z","iopub.status.idle":"2025-07-18T06:14:31.587381Z","shell.execute_reply.started":"2025-07-18T06:14:31.555856Z","shell.execute_reply":"2025-07-18T06:14:31.586544Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nextract_dir = \"/kaggle/working/train/train\"  # フォルダが二重なのでここに変更\nprint(f\"{extract_dir} の中身のファイル数:\", len(os.listdir(extract_dir)))\nprint(\"ファイル例:\", os.listdir(extract_dir)[:10])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.588376Z","iopub.execute_input":"2025-07-18T06:14:31.588685Z","iopub.status.idle":"2025-07-18T06:14:31.629536Z","shell.execute_reply.started":"2025-07-18T06:14:31.588664Z","shell.execute_reply":"2025-07-18T06:14:31.628221Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\ncat_dir = \"/kaggle/working/sorted/train/cat\"\ndog_dir = \"/kaggle/working/sorted/train/dog\"\n\nos.makedirs(cat_dir, exist_ok=True)\nos.makedirs(dog_dir, exist_ok=True)\n\nfor filename in os.listdir(extract_dir):\n    lower_name = filename.lower()\n    if \"cat\" in lower_name:\n        shutil.copy(os.path.join(extract_dir, filename), os.path.join(cat_dir, filename))\n    elif \"dog\" in lower_name:\n        shutil.copy(os.path.join(extract_dir, filename), os.path.join(dog_dir, filename))\n\nprint(\"振り分け完了\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:31.633637Z","iopub.execute_input":"2025-07-18T06:14:31.633946Z","iopub.status.idle":"2025-07-18T06:14:34.836598Z","shell.execute_reply.started":"2025-07-18T06:14:31.633923Z","shell.execute_reply":"2025-07-18T06:14:34.83494Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for folder_name in ['cat', 'dog']:\n    folder_path = f\"/kaggle/working/sorted/train/{folder_name}\"\n    files = os.listdir(folder_path)\n    print(f\"フォルダ {folder_name} の中にあるファイル数: {len(files)}\")\n    print(f\"ファイル例: {files[:5]}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:34.838419Z","iopub.execute_input":"2025-07-18T06:14:34.839471Z","iopub.status.idle":"2025-07-18T06:14:34.857506Z","shell.execute_reply.started":"2025-07-18T06:14:34.839428Z","shell.execute_reply":"2025-07-18T06:14:34.856574Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)\n\ntrain_generator = datagen.flow_from_directory(\n    \"/kaggle/working/sorted/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode='binary',\n    subset='training'\n)\n\nvalidation_generator = datagen.flow_from_directory(\n    \"/kaggle/working/sorted/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode='binary',\n    subset='validation'\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:34.858471Z","iopub.execute_input":"2025-07-18T06:14:34.858703Z","iopub.status.idle":"2025-07-18T06:14:35.185778Z","shell.execute_reply.started":"2025-07-18T06:14:34.858685Z","shell.execute_reply":"2025-07-18T06:14:35.184921Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\n\ndef create_model():\n    model = models.Sequential([\n        layers.Input(shape=(150, 150, 3)),\n        layers.Conv2D(32, (3,3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n\n        layers.Conv2D(64, (3,3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n\n        layers.Conv2D(128, (3,3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n\n        layers.Flatten(),\n        layers.Dense(512, activation='relu'),\n        layers.Dense(1, activation='sigmoid')  # 2クラス分類なので1ユニット+sigmoid\n    ])\n\n    model.compile(optimizer='adam',\n                  loss='binary_crossentropy',\n                  metrics=['accuracy'])\n    return model\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:35.186666Z","iopub.execute_input":"2025-07-18T06:14:35.18695Z","iopub.status.idle":"2025-07-18T06:14:35.193758Z","shell.execute_reply.started":"2025-07-18T06:14:35.186922Z","shell.execute_reply":"2025-07-18T06:14:35.19295Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\n\ndef create_model():\n    model = models.Sequential([\n        layers.Input(shape=(150, 150, 3)),\n        layers.Conv2D(32, (3,3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n\n        layers.Conv2D(64, (3,3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n\n        layers.Conv2D(128, (3,3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n\n        layers.Flatten(),\n        layers.Dense(512, activation='relu'),\n        layers.Dense(1, activation='sigmoid')  # 2クラス分類なので1ユニット+sigmoid\n    ])\n\n    model.compile(optimizer='adam',\n                  loss='binary_crossentropy',\n                  metrics=['accuracy'])\n    return model\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:35.194598Z","iopub.execute_input":"2025-07-18T06:14:35.19487Z","iopub.status.idle":"2025-07-18T06:14:35.223578Z","shell.execute_reply.started":"2025-07-18T06:14:35.194849Z","shell.execute_reply":"2025-07-18T06:14:35.222576Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\n\ndef create_model():\n    model = models.Sequential([\n        tf.keras.Input(shape=(150, 150, 3)),\n        layers.Conv2D(32, (3, 3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n        \n        layers.Conv2D(64, (3, 3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n        \n        layers.Conv2D(128, (3, 3), activation='relu'),\n        layers.MaxPooling2D(2, 2),\n        \n        layers.Flatten(),\n        layers.Dense(512, activation='relu'),\n        layers.Dense(2, activation='softmax')  # 2クラス分類 (cat, dog)\n    ])\n    \n    model.compile(\n        loss='categorical_crossentropy',\n        optimizer='adam',\n        metrics=['accuracy']\n    )\n    \n    return model\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:35.224784Z","iopub.execute_input":"2025-07-18T06:14:35.225722Z","iopub.status.idle":"2025-07-18T06:14:35.247517Z","shell.execute_reply.started":"2025-07-18T06:14:35.225687Z","shell.execute_reply":"2025-07-18T06:14:35.246489Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\nimport os\n\nzip_path = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip\"\nextract_path = \"/kaggle/working/train\"\n\nos.makedirs(extract_path, exist_ok=True)\n\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall(extract_path)\n\nprint(\"✅ 解凍完了:\", len(os.listdir(extract_path)), \"ファイル\")\nprint(\"📄 ファイル例:\", os.listdir(extract_path)[:5])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:35.248447Z","iopub.execute_input":"2025-07-18T06:14:35.248716Z","iopub.status.idle":"2025-07-18T06:14:43.063501Z","shell.execute_reply.started":"2025-07-18T06:14:35.248682Z","shell.execute_reply":"2025-07-18T06:14:43.061743Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\npath = \"/kaggle/working/train/train\"\nfiles = os.listdir(path)\n\nprint(f\"📁 {path} の中のファイル数: {len(files)}\")\nprint(\"📄 ファイル名例:\", files[:5])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:43.064692Z","iopub.execute_input":"2025-07-18T06:14:43.06503Z","iopub.status.idle":"2025-07-18T06:14:43.088939Z","shell.execute_reply.started":"2025-07-18T06:14:43.065005Z","shell.execute_reply":"2025-07-18T06:14:43.087517Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os, shutil\nfrom sklearn.model_selection import train_test_split\n\n# 元の画像フォルダ\noriginal_dir = \"/kaggle/working/train/train\"\n\n# 新しいデータ構造のベースパス\nbase_dir = \"/kaggle/working/dataset\"\ntrain_dir = os.path.join(base_dir, \"train\")\nval_dir = os.path.join(base_dir, \"validation\")\n\n# クラス\nclasses = [\"cat\", \"dog\"]\n\n# フォルダ作成\nfor category in classes:\n    os.makedirs(os.path.join(train_dir, category), exist_ok=True)\n    os.makedirs(os.path.join(val_dir, category), exist_ok=True)\n\n# ファイルをクラスごとに分けて train/val に分割\nall_files = os.listdir(original_dir)\nfor category in classes:\n    files = [f for f in all_files if f.startswith(category)]\n    train_files, val_files = train_test_split(files, test_size=0.2, random_state=42)\n\n    for f in train_files:\n        shutil.copy(os.path.join(original_dir, f), os.path.join(train_dir, category, f))\n    for f in val_files:\n        shutil.copy(os.path.join(original_dir, f), os.path.join(val_dir, category, f))\n\nprint(\"✅ データセットの振り分け完了\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:43.090836Z","iopub.execute_input":"2025-07-18T06:14:43.091578Z","iopub.status.idle":"2025-07-18T06:14:47.225723Z","shell.execute_reply.started":"2025-07-18T06:14:43.091546Z","shell.execute_reply":"2025-07-18T06:14:47.224627Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# データ拡張の設定（訓練用）\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=40,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest'\n)\n\n# 検証用はリスケーリングのみ\nval_datagen = ImageDataGenerator(rescale=1./255)\n\n# ディレクトリから画像を読み込む\ntrain_generator = train_datagen.flow_from_directory(\n    \"/kaggle/working/dataset/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode='binary'\n)\n\nvalidation_generator = val_datagen.flow_from_directory(\n    \"/kaggle/working/dataset/validation\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode='binary'\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:47.226828Z","iopub.execute_input":"2025-07-18T06:14:47.227079Z","iopub.status.idle":"2025-07-18T06:14:47.49799Z","shell.execute_reply.started":"2025-07-18T06:14:47.227061Z","shell.execute_reply":"2025-07-18T06:14:47.49707Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers, models\n\n# モデル構築\nmodel = models.Sequential([\n    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)),\n    layers.MaxPooling2D(2, 2),\n\n    layers.Conv2D(64, (3, 3), activation='relu'),\n    layers.MaxPooling2D(2, 2),\n\n    layers.Conv2D(128, (3, 3), activation='relu'),\n    layers.MaxPooling2D(2, 2),\n\n    layers.Conv2D(128, (3, 3), activation='relu'),\n    layers.MaxPooling2D(2, 2),\n\n    layers.Flatten(),\n    layers.Dense(512, activation='relu'),\n    layers.Dense(1, activation='sigmoid')  # バイナリ分類\n])\n\n# コンパイル\nmodel.compile(\n    loss='binary_crossentropy',\n    optimizer='adam',\n    metrics=['accuracy']\n)\n\n# 学習\nhistory = model.fit(\n    train_generator,\n    epochs=15,\n    validation_data=validation_generator\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T06:14:47.499129Z","iopub.execute_input":"2025-07-18T06:14:47.49943Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.plot(history.history['accuracy'], label='train_acc')\nplt.plot(history.history['val_accuracy'], label='val_acc')\nplt.legend()\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom tensorflow.keras.preprocessing import image\nimport os\n\n# テスト画像のパス\ntest_dir = '/kaggle/working/test'  # 解凍済みならこのパスにあるはず\ntest_images = [f for f in os.listdir(test_dir) if f.endswith('.jpg')]\n\n# 出力データ保持用\npredictions = []\n\nfor img_name in test_images:\n    img_path = os.path.join(test_dir, img_name)\n    img = image.load_img(img_path, target_size=(150, 150))  # 学習時と同じサイズ\n    img_array = image.img_to_array(img)\n    img_array = np.expand_dims(img_array, axis=0) / 255.0\n\n    # 予測\n    pred = model.predict(img_array)[0][0]\n    predictions.append([img_name.split('.')[0], pred])  # id, label\n\n# DataFrameに変換してCSV保存\nsubmission_df = pd.DataFrame(predictions, columns=['id', 'label'])\nsubmission_df['id'] = submission_df['id'].astype(int)  # id列をintに\nsubmission_df = submission_df.sort_values(by='id')     # idで並び替え\n\nsubmission_df.to_csv('/kaggle/working/submission.csv', index=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T08:42:37.483484Z","iopub.execute_input":"2025-07-18T08:42:37.483853Z","iopub.status.idle":"2025-07-18T08:43:03.245818Z","shell.execute_reply.started":"2025-07-18T08:42:37.483827Z","shell.execute_reply":"2025-07-18T08:43:03.244422Z"}},"outputs":[],"execution_count":null}]}