{"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":"gpu","dataSources":[{"sourceId":21154,"databundleVersionId":1243559,"sourceType":"competition"},{"sourceId":8538592,"sourceType":"datasetVersion","datasetId":4247656}],"dockerImageVersionId":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import 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/flower'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-28T11:18:32.817385Z","iopub.execute_input":"2024-05-28T11:18:32.817718Z","iopub.status.idle":"2024-05-28T11:18:32.825187Z","shell.execute_reply.started":"2024-05-28T11:18:32.817689Z","shell.execute_reply":"2024-05-28T11:18:32.824307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install --upgrade pip\n!pip install keras","metadata":{"execution":{"iopub.status.busy":"2024-05-28T11:18:34.821317Z","iopub.execute_input":"2024-05-28T11:18:34.821715Z","iopub.status.idle":"2024-05-28T11:19:12.108966Z","shell.execute_reply.started":"2024-05-28T11:18:34.821686Z","shell.execute_reply":"2024-05-28T11:19:12.107786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\nimport tensorflow as tf\nimport keras\n","metadata":{"execution":{"iopub.status.busy":"2024-05-28T11:19:12.110937Z","iopub.execute_input":"2024-05-28T11:19:12.111242Z","iopub.status.idle":"2024-05-28T11:19:23.662136Z","shell.execute_reply.started":"2024-05-28T11:19:12.111214Z","shell.execute_reply":"2024-05-28T11:19:23.661453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\nfrom tensorflow.keras.layers import Input, Dense, GlobalAveragePooling2D\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.applications import InceptionResNetV2","metadata":{"execution":{"iopub.status.busy":"2024-05-28T11:19:23.663196Z","iopub.execute_input":"2024-05-28T11:19:23.663760Z","iopub.status.idle":"2024-05-28T11:19:23.675016Z","shell.execute_reply.started":"2024-05-28T11:19:23.663733Z","shell.execute_reply":"2024-05-28T11:19:23.673977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.models import load_model\nfrom sklearn.metrics import f1_score, accuracy_score\n\n# 定義 macro F1 score 函數\ndef macro_f1_score(y_true, y_pred):\n    y_pred = np.argmax(y_pred, axis=1)\n    y_true = np.argmax(y_true, axis=1)\n    return f1_score(y_true, y_pred, average='macro')\n\n\nmodel = load_model('/kaggle/input/flower/InceptionResNetV2_checkpoint_v2.keras', custom_objects={'macro_f1_score': macro_f1_score})\n","metadata":{"execution":{"iopub.status.busy":"2024-05-28T11:19:53.963795Z","iopub.execute_input":"2024-05-28T11:19:53.964202Z","iopub.status.idle":"2024-05-28T11:21:06.079057Z","shell.execute_reply.started":"2024-05-28T11:19:53.964171Z","shell.execute_reply":"2024-05-28T11:21:06.078094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_test = np.load('/kaggle/input/flower/x_test.npy')\ny_test = np.load('/kaggle/input/flower/y_test.npy')\nprint(x_test.shape, y_test.shape)\nprint(y_test[0])","metadata":{"execution":{"iopub.status.busy":"2024-05-28T11:21:11.269606Z","iopub.execute_input":"2024-05-28T11:21:11.269977Z","iopub.status.idle":"2024-05-28T11:21:35.226948Z","shell.execute_reply.started":"2024-05-28T11:21:11.269947Z","shell.execute_reply":"2024-05-28T11:21:35.225880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model.predict(x_test)\ny_pred_classes = np.argmax(y_pred, axis=1)\ndecoded_list = [item.decode('utf-8') for item in y_test]\n\nprint(\"test OK\")","metadata":{"execution":{"iopub.status.busy":"2024-05-28T11:21:35.229313Z","iopub.execute_input":"2024-05-28T11:21:35.230107Z","iopub.status.idle":"2024-05-28T11:22:30.483965Z","shell.execute_reply.started":"2024-05-28T11:21:35.230045Z","shell.execute_reply":"2024-05-28T11:22:30.482941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Generating submission.csv file...')\n\n# Get image ids from test set and convert to unicode\n#test_ids_ds = test_ds.map(lambda image, idnum: idnum).unbatch()\n# test_ids = next(iter(y_test)).astype('U')\n\n# Write the submission file\nnp.savetxt(\n    'submission.csv',\n    np.rec.fromarrays([decoded_list, y_pred_classes]),\n    fmt=['%s', '%d'],\n    delimiter=',',\n    header='id,label',\n    comments='',\n)\n\n# Look at the first few predictions\n!head submission.csv","metadata":{"execution":{"iopub.status.busy":"2024-05-28T11:22:30.485184Z","iopub.execute_input":"2024-05-28T11:22:30.485485Z","iopub.status.idle":"2024-05-28T11:22:31.528312Z","shell.execute_reply.started":"2024-05-28T11:22:30.485460Z","shell.execute_reply":"2024-05-28T11:22:31.527045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# x_train = np.load('/kaggle/input/flower/x_train.npy')\n# y_train = np.load('/kaggle/input/flower/y_train.npy')\n# print(x_train.shape, y_train.shape)\n\n# x_val = np.load('/kaggle/input/flower/x_validation.npy')\n# y_val = np.load('/kaggle/input/flower/y_validation.npy')\n# print(x_val.shape, y_val.shape)","metadata":{"execution":{"iopub.status.busy":"2024-05-28T07:02:48.726109Z","iopub.execute_input":"2024-05-28T07:02:48.726436Z","iopub.status.idle":"2024-05-28T07:03:32.205539Z","shell.execute_reply.started":"2024-05-28T07:02:48.726402Z","shell.execute_reply":"2024-05-28T07:03:32.204324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # 載入keras模型(更換輸出圖片尺寸)\n# model = InceptionResNetV2(include_top=False,\n#                  weights='imagenet',\n#                  input_tensor=Input(shape=(192, 192, 3))\n#                  )\n\n# # 定義輸出層\n# x = model.output\n# x = GlobalAveragePooling2D()(x)\n# predictions = Dense(104, activation='softmax')(x)\n# model = Model(inputs=model.input, outputs=predictions)\n\n# # 編譯模型\n# model.compile(optimizer=Adam(learning_rate=0.001),\n#               loss='categorical_crossentropy',\n#               metrics=['accuracy'])\n\n# model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-05-28T07:03:46.277236Z","iopub.execute_input":"2024-05-28T07:03:46.277661Z","iopub.status.idle":"2024-05-28T07:03:53.632899Z","shell.execute_reply.started":"2024-05-28T07:03:46.277629Z","shell.execute_reply":"2024-05-28T07:03:53.631857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # ---------------------------2.設置callbacks----------------------------\n# # 設定earlystop條件\n# estop = EarlyStopping(monitor='val_loss', patience=10, mode='min', verbose=1)\n\n# # 設定模型儲存條件\n# checkpoint = ModelCheckpoint('./InceptionResNetV2_checkpoint_v2.keras', verbose=1,\n#                           monitor='val_loss', save_best_only=True,\n#                           mode='min')\n\n# # 設定lr降低條件(0.001 → 0.0005 → 0.00025 → 0.000125 → 0.0001)\n# reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,\n#                            patience=5, mode='min', verbose=1,\n#                            min_lr=1e-5)","metadata":{"execution":{"iopub.status.busy":"2024-05-28T07:04:13.777949Z","iopub.execute_input":"2024-05-28T07:04:13.778785Z","iopub.status.idle":"2024-05-28T07:04:13.784525Z","shell.execute_reply.started":"2024-05-28T07:04:13.778748Z","shell.execute_reply":"2024-05-28T07:04:13.783502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)\n# #STEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE\n# history = model.fit(x_train,\n#                     y_train,\n#                     epochs = 100,\n#                     validation_split=0.2,\n#                     callbacks=[callback]\n# )","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # -----------------------------4.開始訓練模型------------------------------\n# # 重新訓練權重\n# # 設定批次大小\n# from tensorflow.keras.utils import to_categorical\n\n# batch_size = 64\n\n# # 計算步數\n# steps_per_epoch = len(x_train) // batch_size\n# validation_steps = len(x_val) // batch_size\n\n# # 將標籤轉換為 one-hot 編碼\n# y_train_one_hot = to_categorical(y_train, num_classes=104)\n# y_val_one_hot = to_categorical(y_val, num_classes=104)\n\n# history = model.fit(x_train,\n#                     y_train_one_hot,\n#                     epochs=50,\n#                     verbose=1,\n#                     steps_per_epoch=steps_per_epoch,\n#                     validation_data=(x_val, y_val_one_hot),\n#                     validation_steps=validation_steps,\n#                     callbacks=[checkpoint, estop, reduce_lr])","metadata":{"execution":{"iopub.status.busy":"2024-05-28T07:04:18.975488Z","iopub.execute_input":"2024-05-28T07:04:18.976228Z","iopub.status.idle":"2024-05-28T07:40:57.423273Z","shell.execute_reply.started":"2024-05-28T07:04:18.976198Z","shell.execute_reply":"2024-05-28T07:40:57.422316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # 訓練完成後保存最終模型\n# model.save('/kaggle/working/InceptionResNetV2_final_model.keras')","metadata":{"execution":{"iopub.status.busy":"2024-05-28T07:48:27.086595Z","iopub.execute_input":"2024-05-28T07:48:27.099705Z","iopub.status.idle":"2024-05-28T07:48:30.586694Z","shell.execute_reply.started":"2024-05-28T07:48:27.099661Z","shell.execute_reply":"2024-05-28T07:48:30.585745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # 創建一個下載連結\n# from IPython.display import FileLink\n# FileLink('/kaggle/working/InceptionResNetV2_final_model.keras')","metadata":{"execution":{"iopub.status.busy":"2024-05-28T07:52:38.805764Z","iopub.execute_input":"2024-05-28T07:52:38.807089Z","iopub.status.idle":"2024-05-28T07:52:38.813876Z","shell.execute_reply.started":"2024-05-28T07:52:38.807042Z","shell.execute_reply":"2024-05-28T07:52:38.812914Z"},"trusted":true},"execution_count":null,"outputs":[]}]}