{"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-21T05:43:27.014491Z","iopub.execute_input":"2023-07-21T05:43:27.015098Z","iopub.status.idle":"2023-07-21T05:43:27.027192Z","shell.execute_reply.started":"2023-07-21T05:43:27.015027Z","shell.execute_reply":"2023-07-21T05:43:27.026008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install py7zr\nimport numpy as np\nimport sys\n%matplotlib inline\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom keras.datasets import cifar10\nfrom tensorflow.keras.models import Sequential,Model\nfrom tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization,Input\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D,GlobalAveragePooling2D,Resizing\nfrom tensorflow.keras import backend as K\nfrom sklearn.model_selection import train_test_split\nimport glob\nimport cv2\nimport py7zr\nimport re","metadata":{"execution":{"iopub.status.busy":"2023-07-21T05:43:27.029609Z","iopub.execute_input":"2023-07-21T05:43:27.030522Z","iopub.status.idle":"2023-07-21T05:43:39.417994Z","shell.execute_reply.started":"2023-07-21T05:43:27.030451Z","shell.execute_reply":"2023-07-21T05:43:39.416805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"グラフのベース設定\"\"\"\ndef basic_setting(figsize):\n    ##---グラフのサイズ  (12cm x 18cm 標準)---\n    plt.figure(figsize=figsize,constrained_layout=True)\n\n    #---Ticks--- numberof ticks and character size,,, can be changed.\n    plt.tick_params(which =\"major\",direction='in',axis='both',top='True',right='True',\\\n                    pad=5,length=3.5,     width=None)\n    plt.tick_params(which =\"minor\",direction='in',axis='both',top='True',right='True'\\\n                    ,pad=5,length=1.5, width=None)\n    plt.xticks(fontsize=14) #___xTicks Interval Setting\n    plt.yticks(fontsize=14) #___yTicks Interval Setting\n    #plt.minorticks_on()\n\n    #---Grids---\n    plt.grid(True,which =\"major\",color='k',linewidth=0.3,linestyle='--')\n    plt.grid(True,which =\"minor\",color='k',linewidth=0.1,linestyle='--')\n\n    #---Frame Line Width---\n    plt.gca().spines['top'].set_linewidth(1.0)\n    plt.gca().spines['bottom'].set_linewidth(1.0)\n    plt.gca().spines['right'].set_linewidth(1.0)\n    plt.gca().spines['left'].set_linewidth(1.0)","metadata":{"execution":{"iopub.status.busy":"2023-07-21T05:43:39.420207Z","iopub.execute_input":"2023-07-21T05:43:39.42061Z","iopub.status.idle":"2023-07-21T05:43:39.430873Z","shell.execute_reply.started":"2023-07-21T05:43:39.420572Z","shell.execute_reply":"2023-07-21T05:43:39.429765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#データセットを解凍(結構時間かかります)\ntemp_path = '/kaggle/working/temp/'\nif not os.path.exists(temp_path):\n    os.mkdir(temp_path)\n\n#訓練データ解凍\ntrain_file_path = '../input/cifar-10/train.7z'\narchive = py7zr.SevenZipFile(train_file_path, mode='r')\narchive.extractall(path=temp_path)\narchive.close()\n\n#テストデータ解凍\ntrain_file_path = '../input/cifar-10/test.7z'\narchive = py7zr.SevenZipFile(train_file_path, mode='r')\narchive.extractall(path=temp_path)\narchive.close()","metadata":{"execution":{"iopub.status.busy":"2023-07-21T05:43:39.433841Z","iopub.execute_input":"2023-07-21T05:43:39.434185Z","iopub.status.idle":"2023-07-21T06:04:23.759121Z","shell.execute_reply.started":"2023-07-21T05:43:39.434157Z","shell.execute_reply":"2023-07-21T06:04:23.757978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def atoi(text):\n    return int(text) if text.isdigit() else text\n\ndef natural_keys(text):\n    return [ atoi(c) for c in re.split(r'(\\d+)', text) ]","metadata":{"execution":{"iopub.status.busy":"2023-07-21T06:04:23.760588Z","iopub.execute_input":"2023-07-21T06:04:23.761578Z","iopub.status.idle":"2023-07-21T06:04:23.767985Z","shell.execute_reply.started":"2023-07-21T06:04:23.761541Z","shell.execute_reply":"2023-07-21T06:04:23.766739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#回答した画像を取得\nimages_train = sorted(glob.glob('/kaggle/working/temp/train/*.png'), key=natural_keys)\nimages_test = sorted(glob.glob('/kaggle/working//temp/test/*.png'), key=natural_keys)\nprint(len(images_train))\nprint(len(images_test))","metadata":{"execution":{"iopub.status.busy":"2023-07-21T06:04:23.769695Z","iopub.execute_input":"2023-07-21T06:04:23.770046Z","iopub.status.idle":"2023-07-21T06:04:27.719468Z","shell.execute_reply.started":"2023-07-21T06:04:23.770004Z","shell.execute_reply":"2023-07-21T06:04:27.718394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#訓練データのラベル取得\ntrain_labels = pd.read_csv('../input/cifar-10/trainLabels.csv')\ntrain_labels['label']","metadata":{"execution":{"iopub.status.busy":"2023-07-21T06:04:27.720936Z","iopub.execute_input":"2023-07-21T06:04:27.721608Z","iopub.status.idle":"2023-07-21T06:04:27.75166Z","shell.execute_reply.started":"2023-07-21T06:04:27.72157Z","shell.execute_reply":"2023-07-21T06:04:27.750708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ラベルの整数、文字列変換を便利にする\nLABEL_LIST = ['frog', 'truck', 'deer', 'automobile', 'bird', 'horse', 'ship','cat', 'dog', 'airplane']\nid2cat = dict(zip(list(range(len(LABEL_LIST))), LABEL_LIST))\ncat2id = dict(zip(LABEL_LIST, list(range(len(LABEL_LIST)))))\nprint(id2cat)\nprint(cat2id)","metadata":{"execution":{"iopub.status.busy":"2023-07-21T06:04:27.753234Z","iopub.execute_input":"2023-07-21T06:04:27.753977Z","iopub.status.idle":"2023-07-21T06:04:27.762225Z","shell.execute_reply.started":"2023-07-21T06:04:27.75394Z","shell.execute_reply":"2023-07-21T06:04:27.761144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#画像を読み込む(ちょっと時間かかります)\nx_train = []\ny_list = []\nx_test = []\ny_test = []\n\n\n#訓練データを読み込み&ラベル付け\nfor img in images_train:\n    label = train_labels.iloc[int(img[27:-4])-1]['label']\n    img_arr = cv2.imread(img)\n    x_train.append(list(img_arr))\n    y_list.append(label)\n    \n#テストデータを読み込み\nfor img in images_test:\n    img_arr = cv2.imread(img)\n    x_test.append(list(img_arr))","metadata":{"execution":{"iopub.status.busy":"2023-07-21T06:04:27.763722Z","iopub.execute_input":"2023-07-21T06:04:27.764085Z","iopub.status.idle":"2023-07-21T06:05:10.161912Z","shell.execute_reply.started":"2023-07-21T06:04:27.764052Z","shell.execute_reply":"2023-07-21T06:05:10.16084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ラベルを文字列から整数に変換\ny_train = pd.DataFrame(y_list, columns=['id'])\n\nprint(y_train)\n\ny_train = y_train['id'].map(cat2id)\ny_train = y_train.values.tolist()","metadata":{"execution":{"iopub.status.busy":"2023-07-21T06:05:10.167528Z","iopub.execute_input":"2023-07-21T06:05:10.167847Z","iopub.status.idle":"2023-07-21T06:05:10.190397Z","shell.execute_reply.started":"2023-07-21T06:05:10.167819Z","shell.execute_reply":"2023-07-21T06:05:10.189141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''データセットの読み込み'''\n#(x_train, y_train), (x_test, y_test) = cifar10.load_data()\nprint(np.unique(y_train,return_counts=True))\n#トレーニングデータの分割\n#50000データのうち80％をトレーニングデータ,20%をバリデーションデータ(検証用データ)に分割\n#分割時に各クラスの比が同一になるように分割,random seedは0とする\nx_train, x_val, y_train, y_val = train_test_split(x_train, y_train,\n                                                  test_size=0.2,\n                                                  random_state=0,\n                                                  stratify=y_train)\n\n#クラスに含まれる数の表示\nprint(np.unique(y_train,return_counts=True))\nprint(np.unique(y_val,return_counts=True))\n\n'''クラス数'''\nnum_classes=10\n\n'''one-hotベクトル化'''\n#y_train = keras.utils.to_categorical(y_train, num_classes)\n#y_val = keras.utils.to_categorical(y_val, num_classes)\n#y_test = keras.utils.to_categorical(y_test, num_classes)\n\ny_train = pd.get_dummies(y_train, columns=['LABEL_LIST']).values\ny_val = pd.get_dummies(y_val, columns=['LABEL_LIST']).values\ny_test = pd.get_dummies(y_test, columns=['LABEL_LIST']).values\n\n'''データ正規化'''\nx_train = np.array(x_train, dtype=np.float32)\nx_val = np.array(x_val, dtype=np.float32)\nx_test = np.array(x_test, dtype=np.float32)\nx_train=x_train.astype('float32')\nx_train/=255\nx_val=x_val.astype('float32')\nx_val/=255\nx_test=x_test.astype('float32')\nx_test/=255\n\n'''shape表示'''\nprint(\"x_train : \", x_train.shape)\nprint(\"y_train : \", y_train.shape)\nprint(\"x_validation : \", x_val.shape)\nprint(\"y_validation : \", y_val.shape)\nprint(\"x_test : \", x_test.shape)\n#print(\"y_test : \", y_test.shape)","metadata":{"execution":{"iopub.status.busy":"2023-07-21T06:05:10.191949Z","iopub.execute_input":"2023-07-21T06:05:10.192938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#バッチサイズの決定　今回は64\nbatch_size=64","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#トーレニングデータに対してデータ拡張を行う\n#ランダムに0-20度傾け,ランダムに横方向,縦方向に20％平行移動,\n#シアー変換(剪断変換)，ランダムにズームする，水平方向,垂直方向にランダムに反転\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\ndatagen = ImageDataGenerator(\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.1,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    vertical_flip = True,\n    )\n\ntrain_generator = datagen.flow(\n    x_train,\n    y_train,\n    batch_size=batch_size,\n    )\nval_datagen = ImageDataGenerator()\nval_generator = val_datagen.flow(\n    x_val,\n    y_val,\n    batch_size=batch_size,\n    )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#トレーニングデータの表示\n#画像が変換されていることがわかる\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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#バリデーションデータ(検証用データ)の表示\n#元画像のまま\nitems = next(iter(val_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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ResNet50の転移学習を使用する\n#ResNet50のモデルを読み込み\n#重みはimagenet，全結合層は,使わない\n#ResNetの畳み込み層は凍結し，重みの更新は行わない\nfrom tensorflow.keras.applications import ResNet50V2\n\nbase_model = ResNet50V2(weights='imagenet', include_top=False)\n\nbase_model.trainable = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#重みの更新が行われていないことの確認を行う\n#Falseは，凍結，Trueは，非凍結\nfor l in base_model.layers:\n    print(l.name, l.trainable)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#モデルの作成(Sequentialで作成)\n#まず入力画像のリサイズを行う層を追加\n#ResNet50の畳み込み層のみを追加\n\nmodel = Sequential()\nmodel.add(Resizing(224, 224, input_shape=(32, 32, 3)))  # 画像のリサイズ\nmodel.add(base_model)  # ResNet50モデル\nmodel.add(GlobalAveragePooling2D())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dense(10, activation='softmax'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#モデルの概要\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#凍結されていないか確認\nfor l in model.layers:\n    print(l.name, l.trainable)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"adam=keras.optimizers.Adam(learning_rate=0.001,amsgrad=True)\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=adam,\n              metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''fit'''\n#モデルの学習\nhistory=model.fit(\n                  train_generator,\n                  epochs=20,\n                  steps_per_epoch = len(x_train)//batch_size,\n                  validation_data=val_generator)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#テストデータをモデルを使って分類\npredictions = model.predict(x_test)\n\n#分類予測を格納\nresults = predictions.argmax(axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"以下、モデルの凍結なしに全てのパラメータを更新する\"\"\"\nmodel.trainable = True\n\nfor l in base_model.layers:\n    print(l.name, l.trainable)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"adam=keras.optimizers.Adam(learning_rate=1e-5,amsgrad=True)\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=adam,\n              metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''fit'''\nhistory=model.fit(\n                  train_generator,\n                  steps_per_epoch=len(x_train) // batch_size,\n                  epochs=20,\n                  validation_data=val_generator)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''結果の可視化'''\nplt.figure(figsize=(10,7))\nplt.plot(history.history['accuracy'], color='b', linewidth=3)\nplt.plot(history.history['val_accuracy'], color='r', linewidth=3)\nplt.tick_params(labelsize=18)\nplt.ylabel('acuuracy', fontsize=20)\nplt.xlabel('epoch', fontsize=20)\nplt.legend(['training', 'test'], loc='best', fontsize=20)\nplt.figure(figsize=(10,7))\nplt.plot(history.history['loss'], color='b', linewidth=3)\nplt.plot(history.history['val_loss'], color='r', linewidth=3)\nplt.tick_params(labelsize=18)\nplt.ylabel('loss', fontsize=20)\nplt.xlabel('epoch', fontsize=20)\nplt.legend(['training', 'test'], loc='best', fontsize=20)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#テストデータをモデルを使って分類\npredictions = model.predict(x_test)\n\n#分類予測を格納\nresults = predictions.argmax(axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#モデルの予測結果をCSVファイルに出力\n\ncolumns = ['id', 'label']\ndf = pd.DataFrame(columns=columns)\ndf['label'] = results\ndf['label'] = df['label'].map(id2cat)\ndf['id'] = range(1, len(df.index) + 1)\ndf.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"R = 5\nC = 5\nfig, axes = plt.subplots(R, C, figsize=(12,12))\naxes = axes.ravel()\n\nfor i in np.arange(0, R*C):\n    axes[i].imshow(x_test[i])\n    axes[i].set_title(\"Predict: %s\" % (df['label'][i]))\n    axes[i].axis('off')\n    plt.subplots_adjust(wspace=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}