{"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":"code","source":"#ライブラリのインポート\nimport numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport random #ランダム関数（乱数を生成）\nimport tensorflow as tf #機械学習に必要な諸演算を行うライブラリ\nfrom tensorflow import keras #tensorflowというライブラリに含まれるkerasをインポート\nimport os #osに依存した機能を使用可能\nfrom keras import layers #関数ライブラリが使用可能に\nfrom keras import models #モデル(CNN)\nfrom keras.layers import Dropout #過学習を抑制(CNNの中間層ノードの一部を不活性化)\nfrom keras import optimizers #最適化アルゴリズム\nfrom sklearn.model_selection  import train_test_split #データを訓練用とテスト用に分割\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator #データ拡張","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:15:09.462752Z","iopub.execute_input":"2023-07-25T03:15:09.463188Z","iopub.status.idle":"2023-07-25T03:15:16.190758Z","shell.execute_reply.started":"2023-07-25T03:15:09.463096Z","shell.execute_reply":"2023-07-25T03:15:16.189673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#データ（zipファイル)の解凍\n! unzip -qq \"../input/dogs-vs-cats/test1.zip\"  \n! unzip -qq \"../input/dogs-vs-cats/train.zip\"","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:15:47.899092Z","iopub.execute_input":"2023-07-25T03:15:47.899490Z","iopub.status.idle":"2023-07-25T03:16:08.219732Z","shell.execute_reply.started":"2023-07-25T03:15:47.899456Z","shell.execute_reply":"2023-07-25T03:16:08.217963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#訓練データの犬・猫の画像をいくつか確認\nfilenames = os.listdir('./train/')\nfor i in range(2):\n    picture = np.array(plt.imread(os.path.join('./train',random.choice(filenames))))\n    plt.imshow(picture)\n    plt.show()\n    plt.figure()","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:16:25.508110Z","iopub.execute_input":"2023-07-25T03:16:25.508485Z","iopub.status.idle":"2023-07-25T03:16:26.044231Z","shell.execute_reply.started":"2023-07-25T03:16:25.508452Z","shell.execute_reply":"2023-07-25T03:16:26.043182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#訓練データのデータフレームを作成\ncategories = []\nfor filename in filenames:\n    category= filename.split('.')[0]\n    if category == 'cat':\n        categories.append('0')\n    else:\n        categories.append('1')\n\ndf = pd.DataFrame({'filename':filenames,'category':categories})\nprint('df.shape:',df.shape)\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:19:10.579072Z","iopub.execute_input":"2023-07-25T03:19:10.579484Z","iopub.status.idle":"2023-07-25T03:19:10.623376Z","shell.execute_reply.started":"2023-07-25T03:19:10.579450Z","shell.execute_reply":"2023-07-25T03:19:10.622432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#訓練データ内の犬・猫の割合\nprint('Number of dogs in the train dataset:',df.category[df.category=='1'].count())\nprint('Number of cats in the train dataset:',df.category[df.category=='0'].count())\ndf['category'].value_counts().plot.bar(color=['pink','orange'])","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:19:19.868085Z","iopub.execute_input":"2023-07-25T03:19:19.868475Z","iopub.status.idle":"2023-07-25T03:19:20.094172Z","shell.execute_reply.started":"2023-07-25T03:19:19.868439Z","shell.execute_reply":"2023-07-25T03:19:20.093100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#モデルの構築（CNN）\nImage_Size = (256,256) #CNNに入力する画像サイズ\nChannel_Size = 3 #カーネル幅\nBatch_Size = 64 #1回の計算で扱うデータ数\n\ndef create_model():\n    model = models.Sequential() #Sequentialモデル\n    model.add(layers.Conv2D(32, (3, 3), activation='relu',\n                            input_shape=(256,256,3))) #畳み込み層１\n    model.add(layers.MaxPooling2D((2, 2))) #プーリング層１\n    \n    model.add(layers.Conv2D(64, (3, 3), activation='relu'))#畳み込み層２\n    model.add(layers.MaxPooling2D((2, 2))) #プーリング層２\n    \n    \n    model.add(layers.Conv2D(128, (3, 3), activation='relu')) #畳み込み層３\n    model.add(layers.MaxPooling2D((2, 2))) #プーリング層３\n    \n    model.add(layers.Conv2D(256, (3, 3), activation='relu')) #畳み込み層４\n    model.add(layers.MaxPooling2D((2, 2))) #プーリング層４\n    \n    \n    model.add(layers.Flatten()) #平滑化\n    model.add(layers.Dense(128,activation='relu')) #全結合層１\n    model.add(Dropout(0.2)) #中間層ノードの２割を不活性化\n    \n    model.add(layers.Dense(256,activation='relu')) #全結合層２\n    model.add(Dropout(0.5)) #中間層ノードの５割を不活性化\n    \n    model.add(layers.Dense(2, activation='softmax')) #全結合３\n    \n    model.compile(loss='categorical_crossentropy', #モデルのコンパイル\n              optimizer='rmsprop',\n              metrics=['accuracy'],)\n    return model\n\nmy_model = create_model()","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:20:33.418768Z","iopub.execute_input":"2023-07-25T03:20:33.419163Z","iopub.status.idle":"2023-07-25T03:20:36.200852Z","shell.execute_reply.started":"2023-07-25T03:20:33.419129Z","shell.execute_reply":"2023-07-25T03:20:36.199823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#モデルの詳細\nmy_model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:20:41.698497Z","iopub.execute_input":"2023-07-25T03:20:41.699256Z","iopub.status.idle":"2023-07-25T03:20:41.707609Z","shell.execute_reply.started":"2023-07-25T03:20:41.699215Z","shell.execute_reply":"2023-07-25T03:20:41.706504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#データを分割(2.5万枚の画像データ⇒訓練データ(2万枚)、バリデーションデータ(5000枚))\ntrain_df, validation_df = train_test_split(df, test_size=0.2, random_state=45)\ntrain_df = train_df.reset_index(drop=True)\nvalidation_df = validation_df.reset_index(drop=True)\nprint(f'train_df.shpae:{train_df.shape} & validation_df.shape:{validation_df.shape}')","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:20:53.768565Z","iopub.execute_input":"2023-07-25T03:20:53.769007Z","iopub.status.idle":"2023-07-25T03:20:53.785015Z","shell.execute_reply.started":"2023-07-25T03:20:53.768972Z","shell.execute_reply":"2023-07-25T03:20:53.783919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 過学習を避けるためにデータ拡張を行う\n\n# 訓練データのImageDataGeneratorを作成:\ntrain_datagen = ImageDataGenerator(\n    rotation_range=15, #ランダムに回転\n    rescale=1./255, #255で割ることで正規化\n    shear_range=0.1, #シアー変換(斜めに歪ませる?)\n    zoom_range=0.4, #ランダムにズーム\n    horizontal_flip=True) #水平反転\n\n#データフレームから画像を読み取る\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df,\n    './train',\n    x_col='filename',\n    y_col='category',\n    target_size=Image_Size,\n    class_mode='categorical',\n    batch_size=Batch_Size\n)\n\n\n#バリデーション（検証)データのImageDataGeneratorを作成:\nvalidation_datagen = ImageDataGenerator(\n    rescale=1./255)\n\nvalidation_generator = train_datagen.flow_from_dataframe(\n    validation_df,\n    './train',\n    x_col='filename',\n    y_col='category',\n    target_size=Image_Size,\n    class_mode='categorical',\n    batch_size=Batch_Size\n)\n","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:21:33.283412Z","iopub.execute_input":"2023-07-25T03:21:33.283822Z","iopub.status.idle":"2023-07-25T03:21:33.583733Z","shell.execute_reply.started":"2023-07-25T03:21:33.283787Z","shell.execute_reply":"2023-07-25T03:21:33.582621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#モデルの学習\nHistory = my_model.fit(\n    train_generator,\n    epochs=10, #学習回数\n    validation_data=(validation_generator),\n    batch_size = Batch_Size\n)","metadata":{"execution":{"iopub.status.busy":"2023-07-25T03:21:50.043122Z","iopub.execute_input":"2023-07-25T03:21:50.043505Z","iopub.status.idle":"2023-07-25T04:32:41.158771Z","shell.execute_reply.started":"2023-07-25T03:21:50.043470Z","shell.execute_reply":"2023-07-25T04:32:41.157570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#折れ線グラフによる学習結果の表示\naccuracy = History.history['accuracy']\nval_accuracy = History.history['val_accuracy']\nloss = History.history['loss']\nval_loss = History.history['val_loss']\n\nepochs = range(len(accuracy))\n\nplt.plot(epochs,accuracy, label='accuracy',color='red')\nplt.plot(epochs,val_accuracy, label='val_accuracy',color='pink')\nplt.title('Training and validation accuracy')\nplt.legend()\nplt.figure()\n\nplt.plot(epochs,loss,label='loss',color='blue')\nplt.plot(epochs,val_loss,label='val_loss',color='lightblue')\nplt.title('Training and validation loss')\nplt.legend()\nplt.figure()","metadata":{"execution":{"iopub.status.busy":"2023-07-25T04:34:29.571740Z","iopub.execute_input":"2023-07-25T04:34:29.572137Z","iopub.status.idle":"2023-07-25T04:34:30.031485Z","shell.execute_reply.started":"2023-07-25T04:34:29.572101Z","shell.execute_reply":"2023-07-25T04:34:30.030576Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#テストデータのデータフレームを作成\ntest_filenames = os.listdir('./test1/')\ntest_df = pd.DataFrame({'filename':test_filenames})\nprint('test_df.shape:',test_df.shape)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-07-25T04:34:43.571431Z","iopub.execute_input":"2023-07-25T04:34:43.572203Z","iopub.status.idle":"2023-07-25T04:34:43.595811Z","shell.execute_reply.started":"2023-07-25T04:34:43.572163Z","shell.execute_reply":"2023-07-25T04:34:43.594769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#テストデータフレームから画像データを読み\ntest_datagen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_datagen.flow_from_dataframe(\n    test_df, \n    \"./test1/\", \n    x_col='filename',\n    y_col=None,\n    class_mode=None,\n    target_size=Image_Size,\n    batch_size=Batch_Size,\n    shuffle=False\n)","metadata":{"execution":{"iopub.status.busy":"2023-07-25T04:34:47.171396Z","iopub.execute_input":"2023-07-25T04:34:47.172167Z","iopub.status.idle":"2023-07-25T04:34:47.301964Z","shell.execute_reply.started":"2023-07-25T04:34:47.172115Z","shell.execute_reply":"2023-07-25T04:34:47.300202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#テストデータによる予測\nPredict = my_model.predict(test_generator)\n# 予測結果(1 or 0)をカテゴリ列としてデータフレーム\"test_df\"に追加 \ntest_df['category'] = np.argmax(Predict, axis=-1)","metadata":{"execution":{"iopub.status.busy":"2023-07-25T04:37:15.631496Z","iopub.execute_input":"2023-07-25T04:37:15.632274Z","iopub.status.idle":"2023-07-25T04:38:09.051083Z","shell.execute_reply.started":"2023-07-25T04:37:15.632234Z","shell.execute_reply":"2023-07-25T04:38:09.049881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#最終結果の提出\nsubmission_df = test_df.copy()\nsubmission_df['id'] = submission_df['filename'].str.split('.').str[0]\nsubmission_df['label'] = submission_df['category']\nsubmission_df.drop(['filename', 'category'], axis=1, inplace=True)\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-07-25T04:40:03.522697Z","iopub.execute_input":"2023-07-25T04:40:03.523137Z","iopub.status.idle":"2023-07-25T04:40:03.582568Z","shell.execute_reply.started":"2023-07-25T04:40:03.523102Z","shell.execute_reply":"2023-07-25T04:40:03.581522Z"},"trusted":true},"execution_count":null,"outputs":[]}]}