{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30732,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-24T12:25:47.173076Z","iopub.execute_input":"2024-07-24T12:25:47.173901Z","iopub.status.idle":"2024-07-24T12:25:48.316367Z","shell.execute_reply.started":"2024-07-24T12:25:47.173865Z","shell.execute_reply":"2024-07-24T12:25:48.315190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ZIPファイルの展開","metadata":{}},{"cell_type":"code","source":"import zipfile\n\n#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":"2024-07-24T12:25:48.318359Z","iopub.execute_input":"2024-07-24T12:25:48.318735Z","iopub.status.idle":"2024-07-24T12:26:05.429719Z","shell.execute_reply.started":"2024-07-24T12:25:48.318709Z","shell.execute_reply":"2024-07-24T12:26:05.428840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 必要なライブラリをインストールする","metadata":{}},{"cell_type":"code","source":"import numpy as np #numpy（Pythonでの機械学習の計算をより速く、効率的に行えるようにする拡張モジュール）\nimport pandas as pd\nimport os\nimport shutil\nimport cv2\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport tensorflow.keras as keras\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import load_model\nimport csv","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:05.430875Z","iopub.execute_input":"2024-07-24T12:26:05.431161Z","iopub.status.idle":"2024-07-24T12:26:18.089887Z","shell.execute_reply.started":"2024-07-24T12:26:05.431136Z","shell.execute_reply":"2024-07-24T12:26:18.088819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# パスを指定する","metadata":{}},{"cell_type":"code","source":"# trainデータのディレクトリのパス\ntrain_dir = '/kaggle/working/train/train'","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:18.092611Z","iopub.execute_input":"2024-07-24T12:26:18.093145Z","iopub.status.idle":"2024-07-24T12:26:18.097465Z","shell.execute_reply.started":"2024-07-24T12:26:18.093102Z","shell.execute_reply":"2024-07-24T12:26:18.096318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# testデータのディレクトリのパス\ntest_dir = '/kaggle/working/test/test'","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:18.098826Z","iopub.execute_input":"2024-07-24T12:26:18.099183Z","iopub.status.idle":"2024-07-24T12:26:18.194508Z","shell.execute_reply.started":"2024-07-24T12:26:18.099151Z","shell.execute_reply":"2024-07-24T12:26:18.193176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 画像のサイズを統一","metadata":{}},{"cell_type":"code","source":"# 画像のサイズ統一\nIMG_SIZE = 64","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:18.199963Z","iopub.execute_input":"2024-07-24T12:26:18.200417Z","iopub.status.idle":"2024-07-24T12:26:18.205952Z","shell.execute_reply.started":"2024-07-24T12:26:18.200380Z","shell.execute_reply":"2024-07-24T12:26:18.204588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# データ読み込みの関数の作成","metadata":{}},{"cell_type":"code","source":"# データを読み込む用の関数\ndef load_data(data_dir, sample_size=1000):\n    images = [] # 写真を入れるリスト\n    labels = [] # その写真のラベル(犬か猫かを判断する)を入れる用のリスト\n    files = os.listdir(data_dir)[:sample_size] # サイズを指定\n#     print(f'（発見） {len(files)} files in {data_dir}')  # デバッグ文\n    for file in files: \n        img_path = os.path.join(data_dir, file) # ディレクトリのパスとファイル名（写真名）をくっつけて（join）、ファイル（写真）のパスを作る。それをimg_pathに入れる\n#         print(f'（ファイル読み込み） {img_path}')  # デバッグ文\n        img = cv2.imread(img_path) \n        if img is not None: \n            img = cv2.resize(img, (IMG_SIZE, IMG_SIZE)) # 写真のサイズを調整\n            images.append(img) # リストの中に一枚ずつ格納\n            label = 1 if 'dog' in file else 0 # 写真が犬なら 1, 猫なら 0とラベル付して\n            labels.append(label) # ラベルをリストに格納\n        else: #　写真がきちんと読み込めていない場合\n            print(f'error {img_path}')  # デバッグ文\n    return np.array(images) / 255.0, np.array(labels) # 戻り値","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:18.208023Z","iopub.execute_input":"2024-07-24T12:26:18.209186Z","iopub.status.idle":"2024-07-24T12:26:18.221354Z","shell.execute_reply.started":"2024-07-24T12:26:18.209139Z","shell.execute_reply":"2024-07-24T12:26:18.219894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# trainデータとtestデータの読み込み","metadata":{}},{"cell_type":"code","source":"X_train, y_train = load_data(train_dir, sample_size=1000)\nX_test, y_test = load_data(test_dir, sample_size=500)","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:18.222843Z","iopub.execute_input":"2024-07-24T12:26:18.223200Z","iopub.status.idle":"2024-07-24T12:26:19.875404Z","shell.execute_reply.started":"2024-07-24T12:26:18.223158Z","shell.execute_reply":"2024-07-24T12:26:19.874339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 読み込まれているか確認","metadata":{}},{"cell_type":"code","source":"# print(f'X_train shape: {X_train.shape}')\n# print(f'y_train shape: {y_train.shape}')\n# print(f'X_test shape: {X_test.shape}')\n# print(f'y_test shape: {y_test.shape}')","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.876932Z","iopub.execute_input":"2024-07-24T12:26:19.877338Z","iopub.status.idle":"2024-07-24T12:26:19.882398Z","shell.execute_reply.started":"2024-07-24T12:26:19.877308Z","shell.execute_reply":"2024-07-24T12:26:19.881325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# データの拡張","metadata":{}},{"cell_type":"code","source":"# 全てランダムに行う\ndatagen = ImageDataGenerator(\n    rotation_range=20, # 画像の回転(最大20度まで)\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)","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.887103Z","iopub.execute_input":"2024-07-24T12:26:19.887585Z","iopub.status.idle":"2024-07-24T12:26:19.893552Z","shell.execute_reply.started":"2024-07-24T12:26:19.887553Z","shell.execute_reply":"2024-07-24T12:26:19.892257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# モデルの作成","metadata":{}},{"cell_type":"markdown","source":"# モデル関数の作成","metadata":{}},{"cell_type":"code","source":"def create_model(neuron):\n    # 必要なライブラリとか関数とかをインポート\n    Dense = keras.layers.Dense\n    Conv2D = keras.layers.Conv2D\n    MaxPooling2D = keras.layers.MaxPooling2D\n    Flatten = keras.layers.Flatten\n    Dropout = keras.layers.Dropout\n    \n    # モデルの定義\n    model = keras.models.Sequential()\n    \n    # 畳み込みのレイヤーを追加\n    \n    # 32個のフィルターと3x3のカーネルサイズを持ってる畳み込みそう。活性化関数はrelu。画像の形状の指定。今回はカラー（赤、青、緑）だから３\n    model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)))\n    # 2x2のプーリング層。空間サイズを半分\n    model.add(MaxPooling2D((2, 2)))\n    \n    # 64個のフィルターと3x3のカーネルサイズを持ってる畳み込みそう\n    model.add(Conv2D(64, (3, 3), activation='relu'))\n    # 2x2のプーリング層。空間サイズを半分\n    model.add(MaxPooling2D((2, 2)))\n    \n    # 128個のフィルターと3x3のカーネルサイズを持ってる畳み込みそう\n    model.add(Conv2D(128, (3, 3), activation='relu'))\n    # 2x2のプーリング層。空間サイズを半分\n    model.add(MaxPooling2D((2, 2)))\n    \n    # 全部の結合そうを追加　　　　　　　　\n    # Flatten(): 3次元の特徴マップを1次元のベクトルに変換\n    model.add(Flatten())\n    # neuron数のユニットを持つ全結合層。\n    model.add(Dense(neuron, activation='relu'))\n    # ドロップアウト正則化。半分のニューロンをランダムに無効。\n    model.add(Dropout(0.5))\n    # 出力層。シグモイド\n    model.add(Dense(1, activation='sigmoid'))\n\n    # モデルをコンパイル\n    # バイナリクロスエントロピー損失関数。Adam。モデルの評価は精度で\n    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n    \n    # モデルを返す\n    return model","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.895497Z","iopub.execute_input":"2024-07-24T12:26:19.895902Z","iopub.status.idle":"2024-07-24T12:26:19.908433Z","shell.execute_reply.started":"2024-07-24T12:26:19.895873Z","shell.execute_reply":"2024-07-24T12:26:19.907050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# モデルの保存","metadata":{}},{"cell_type":"code","source":"def save_model(model, filename):\n    model.save(filename)","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.910069Z","iopub.execute_input":"2024-07-24T12:26:19.910445Z","iopub.status.idle":"2024-07-24T12:26:19.920358Z","shell.execute_reply.started":"2024-07-24T12:26:19.910416Z","shell.execute_reply":"2024-07-24T12:26:19.919374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# モデルをロード","metadata":{}},{"cell_type":"code","source":"def load_existing_model(filename):\n    return load_model(filename)","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.921788Z","iopub.execute_input":"2024-07-24T12:26:19.922148Z","iopub.status.idle":"2024-07-24T12:26:19.931267Z","shell.execute_reply.started":"2024-07-24T12:26:19.922095Z","shell.execute_reply":"2024-07-24T12:26:19.929941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# モデルの学習開始\n学習→評価","metadata":{}},{"cell_type":"code","source":"# 学習し、テストデータで評価し、スコアを表示する関数\ndef fit_epoch(neuron, batch, epochs, initial_epoch=0, model_filename='model.h5'):\n    if initial_epoch == 0: # モデルを作るのが初めての場合\n        # さっき作ったモデル作る関数を実行\n        model = create_model(neuron)\n    else: # すでにモデルを作っている場合\n        model = load_existing_model(model_filename) #モデルの読み込み\n        \n    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n    \n    # モデルを学習\n    hist = model.fit(datagen.flow(X_train, y_train, batch_size=batch),\n                     steps_per_epoch=len(X_train) // batch,\n                     validation_data=(X_test, y_test),\n                     epochs=epochs,\n                     initial_epoch=initial_epoch,\n                     verbose=1)\n    \n    # モデルを評価\n    score = model.evaluate(X_test, y_test, verbose=1)\n    print('正解率=', score[1], 'loss=', score[0])\n    \n    #モデルの保存\n    save_model(model, model_filename)\n    \n    \n    # 学習結果を可視化(グラフ化)\n    \n    # trainデータの精度のグラフ\n    plt.plot(hist.history['accuracy'])\n    # testデータの精度のグラフ\n    plt.plot(hist.history['val_accuracy'])\n    # タイトル\n    plt.title('Accuracy')\n    # 凡例\n    plt.legend(['train', 'test'], loc='upper left')\n    # グラフの表示\n    plt.show()\n\n    # trainデータの損失値のグラフ\n    plt.plot(hist.history['loss'])\n    # testデータの損失値のグラフ\n    plt.plot(hist.history['val_loss'])\n    # タイトル\n    plt.title('Loss')\n    # 凡例\n    plt.legend(['train', 'test'], loc='upper left')\n    # グラフの表示\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.933114Z","iopub.execute_input":"2024-07-24T12:26:19.933676Z","iopub.status.idle":"2024-07-24T12:26:19.945643Z","shell.execute_reply.started":"2024-07-24T12:26:19.933596Z","shell.execute_reply":"2024-07-24T12:26:19.944531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# モデルの作成","metadata":{}},{"cell_type":"code","source":"### total_epochs = 30  # 全体のエポック数\nneuron = 512  # ニューロンの数\nbatch = 8  # バッチサイズ\nmodel_filename = 'model.h5'  # モデルのファイル名","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.947209Z","iopub.execute_input":"2024-07-24T12:26:19.947577Z","iopub.status.idle":"2024-07-24T12:26:19.954785Z","shell.execute_reply.started":"2024-07-24T12:26:19.947546Z","shell.execute_reply":"2024-07-24T12:26:19.953897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 1回目の学習\nfit_epoch(neuron=neuron, batch=batch, epochs=10, initial_epoch=0, model_filename=model_filename)","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:19.956112Z","iopub.execute_input":"2024-07-24T12:26:19.956544Z","iopub.status.idle":"2024-07-24T12:26:42.515350Z","shell.execute_reply.started":"2024-07-24T12:26:19.956491Z","shell.execute_reply":"2024-07-24T12:26:42.514205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 2回目の学習\nfit_epoch(neuron=neuron, batch=batch, epochs=20, initial_epoch=10, model_filename=model_filename)","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:42.517022Z","iopub.execute_input":"2024-07-24T12:26:42.517946Z","iopub.status.idle":"2024-07-24T12:26:59.800693Z","shell.execute_reply.started":"2024-07-24T12:26:42.517903Z","shell.execute_reply":"2024-07-24T12:26:59.799610Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 3回目の学習\nfit_epoch(neuron=neuron, batch=batch, epochs=30, initial_epoch=20, model_filename=model_filename)","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:26:59.804069Z","iopub.execute_input":"2024-07-24T12:26:59.804415Z","iopub.status.idle":"2024-07-24T12:27:16.519902Z","shell.execute_reply.started":"2024-07-24T12:26:59.804386Z","shell.execute_reply":"2024-07-24T12:27:16.518716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 予測結果をCSVファイルに保存","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport cv2\nimport tensorflow.keras as keras\nfrom tensorflow.keras.models import load_model\n\n# 定数の設定\nIMG_SIZE = 64  # 画像のサイズ\ntest_dir = '/kaggle/working/test/test'  # テストデータのディレクトリ\nmodel_filename = 'model.h5'  # 学習したモデルのファイル名\noutput_csv = '/kaggle/working/submission.csv'  # 提出するCSVファイルのパス\n\n# 画像データの読み込み関数\ndef load_test_data(data_dir):\n    images = []\n    filenames = os.listdir(data_dir)\n    for file in filenames:\n        img_path = os.path.join(data_dir, file)\n        img = cv2.imread(img_path)\n        if img is not None:\n            img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n            images.append(img)\n        else:\n            print(f'Error reading {img_path}')\n    return np.array(images) / 255.0, filenames\n\n# テストデータの読み込み\nX_test, test_filenames = load_test_data(test_dir)\n\n# モデルの読み込み\nmodel = load_model(model_filename)\n\n# 予測の実行\npredictions = model.predict(X_test)\n\n# 予測結果を0または1に変換\npredictions = (predictions > 0.5).astype(int).flatten()\n\n# CSVファイルの作成\noutput_df = pd.DataFrame({\n    'id': [os.path.splitext(f)[0] for f in test_filenames],  # ファイル名から拡張子を除去してIDにする\n    'label': predictions\n})\noutput_df.to_csv(output_csv, index=False)\n\nprint(f'CSVファイル {output_csv} を作成しました')\n","metadata":{"execution":{"iopub.status.busy":"2024-07-24T12:29:46.799666Z","iopub.execute_input":"2024-07-24T12:29:46.800349Z","iopub.status.idle":"2024-07-24T12:30:02.653038Z","shell.execute_reply.started":"2024-07-24T12:29:46.800315Z","shell.execute_reply":"2024-07-24T12:30:02.651504Z"},"trusted":true},"execution_count":null,"outputs":[]}]}