{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.8.17","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Kaggle Python環境をセットアップし、/kaggle/input ディレクトリにあるファイルのリストを表示する。\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-09-03T05:57:43.462611Z","iopub.execute_input":"2023-09-03T05:57:43.463002Z","iopub.status.idle":"2023-09-03T05:57:43.483351Z","shell.execute_reply.started":"2023-09-03T05:57:43.462966Z","shell.execute_reply":"2023-09-03T05:57:43.482480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport os\nimport zipfile\nimport shutil\nimport glob\nimport tensorflow as tf\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras import layers, models","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:57:43.485185Z","iopub.execute_input":"2023-09-03T05:57:43.485498Z","iopub.status.idle":"2023-09-03T05:58:25.659047Z","shell.execute_reply.started":"2023-09-03T05:57:43.485470Z","shell.execute_reply":"2023-09-03T05:58:25.657962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train.zipの展開。\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip', 'r') as zip_ref:\n    zip_ref.extractall('/kaggle/working/train')\n\n# test.zipの展開。\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip', 'r') as zip_ref:\n    zip_ref.extractall('/kaggle/working/test')","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:25.660378Z","iopub.execute_input":"2023-09-03T05:58:25.660944Z","iopub.status.idle":"2023-09-03T05:58:45.945348Z","shell.execute_reply.started":"2023-09-03T05:58:25.660911Z","shell.execute_reply":"2023-09-03T05:58:45.944348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 画像ファイルが展開されたディレクトリ。\ntrain_images_dir = '/kaggle/working/train/train'\n\n# 画像ファイルのリストを取得。\ntrain_image_files = os.listdir(train_images_dir)\n\n# 最初の画像を選ぶ。\nsample_image_path = os.path.join(train_images_dir, train_image_files[0])\n\n# 画像を読み込む。\nimg = cv2.imread(sample_image_path)\n\n# OpenCVのBGR形式をMatplotlibのRGB形式に変換。\nimg_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n# 画像を表示。\nplt.imshow(img_rgb)\nplt.axis('off')  # 軸を表示しない。\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:45.946498Z","iopub.execute_input":"2023-09-03T05:58:45.946877Z","iopub.status.idle":"2023-09-03T05:58:46.225389Z","shell.execute_reply.started":"2023-09-03T05:58:45.946849Z","shell.execute_reply":"2023-09-03T05:58:46.224250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 新しいディレクトリのパスを指定。\ndirectory_path = [\n    \"/kaggle/working/data/train/dogs\",\n    \"/kaggle/working/data/train/cats\",\n    \"/kaggle/working/data/valid/dogs\",\n    \"/kaggle/working/data/valid/cats\",\n    \"/kaggle/working/data/test\",\n]\n\n# ディレクトリを作成。\nfor path in directory_path:\n    os.makedirs(path, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:46.229366Z","iopub.execute_input":"2023-09-03T05:58:46.230221Z","iopub.status.idle":"2023-09-03T05:58:46.237637Z","shell.execute_reply.started":"2023-09-03T05:58:46.230175Z","shell.execute_reply":"2023-09-03T05:58:46.236564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def move_images(source_directory, destination_directories, file_filter=None):\n    for key, dest_dir in destination_directories.items():\n        files = [file for file in os.listdir(source_directory) if file_filter(file, key)]\n        for file in files:\n            source_path = os.path.join(source_directory, file)\n            destination_path = os.path.join(dest_dir, file)\n            shutil.move(source_path, destination_path)\n\nsource_directory = \"/kaggle/working/train/train\"\ntest_source_directory = \"/kaggle/working/test/test\"\n\ntrain_dest_directories = {\n    \"dog.\": \"/kaggle/working/data/train/dogs\",\n    \"cat.\": \"/kaggle/working/data/train/cats\",\n}\n\ntest_dest_directory = \"/kaggle/working/data/test/\"\n\n# ファイルフィルタ関数。\ndef train_file_filter(file, key):\n    return file.startswith(key)\n\ndef test_file_filter(file, key):\n    return file.endswith(\".jpg\")\n\nmove_images(source_directory, train_dest_directories, file_filter=train_file_filter)\nmove_images(test_source_directory, {None: test_dest_directory}, file_filter=test_file_filter)","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:46.239085Z","iopub.execute_input":"2023-09-03T05:58:46.239537Z","iopub.status.idle":"2023-09-03T05:58:47.668833Z","shell.execute_reply.started":"2023-09-03T05:58:46.239494Z","shell.execute_reply":"2023-09-03T05:58:47.667903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TARGET_SIZE = (128, 128)  ","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:47.670029Z","iopub.execute_input":"2023-09-03T05:58:47.670317Z","iopub.status.idle":"2023-09-03T05:58:47.674836Z","shell.execute_reply.started":"2023-09-03T05:58:47.670292Z","shell.execute_reply":"2023-09-03T05:58:47.673930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_data(x, y=None):\n    # 画像データの形状を再構築し、指定のターゲットサイズとチャンネル数を設定。\n    x = tf.reshape(x, (-1, *TARGET_SIZE, 1))\n    # データを0から1の範囲に正規化。\n    x = tf.cast(x, tf.float32) / 255.0\n    if y is not None:\n        # ラベルデータを整数型に変換。\n        y = tf.cast(y, tf.int32)\n        return x, y\n    return x\n\n# 特徴データとラベルデータのリストを作成。\nfeature_data, label_data = [], []","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:47.675895Z","iopub.execute_input":"2023-09-03T05:58:47.676171Z","iopub.status.idle":"2023-09-03T05:58:47.686404Z","shell.execute_reply.started":"2023-09-03T05:58:47.676147Z","shell.execute_reply":"2023-09-03T05:58:47.685621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATADIR = \"/kaggle/working/data/train\"\nTESTDIR = \"/kaggle/working/data/test\"\nCATEGORIES = [\"dogs\", \"cats\"]","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:47.687451Z","iopub.execute_input":"2023-09-03T05:58:47.687732Z","iopub.status.idle":"2023-09-03T05:58:47.695337Z","shell.execute_reply.started":"2023-09-03T05:58:47.687707Z","shell.execute_reply":"2023-09-03T05:58:47.694570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for class_num, category in enumerate(CATEGORIES):\n    path = os.path.join(DATADIR, category)\n    for image_name in os.listdir(path):\n        try:\n            img_file = cv2.imread(os.path.join(path, image_name))\n            \n            # 画像の読み込みが正しくできているか確認。\n            # print(\"Loaded image shape:\", img_file.shape)\n            \n            gray_image = cv2.cvtColor(img_file, cv2.COLOR_BGR2GRAY)\n            \n            # グレースケールへの変換が正しくできているか確認。\n            # print(\"Converted image shape:\", gray_image.shape)\n            \n            resize_file = cv2.resize(gray_image, TARGET_SIZE)\n            \n            feature_data.append(resize_file)\n            label_data.append(class_num)\n        except Exception as e:\n            print(\"Error processing image:\", e)","metadata":{"execution":{"iopub.status.busy":"2023-09-03T05:58:47.696362Z","iopub.execute_input":"2023-09-03T05:58:47.696641Z","iopub.status.idle":"2023-09-03T06:00:15.409501Z","shell.execute_reply.started":"2023-09-03T05:58:47.696616Z","shell.execute_reply":"2023-09-03T06:00:15.408373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(feature_data))\nprint(len(label_data))","metadata":{"execution":{"iopub.status.busy":"2023-09-03T06:00:15.410908Z","iopub.execute_input":"2023-09-03T06:00:15.411231Z","iopub.status.idle":"2023-09-03T06:00:15.416373Z","shell.execute_reply.started":"2023-09-03T06:00:15.411203Z","shell.execute_reply":"2023-09-03T06:00:15.415436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_x, valid_x, train_y, valid_y = train_test_split(\n    np.array(feature_data), np.array(label_data), test_size=0.1, random_state=50\n)","metadata":{"execution":{"iopub.status.busy":"2023-09-03T06:00:15.417420Z","iopub.execute_input":"2023-09-03T06:00:15.417698Z","iopub.status.idle":"2023-09-03T06:00:15.701229Z","shell.execute_reply.started":"2023-09-03T06:00:15.417672Z","shell.execute_reply":"2023-09-03T06:00:15.700277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 32\nEPOCHS = 15 \nNUM_CLASSES = 2","metadata":{"execution":{"iopub.status.busy":"2023-09-03T06:00:15.702359Z","iopub.execute_input":"2023-09-03T06:00:15.702732Z","iopub.status.idle":"2023-09-03T06:00:15.706777Z","shell.execute_reply.started":"2023-09-03T06:00:15.702700Z","shell.execute_reply":"2023-09-03T06:00:15.705840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 訓練データとラベルをTensorSliceDatasetとして読み込む。\ntrain_ds = tf.data.Dataset.from_tensor_slices((train_x, train_y))\nvalid_ds = tf.data.Dataset.from_tensor_slices((valid_x, valid_y))\n\n# データの読み込みと前処理の効率を向上させるため、AUTOTUNEを使用。\nAUTOTUNE = tf.data.experimental.AUTOTUNE\n\n# 訓練データの処理パイプラインを構築\ntrain_ds = (\n    train_ds.shuffle(len(train_x))  # データをシャッフルしてランダム性を増す。\n    .repeat()                        # データセットを繰り返し利用。（エポックごとに繰り返す。）\n    .batch(BATCH_SIZE)               # バッチサイズに分割。\n    .map(convert_data)               # データ変換関数を適用。\n    .prefetch(buffer_size=AUTOTUNE)  # バッファを使用してデータの取得を最適化。\n)\n\n# 検証データの処理パイプラインを構築。\nvalid_ds = valid_ds.batch(BATCH_SIZE)  # バッチサイズに分割。\nvalid_ds = valid_ds.map(convert_data)  # データ変換関数を適用。","metadata":{"execution":{"iopub.status.busy":"2023-09-03T06:00:15.710227Z","iopub.execute_input":"2023-09-03T06:00:15.710500Z","iopub.status.idle":"2023-09-03T06:00:20.357339Z","shell.execute_reply.started":"2023-09-03T06:00:15.710475Z","shell.execute_reply":"2023-09-03T06:00:20.356230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CNN モデル。\nmodel = models.Sequential([\n    layers.Input(shape=(*TARGET_SIZE, 1)),  \n    layers.Conv2D(32, (9, 9), activation='relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(64, (5, 5), activation='relu'),  \n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(128, (3, 3), activation='relu'),  \n    layers.MaxPooling2D((2, 2)),\n    layers.Flatten(),\n    layers.Dense(256, activation='relu'),\n    layers.Dense(NUM_CLASSES, activation='softmax')  \n])\n\nmodel.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\nhistory = model.fit(train_ds, epochs=EPOCHS, validation_data=valid_ds, steps_per_epoch=len(train_x) // BATCH_SIZE)\n","metadata":{"execution":{"iopub.status.busy":"2023-09-03T06:00:20.358613Z","iopub.execute_input":"2023-09-03T06:00:20.358951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_test_data = []\n\n# テストディレクトリ内の各画像ファイルに対して処理を行う。\nfor image_name in os.listdir(TESTDIR):\n    try:\n        # 画像ファイルを読み込み。\n        img_file = cv2.imread(os.path.join(TESTDIR, image_name))\n        # カラー画像をグレースケールに変換。\n        gray_image = cv2.cvtColor(img_file, cv2.COLOR_BGR2GRAY)\n        # 画像サイズをターゲットサイズにリサイズ。\n        resize_file = cv2.resize(gray_image, TARGET_SIZE)\n        # 処理済みの画像データをリストに追加。\n        feature_test_data.append(resize_file)\n    except Exception as e:\n        # エラーが発生した場合、エラーメッセージを表示。\n        print(f\"画像 {image_name} の処理中にエラーが発生しました: {e}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds = tf.data.Dataset.from_tensor_slices(np.array(feature_test_data))\ntest_ds = test_ds.batch(BATCH_SIZE).map(convert_data)\n\ny_pred = model.predict(test_ds)\npredictions = np.argmax(y_pred, axis=1)\n\n# Submission ファイルの作成。\nsubmission = pd.DataFrame({\"id\": range(1, len(predictions) + 1), \"label\": predictions})\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}],"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"}}