{"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":"# 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":"2023-07-30T01:39:58.730218Z","iopub.execute_input":"2023-07-30T01:39:58.730564Z","iopub.status.idle":"2023-07-30T01:39:58.751719Z","shell.execute_reply.started":"2023-07-30T01:39:58.730533Z","shell.execute_reply":"2023-07-30T01:39:58.750442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-30T01:39:58.753830Z","iopub.execute_input":"2023-07-30T01:39:58.754475Z","iopub.status.idle":"2023-07-30T01:40:09.688151Z","shell.execute_reply.started":"2023-07-30T01:39:58.754441Z","shell.execute_reply":"2023-07-30T01:40:09.686986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#データ（zipファイル)の解凍\n!unzip /kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip\n!unzip /kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip","metadata":{"execution":{"iopub.status.busy":"2023-07-30T01:40:09.689927Z","iopub.execute_input":"2023-07-30T01:40:09.690937Z","iopub.status.idle":"2023-07-30T01:40:29.166141Z","shell.execute_reply.started":"2023-07-30T01:40:09.690897Z","shell.execute_reply":"2023-07-30T01:40:29.164972Z"},"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-30T01:40:29.170707Z","iopub.execute_input":"2023-07-30T01:40:29.171978Z","iopub.status.idle":"2023-07-30T01:40:29.910779Z","shell.execute_reply.started":"2023-07-30T01:40:29.171927Z","shell.execute_reply":"2023-07-30T01:40:29.909862Z"},"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-30T01:40:29.912264Z","iopub.execute_input":"2023-07-30T01:40:29.913066Z","iopub.status.idle":"2023-07-30T01:40:29.961417Z","shell.execute_reply.started":"2023-07-30T01:40:29.913028Z","shell.execute_reply":"2023-07-30T01:40:29.960457Z"},"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-30T01:40:29.962743Z","iopub.execute_input":"2023-07-30T01:40:29.964992Z","iopub.status.idle":"2023-07-30T01:40:30.235757Z","shell.execute_reply.started":"2023-07-30T01:40:29.964957Z","shell.execute_reply":"2023-07-30T01:40:30.234848Z"},"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-30T01:40:30.237445Z","iopub.execute_input":"2023-07-30T01:40:30.237990Z","iopub.status.idle":"2023-07-30T01:40:35.051160Z","shell.execute_reply.started":"2023-07-30T01:40:30.237952Z","shell.execute_reply":"2023-07-30T01:40:35.050119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#モデルの詳細\nmy_model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-07-30T01:40:35.052971Z","iopub.execute_input":"2023-07-30T01:40:35.053366Z","iopub.status.idle":"2023-07-30T01:40:35.095733Z","shell.execute_reply.started":"2023-07-30T01:40:35.053331Z","shell.execute_reply":"2023-07-30T01:40:35.094966Z"},"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-30T01:40:35.099113Z","iopub.execute_input":"2023-07-30T01:40:35.099822Z","iopub.status.idle":"2023-07-30T01:40:35.125075Z","shell.execute_reply.started":"2023-07-30T01:40:35.099783Z","shell.execute_reply":"2023-07-30T01:40:35.124204Z"},"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)","metadata":{"execution":{"iopub.status.busy":"2023-07-30T01:40:35.126156Z","iopub.execute_input":"2023-07-30T01:40:35.126679Z","iopub.status.idle":"2023-07-30T01:40:35.443353Z","shell.execute_reply.started":"2023-07-30T01:40:35.126645Z","shell.execute_reply":"2023-07-30T01:40:35.442267Z"},"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-30T01:40:35.444755Z","iopub.execute_input":"2023-07-30T01:40:35.445184Z","iopub.status.idle":"2023-07-30T02:49:45.761626Z","shell.execute_reply.started":"2023-07-30T01:40:35.445149Z","shell.execute_reply":"2023-07-30T02:49:45.760547Z"},"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-30T02:49:45.763703Z","iopub.execute_input":"2023-07-30T02:49:45.764099Z","iopub.status.idle":"2023-07-30T02:49:46.445430Z","shell.execute_reply.started":"2023-07-30T02:49:45.764061Z","shell.execute_reply":"2023-07-30T02:49:46.444513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#テストデータのデータフレームを作成\ntest_filenames = os.listdir('./test/')\ntest_df = pd.DataFrame({'filename':test_filenames})\nprint('test_df.shape:',test_df.shape)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-07-30T02:49:46.448310Z","iopub.execute_input":"2023-07-30T02:49:46.448585Z","iopub.status.idle":"2023-07-30T02:49:46.469743Z","shell.execute_reply.started":"2023-07-30T02:49:46.448560Z","shell.execute_reply":"2023-07-30T02:49:46.468576Z"},"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    \"./test/\", \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-30T02:49:46.471277Z","iopub.execute_input":"2023-07-30T02:49:46.471612Z","iopub.status.idle":"2023-07-30T02:49:46.599877Z","shell.execute_reply.started":"2023-07-30T02:49:46.471580Z","shell.execute_reply":"2023-07-30T02:49:46.598976Z"},"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-30T02:49:46.601276Z","iopub.execute_input":"2023-07-30T02:49:46.601596Z","iopub.status.idle":"2023-07-30T02:50:28.352223Z","shell.execute_reply.started":"2023-07-30T02:49:46.601564Z","shell.execute_reply":"2023-07-30T02:50:28.351152Z"},"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-30T02:50:28.353520Z","iopub.execute_input":"2023-07-30T02:50:28.353886Z","iopub.status.idle":"2023-07-30T02:50:28.415956Z","shell.execute_reply.started":"2023-07-30T02:50:28.353852Z","shell.execute_reply":"2023-07-30T02:50:28.415041Z"},"trusted":true},"execution_count":null,"outputs":[]}]}