{"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":"#===========================================================================================\n# 資料集：CIFAR-10資料集(CIFAR-10)\n# 功能　：觀察後是單純預測種類\n# 作者　：顏瑋良 (WeiLiang,Yan)\n# 用意　：因中文範例教學較少，故撰寫此範本希望可以幫助剛學習的中文使用者，加速理解。\n# 　　　　也在此作紀錄，給予lab未來學弟妹學習教學使用。\n# 備註　：最近剛好正在閱讀 EfficientNet 網路，也因tensorflow有支援故本次使用 EfficientNet 做簡易預測\n#        筆者也是剛接觸 tensorflow 與 CNN 為了加速學習故寫成筆記，若大家有看到筆者的錯誤請給予指導，謝謝。 \n#===========================================================================================","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-06-28T13:44:58.818814Z","iopub.execute_input":"2022-06-28T13:44:58.819274Z","iopub.status.idle":"2022-06-28T13:44:58.849733Z","shell.execute_reply.started":"2022-06-28T13:44:58.819166Z","shell.execute_reply":"2022-06-28T13:44:58.846369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=========================================================================\n# 以個人經驗做出簡易的作業標準流程(SOP)如下圖:\n# 大致步驟分為三部分：(模型與資料處理皆很彈性沒有一定，所以參考即可)\n# Step1.資料的御處理(Preprocessing data)\n# Step2.模型選擇與建立(Data choose and build)\n# STep3.模型驗證(Model validation)\n#=========================================================================","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:44:58.886949Z","iopub.execute_input":"2022-06-28T13:44:58.887469Z","iopub.status.idle":"2022-06-28T13:44:58.893655Z","shell.execute_reply.started":"2022-06-28T13:44:58.887423Z","shell.execute_reply":"2022-06-28T13:44:58.892421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"\\n簡易作業流程圖： \\n\\n\")\nfrom IPython.display import Image\nfrom IPython.core.display import HTML \nImage(url= \"https://i.imgur.com/6FQ3BZA.png\")","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:44:58.980149Z","iopub.execute_input":"2022-06-28T13:44:58.981205Z","iopub.status.idle":"2022-06-28T13:44:59.010595Z","shell.execute_reply.started":"2022-06-28T13:44:58.981163Z","shell.execute_reply":"2022-06-28T13:44:59.009157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#==================================================\n# 載入需要的套件，做資料的預處理(在後續執行時會一一講解)。\n#==================================================\n\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow.keras.datasets import cifar10","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:44:59.099822Z","iopub.execute_input":"2022-06-28T13:44:59.100714Z","iopub.status.idle":"2022-06-28T13:45:05.822642Z","shell.execute_reply.started":"2022-06-28T13:44:59.100668Z","shell.execute_reply":"2022-06-28T13:45:05.821551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#================================================================================\n# Step1：資料觀察與預處理\n# Step1-1 開啟檔案\n# Step1-2 觀察資料\n# Step1-3 處理資料的NAN\n# Step1-4 特徵挑選及資料正規化與編碼\n#================================================================================","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:05.825191Z","iopub.execute_input":"2022-06-28T13:45:05.825939Z","iopub.status.idle":"2022-06-28T13:45:05.837180Z","shell.execute_reply.started":"2022-06-28T13:45:05.825894Z","shell.execute_reply":"2022-06-28T13:45:05.834743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#===============================================================================================\n# Step1：資料觀察與預處理\n#　｜\n#　｜\n#　－－－Step1-1 開啟檔案\n#  (因 tensorflow dataset 有收錄此資料集，故直接載入 cifar10 資料集)\n#===============================================================================================\n\n(train_image, train_label), (test_image, test_label) = tf.keras.datasets.cifar10.load_data()\n\nprint(\"\\n\\n訓練集特徵資料(圖像)：\\n\\n\",train_image)\nprint(\"\\n\\n訓練集特徵資料(標籤)：\\n\\n\",train_label)\nprint(\"\\n\\n測試集特徵資料(圖像)：\\n\\n\",test_image)\nprint(\"\\n\\n測試集特徵資料(標籤)：\\n\\n\",test_label)","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:05.838934Z","iopub.execute_input":"2022-06-28T13:45:05.839597Z","iopub.status.idle":"2022-06-28T13:45:10.388082Z","shell.execute_reply.started":"2022-06-28T13:45:05.839555Z","shell.execute_reply":"2022-06-28T13:45:10.386782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=============================================================================================================\n# Step1：資料觀察與預處理\n#　｜\n# 　－－－Step1-2 觀察資料 (介紹筆者喜愛使用指令)\n#　　　　　｜　　　　\n#　　　　　－－－ Step1-2-1　Pandas.DataFrame 類型\n#　　　　　｜　　　　｜\n#　　　　　｜　　　　－－－Step1-2-1-1 .columns      :判斷資料的行數及名稱\n#　　　　　｜　　　　｜\n#　　　　　｜　　　　－－－Step1-2-1-2 .info()　　　　：主因方便確認每行(column)是否有缺值(NAN)，和資料型態大小與行列數。\n#　　　　　｜　　　　｜\n#　　　　　｜　　　　－－－Step1-2-1-3 .shape        :這也可也用來單純確認，資料行列數(形狀)\n#　　　　　｜　　　　｜\n#　　　　　｜　　　　－－－Step1-2-1-4 .describe()　 ：描述資料基本狀態(如:平均值、標準差、最大值...等)\n#　　　　　｜\n#　　　　　｜　　　　\n#　　　　　－－－Step1-2-2　Numpy.narray 類型\n#　　　　　　　　　｜\n#　　　　　　　　　－－－1-2-1 .unique()　　　：可以顯現出所有不重複的元素，可以判別標籤(label)內有幾類等。 \n#　　　　　　　　　｜\n#　　　　　　　　　－－－1-2-2 np.sort()　　　：蠻常需要將數值比大小等，可以將資料排序方便觀察。\n#=============================================================================================================","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:10.391240Z","iopub.execute_input":"2022-06-28T13:45:10.392234Z","iopub.status.idle":"2022-06-28T13:45:10.399920Z","shell.execute_reply.started":"2022-06-28T13:45:10.392202Z","shell.execute_reply":"2022-06-28T13:45:10.397730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=============================================================================================================\n# Step1：資料觀察與預處理\n#　｜\n# 　－－－Step1-2 觀察資料 (介紹筆者喜愛使用指令)\n#　　　　　｜　　　　\n#　　　　　－－－ Step1-2-1　Pandas.DataFrame 類型\n#　　　　　 　　　　｜\n#　　　　　 　　　　－－－Step1-2-1-1 .columns      :判斷資料的行數及名稱\n#=============================================================================================================\n# 因為這裡為 numpy.ndarray 沒辦法直接看出類別名稱得對應\n# 這裡使用 matplotlib 套件將資料視覺化，可以觀察這裡 畫出資料集中第0到第24張圖與他對應的標籤 (圖片大小 10*10)\n#=============================================================================================================\n\nplt.figure(figsize=(10,10))\nfor i in range(25):\n    plt.subplot(5,5,i+1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.grid(False)\n    plt.imshow(train_image[i])\n    plt.xlabel(train_label[i])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:10.403508Z","iopub.execute_input":"2022-06-28T13:45:10.404577Z","iopub.status.idle":"2022-06-28T13:45:11.789096Z","shell.execute_reply.started":"2022-06-28T13:45:10.404531Z","shell.execute_reply":"2022-06-28T13:45:11.788010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=============================================================================================================\n# 這裡稍微偷懶一下，因為圖片不太清楚所以我先上網查了一下各標籤的種類名稱，類別如下為了方便後續驗證比較好辨認。\n#=============================================================================================================\n\nlabel_names = ['airplane', 'automobile', 'bird', 'cat', 'deer','dog', 'frog', 'horse', 'ship', 'truck']\n","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:11.790245Z","iopub.execute_input":"2022-06-28T13:45:11.790595Z","iopub.status.idle":"2022-06-28T13:45:11.797226Z","shell.execute_reply.started":"2022-06-28T13:45:11.790561Z","shell.execute_reply":"2022-06-28T13:45:11.796273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=============================================================================================================\n# Step1：資料觀察與預處理\n#　｜\n# 　－－－Step1-2 觀察資料 (介紹筆者喜愛使用指令)\n#　　　　　｜　　　　\n#　　　　　－－－ Step1-2-1　Pandas.DataFrame 類型\n#　　　　　 　　　　｜\n#　　　　　　 　　　－－－Step1-2-1-2 .info()　　　　：主因方便確認每行(column)是否有缺值(NAN)，和資料型態大小與行列數。\n#=============================================================================================================\n# 因資料並不是pandas型態故跳過此步驟\n#=============================================================================================================","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:11.799233Z","iopub.execute_input":"2022-06-28T13:45:11.800168Z","iopub.status.idle":"2022-06-28T13:45:11.809353Z","shell.execute_reply.started":"2022-06-28T13:45:11.800132Z","shell.execute_reply":"2022-06-28T13:45:11.807891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=============================================================================================================\n# Step1：資料觀察與預處理\n#　｜\n# 　－－－Step1-2 觀察資料 (介紹筆者喜愛使用指令)\n#　　　　　｜　　　　\n#　　　　　－－－ Step1-2-1　Pandas.DataFrame 類型\n#　　　　　 　　　　｜\n#　　　　　 　　　　－－－Step1-2-1-4 .describe()　 ：描述資料基本狀態(如:平均值、標準差、最大值...等)\n#\n#=============================================================================================================\n# 因資料並不是pandas型態故跳過此步驟\n#=============================================================================================================","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:11.811433Z","iopub.execute_input":"2022-06-28T13:45:11.812411Z","iopub.status.idle":"2022-06-28T13:45:11.822761Z","shell.execute_reply.started":"2022-06-28T13:45:11.812367Z","shell.execute_reply":"2022-06-28T13:45:11.821508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=============================================================================================================\n# Step1：資料觀察與預處理\n#　｜\n# 　－－－Step1-3 處理資料的NAN (沒有一定硬性規定，只要能讓資料變得好訓練都可以)\n#　　　　　｜　　　　\n#　　　　　－－－Step1-3-1 遺失比例極小以至於不影響Data時\n#　　　　　｜　　　　｜\n#　　　　　｜　　　　－－－Step1-3-1 .columns      :直接捨棄\n#　　　　　｜　　　  (例如：有1000筆資料只有1筆資料填寫不完整，此時只皆捨棄使用999筆資料去訓練，論時間成本會好些)\n#　　　　　｜\n#　　　　　｜\n#　　　　　－－－Step1-3-2 遺失比例極高以至於不影響Data時\n#　　　　　　　　　｜\n#　　　　　　　　　－－－1-3-1 當遺失資料為數值型(連續)：可以使用平均數代替缺失值。\n#　　　　　　　　　｜\n#　　　　　　　　　－－－1-3-2 當遺失資料為分類型(離散)：可以使用眾數值代替缺失值。\n#\n#=============================================================================================================\n# 依上述可觀察出，此資料集印出後為數值矩陣，而每個矩陣都是代表一張圖，這種資料集合故無缺值問題。\n#=============================================================================================================","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:11.825150Z","iopub.execute_input":"2022-06-28T13:45:11.826110Z","iopub.status.idle":"2022-06-28T13:45:11.832880Z","shell.execute_reply.started":"2022-06-28T13:45:11.826068Z","shell.execute_reply":"2022-06-28T13:45:11.831803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#=============================================================================================================\n# Step1：資料觀察與預處理\n#　｜\n# 　－－－Step1-4 挑選特徵並將資料正規化與編碼\n#　　　　　｜－－－Step1-4-1 挑選特徵\n#　　　　　｜　　　　(淘汰不重要的特徵，例如名字、學號...等具備唯一性值，通常沒有什麼參考性，因為大家都不一樣較難有共通點)\n#　　　　　｜\n#　　　　　｜－－－Step1-4-2 將資料正規化\n#                 (將數值型資料正規化，映射至[0,1]之間，避免overflow也可以加快運算)\n#　　　　　｜－－－Step1-4-3 將資料編碼\n#                 (將分類型資料編碼，因若是字串比較時間複雜度會比數值型高上許多，所以需要做編碼加快運算)\n#=============================================================================================================\n# 直接看矩陣看不出關聯，因為為圖片所以所有特徵皆保留，此步驟只做正規化(由於矩陣內數值為0-255)只需要直接/255則可達到正規化效果\n#=============================================================================================================\n\ntrain_image = train_image/255 \ntest_image = test_image/255\n\nprint(\"\\n\\n訓練集特徵資料(圖像)：\\n\\n\",train_image)\nprint(\"\\n\\n訓練集特徵資料(圖像)：\\n\\n\",test_image)","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:11.838013Z","iopub.execute_input":"2022-06-28T13:45:11.838422Z","iopub.status.idle":"2022-06-28T13:45:12.459460Z","shell.execute_reply.started":"2022-06-28T13:45:11.838378Z","shell.execute_reply":"2022-06-28T13:45:12.458137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#================================================================================\n# Step2.模型建立(model build)\n#　｜\n#　－－－這裡直接使用 EfficientNet-B7 () 網路\n#  (等研讀完會在補充較詳細的 EfficientNet-B7 網路架構及效能原理，這裡先放架構圖)\n#================================================================================\nprint(\"\\n\\n EfficientNet-B7 架構圖： \\n\\n\")\nfrom IPython.display import Image\nfrom IPython.core.display import HTML \nImage(url= \"https://i.imgur.com/At1bloW.png\")\n#================================================================================","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:12.461687Z","iopub.execute_input":"2022-06-28T13:45:12.462534Z","iopub.status.idle":"2022-06-28T13:45:12.481423Z","shell.execute_reply.started":"2022-06-28T13:45:12.462489Z","shell.execute_reply":"2022-06-28T13:45:12.472270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = tf.keras.applications.efficientnet.EfficientNetB7(\n    include_top=True,\n    weights=None,\n    input_tensor=None,\n    input_shape=(32,32,3),\n    pooling=None,\n    classes=10,\n    classifier_activation='relu')","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:12.483727Z","iopub.execute_input":"2022-06-28T13:45:12.484656Z","iopub.status.idle":"2022-06-28T13:45:21.245707Z","shell.execute_reply.started":"2022-06-28T13:45:12.484603Z","shell.execute_reply":"2022-06-28T13:45:21.244667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer='adam',\n              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n              metrics=['accuracy'])\n\nhistory = model.fit(train_image, train_label, epochs=20, \n                    validation_data=(test_image, test_label))","metadata":{"execution":{"iopub.status.busy":"2022-06-28T13:45:21.247073Z","iopub.execute_input":"2022-06-28T13:45:21.248589Z","iopub.status.idle":"2022-06-28T15:18:17.450199Z","shell.execute_reply.started":"2022-06-28T13:45:21.248545Z","shell.execute_reply":"2022-06-28T15:18:17.448988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['accuracy'], label='accuracy')\nplt.plot(history.history['val_accuracy'], label = 'val_accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.ylim([0.5, 1])\nplt.legend(loc='lower right')\n\ntest_loss, test_acc = model.evaluate(test_image,  test_label, verbose=2)","metadata":{"execution":{"iopub.status.busy":"2022-06-28T15:22:57.576427Z","iopub.execute_input":"2022-06-28T15:22:57.577553Z","iopub.status.idle":"2022-06-28T15:23:18.673236Z","shell.execute_reply.started":"2022-06-28T15:22:57.577488Z","shell.execute_reply":"2022-06-28T15:23:18.672209Z"},"trusted":true},"execution_count":null,"outputs":[]}]}