{"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":"markdown","source":"# パッケージのインポート\n全体を通して必要なパッケージは，最初にインポートしておく．","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np \nimport glob\nimport shutil","metadata":{"execution":{"iopub.status.busy":"2022-07-28T19:32:10.573128Z","iopub.execute_input":"2022-07-28T19:32:10.573473Z","iopub.status.idle":"2022-07-28T19:32:10.577366Z","shell.execute_reply.started":"2022-07-28T19:32:10.573440Z","shell.execute_reply":"2022-07-28T19:32:10.576528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# データの読み込み\n/kaggle/inputのデータを，/kaggle/workingに読み込む．","metadata":{}},{"cell_type":"code","source":"# '/kaggle/input'に入っているファイルを確認\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n\n# /kaggle/inputのcsvファイルをkaggle/workingにコピー\nshutil.copyfile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv',\n                '/kaggle/working/submission.csv')\n\n\n# /kaggle/inputのzipファイルを/kaggle/workingに解凍\nimport zipfile\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip') as existing_zip:\n    existing_zip.extractall()\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip') as existing_zip:\n    existing_zip.extractall()\n\n\n# '/kaggle/working'に入っているファイルを確認\nfiles = glob.glob('/kaggle/working/*')\nfor file in files:\n    print(file)","metadata":{"execution":{"iopub.status.busy":"2022-07-28T19:32:10.615602Z","iopub.execute_input":"2022-07-28T19:32:10.615964Z","iopub.status.idle":"2022-07-28T19:32:29.349046Z","shell.execute_reply.started":"2022-07-28T19:32:10.615930Z","shell.execute_reply":"2022-07-28T19:32:29.347566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 画像フォルダの中身を確認","metadata":{}},{"cell_type":"code","source":"# /kaggle/working/trainの中身を確認\nfiles = sorted(glob.glob('/kaggle/working/train/*'))# 訓練画像フォルダ\nprint('訓練用フォルダの中には', len(files), '個の訓練用の画像ファイルが入っています．')\n\n# /kaggle/working/testの中身を確認\nfiles = sorted(glob.glob('/kaggle/working/test/*'))# テスト画像フォルダ\nprint('テスト用フォルダの中には', len(files), '個のテスト用の画像ファイルが入っています．')\n\n# 学習させる猫と犬の画像数を確認\nn_cat = 0# 猫の画像数\nn_dog = 0# 犬の画像数\nfiles = glob.glob('/kaggle/working/train/*')# 訓練用フォルダ\nfor file in files:\n    if 'cat' in file:\n        n_cat += 1\n    else:\n        n_dog += 1\nprint('学習させる画像数...')\nprint('猫の画像数：', n_cat, '枚')\nprint('犬の画像数：', n_dog, '枚')","metadata":{"execution":{"iopub.status.busy":"2022-07-28T19:32:29.350647Z","iopub.execute_input":"2022-07-28T19:32:29.351039Z","iopub.status.idle":"2022-07-28T19:32:29.584137Z","shell.execute_reply.started":"2022-07-28T19:32:29.351001Z","shell.execute_reply":"2022-07-28T19:32:29.583161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 犬と猫の画像を，別々のフォルダに保存する\n/kaggle/working/train下に，dogフォルダとcatフォルダを作成し，画像をそれぞれのフォルダにコピーする．","metadata":{}},{"cell_type":"code","source":"from PIL import Image\n\n# 犬・猫の画像を，それぞれ保存するフォルダのパスを定義\ndog_dir = '/kaggle/working/train/dog'\ncat_dir = '/kaggle/working/train/cat'\ntimes = '/kaggle/working/train/times'\ntimes_dog ='/kaggle/working/train/times/dog'\ntimes_cat ='/kaggle/working/train/times/cat'\n# # フォルダの作成\nos.mkdir(dog_dir)\nos.mkdir(cat_dir)\nos.mkdir(times)\nos.mkdir(times_dog)\nos.mkdir(times_cat)\n\n# 犬・猫の画像を，それぞれのフォルダに移動する\nfiles = glob.glob('/kaggle/working/train/*.jpg')# 訓練用フォルダ内の全ファイルパスを取得\nfor file in files:\n    file_name = os.path.basename(file)\n    if 'cat' in file:\n        shutil.move(file,'/kaggle/working/train/cat/' + file_name)\n    else:\n        shutil.move(file,'/kaggle/working/train/dog/' + file_name)\ndir = '/kaggle/working/train/cat/'\nprint(sum(os.path.isfile(os.path.join(dir,name)) for name in os.listdir(dir)))\ndir = '/kaggle/working/train/dog/'\nprint(sum(os.path.isfile(os.path.join(dir,name)) for name in os.listdir(dir)))\n\n\nfiles = glob.glob('/kaggle/working/train/cat/*.jpg')# 訓練用フォルダ内の全ファイルパスを取得\nfor file in files:\n    file_name = os.path.basename(file)\n    shutil.copy(file,'/kaggle/working/train/times/cat/' + file_name)\n\nfiles = glob.glob('/kaggle/working/train/dog/*.jpg')# 訓練用フォルダ内の全ファイルパスを取得\nfor file in files:\n    file_name = os.path.basename(file)\n    shutil.copy(file,'/kaggle/working/train/times/dog/' + file_name)\n\n    \n#im = image.open('/kaggle/working/train/times/cat/*.jpg') \nimage_name = \"cocat_%05d.jpg\"\nfor file in glob.glob('/kaggle/working/train/times/cat/*.jpg'):\n    im = Image.open(file)\n    file_name = os.path.basename(file)\n    for i in range(5):\n        dir = '/kaggle/working/train/times/cat/'\n        copy_im = im.copy()\n        copy_im.save(dir + file_name + image_name % i)\n\nimage_name = \"codog_%05d.jpg\"\nfor file in glob.glob('/kaggle/working/train/times/dog/*.jpg'):\n    im = Image.open(file)\n    file_name = os.path.basename(file)\n    for i in range(5):\n        dir = '/kaggle/working/train/times/dog/'\n        copy_im = im.copy()\n        copy_im.save(dir + file_name + image_name % i)\n        \ndir = '/kaggle/working/train/times/cat/'\nprint(sum(os.path.isfile(os.path.join(dir,name)) for name in os.listdir(dir)))\ndir = '/kaggle/working/train/times/dog/'\nprint(sum(os.path.isfile(os.path.join(dir,name)) for name in os.listdir(dir)))","metadata":{"execution":{"iopub.status.busy":"2022-07-28T21:58:18.987067Z","iopub.execute_input":"2022-07-28T21:58:18.987395Z","iopub.status.idle":"2022-07-28T22:12:21.284635Z","shell.execute_reply.started":"2022-07-28T21:58:18.987362Z","shell.execute_reply":"2022-07-28T22:12:21.283812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 学習中に，学習精度を評価するために，訓練データの一部を訓練に使わず，予測に用いる．\n# この予測のことをバリデーションと言い，データをバリデーションデータと言う．\n\nfrom sklearn.model_selection import train_test_split\ndir = '/kaggle/working/train/times/cat/'\nprint(sum(os.path.isfile(os.path.join(dir,name)) for name in os.listdir(dir)))\n#バリデーションフォルダのパスを定義\nval = '/kaggle/working/val'\nval_dog = '/kaggle/working/val/dog'\nval_cat = '/kaggle/working/val/cat'\n\n# フォルダの作成\nos.mkdir(val)\nos.mkdir(val_dog)\nos.mkdir(val_cat)\n\n# 訓練画像の一部を，バリデーションフォルダに移動する(犬)\ndog_files = glob.glob('/kaggle/working/train/dog/*.jpg')\ndog_train, dog_val = train_test_split(dog_files, test_size=0.2, random_state=42)\n# 画像の一部をバリデーションフォルダに移動する\nfor file in dog_val:\n    file_name = os.path.basename(file)\n    shutil.move(file,'/kaggle/working/val/dog/' + file_name)\n\n# 訓練画像の一部を，バリデーションフォルダに移動する(猫)\ncat_files = glob.glob('/kaggle/working/train/cat/*.jpg')\ncat_train, cat_val = train_test_split(cat_files, test_size=0.2, random_state=42)\n# 画像の一部をバリデーションフォルダに移動する\nfor file in cat_val:\n    file_name = os.path.basename(file)\n    shutil.move(file,'/kaggle/working/val/cat/' + file_name)\n    ","metadata":{"execution":{"iopub.status.busy":"2022-07-28T21:57:38.836726Z","iopub.execute_input":"2022-07-28T21:57:38.837168Z","iopub.status.idle":"2022-07-28T21:57:39.955991Z","shell.execute_reply.started":"2022-07-28T21:57:38.837127Z","shell.execute_reply":"2022-07-28T21:57:39.954000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 学習モデルの定義\n学習させるモデルの構成を定義する\n","metadata":{}},{"cell_type":"code","source":"import tensorflow.keras.layers as layers\nfrom keras import layers, models, optimizers\nmodel = models.Sequential()\nmodel.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(150,150,3)))\nmodel.add(layers.MaxPooling2D((2,2)))\n \nmodel.add(layers.Conv2D(64,(3,3),activation='relu'))\nmodel.add(layers.MaxPooling2D((2,2)))\n \nmodel.add(layers.Conv2D(128,(3,3),activation='relu'))\nmodel.add(layers.MaxPooling2D((2,2)))\n \nmodel.add(layers.Conv2D(128,(3,3),activation='relu'))\nmodel.add(layers.MaxPooling2D((2,2)))\n\nmodel.add(layers.Flatten())\n \nmodel.add(layers.Dense(512,activation='relu'))\nmodel.add(layers.Dense(1,activation='sigmoid'))\n\nmodel.compile(loss='binary_crossentropy',\n             optimizer=optimizers.RMSprop(lr=1e-4),\n             metrics=['acc'])\n \nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-28T19:32:30.510924Z","iopub.status.idle":"2022-07-28T19:32:30.511694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 訓練データの前処理","metadata":{}},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n#データの正規化 \ntrain_datagen = ImageDataGenerator(rescale=1./255, # 255で割ることで正規化\n                                    zoom_range=0.2, # ランダムにズーム\n                                    horizontal_flip=True, # 水平反転\n                                    rotation_range=40, # ランダムに回転\n                                    vertical_flip=True) # 垂直反転\n\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\n#訓練データ\ntrain_dir = ('/kaggle/working/train/times') \n#教師データ\nvalidation_dir = ('/kaggle/working/val') \n#    class_mode='binary''input'    color_mode = 'grayscale'\nvalidation_generator = validation_datagen.flow_from_directory(\n    validation_dir,\n    target_size=(150,150),\n    batch_size=32,\n    class_mode='binary'\n)\n\ntrain_generator = train_datagen.flow_from_directory(\n     train_dir,\n     target_size=(150,150),\n     batch_size=32,\n     class_mode='binary'\n)\n\nimport numpy as np\nimport matplotlib.pyplot as plt\n# 1バッチ分取り出す(64個の画像）\nitems = next(iter(train_generator))\n\nplt.figure(figsize=(12,12))\nfor i, image in enumerate(items[0][:25], 1):\n    plt.subplot(5,5,i)\n    plt.imshow(image)\n    plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2022-07-28T19:32:30.513086Z","iopub.status.idle":"2022-07-28T19:32:30.513957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 学習\nモデルを使って，訓練画像をする．","metadata":{}},{"cell_type":"code","source":"#学習\nnum_data_train_dog = len(os.listdir('/kaggle/working/train/times/dog'))\nnum_data_train_cat = len(os.listdir('/kaggle/working/train/times/cat'))\nnum_data_train = num_data_train_dog + num_data_train_cat\nnum_data_valid_dog = len(os.listdir('/kaggle/working/val/dog'))\nnum_data_valid_cat = len(os.listdir('/kaggle/working/val/cat'))\nnum_data_valid = num_data_valid_dog + num_data_valid_cat\nprint(num_data_train)\nprint(num_data_valid)\n\nhistory = model.fit(train_generator,\n                    steps_per_epoch=num_data_train/32,\n                    epochs=20,\n                    validation_data=validation_generator,\n                    validation_steps=num_data_valid/32)\n#学習済みモデルの保存\nmodel.save(\"/kaggle/working/dog_cat.h5\")\n\n# DIR = '/kaggle/working/val/dog'\n# import os\n\n# print(sum(os.path.isfile(os.path.join(DIR, name)) for name in os.listdir(DIR)))\nprint()","metadata":{"execution":{"iopub.status.busy":"2022-07-28T19:32:30.515357Z","iopub.status.idle":"2022-07-28T19:32:30.516166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 予測\n学習済みモデルを使って，テスト画像を予測する","metadata":{}},{"cell_type":"code","source":"import re\nimport csv\nfrom keras.preprocessing import image\n\n# テスト画像のパスを取得\np = re.compile(r'\\d+')\ntest_list = glob.glob('/kaggle/working/test/*.jpg')# 全画像ファイルのパスを読み込み\ntest_list = sorted(test_list,key=lambda s: int(p.search(s).group()))# ソート\n\n#学習済みモデルの読み込み\nmodel = models.load_model('/kaggle/working/dog_cat.h5')\n\nimcount = 0# 画像の数をカウント\n\n# csvファイルを開く\nwith open('/kaggle/working/submission.csv', 'w') as f:\n    writer= csv.writer(f, lineterminator='\\n')\n    writer.writerow(['id', 'label'])\n    \n    # テスト画像ごとに予測し，予測結果をcsvファイルに書き込んでいく\n    for test in test_list:# 1画像ずつ繰り返す\n        print(imcount)\n        # 画像の読み込み\n        img = image.load_img(test, target_size=(150, 150))# 画像を読み込み，150×150にリサイズ\n        \n        # 画像を変形\n        x = image.img_to_array(img)# 画像をnumpy型(行列型)に変更\n        x = np.expand_dims(x, axis=0)# 1次元増やす\n        x = x / 255.0# 正規化(全値を0～1の数値に変換)←モデルに入力する際はこの形\n        \n        # 予測\n        result_predict = model.predict(x)\n        \n        # 予測結果をcsvファイルに書き込み\n        imcount += 1\n        writer.writerow([imcount, result_predict[0][0]])\n        print('結果',[imcount, result_predict[0][0]])\n","metadata":{"execution":{"iopub.status.busy":"2022-07-28T19:32:30.517500Z","iopub.status.idle":"2022-07-28T19:32:30.518328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}