# 深度學習HW2_ Music Scale Recognition by CNN ###### tags: `pytorch`, `Python筆記`, `CNN` ### :small_blue_diamond: 410823001 電機四 許哲瑜 1. what problems you encountered when doing this assignment 在做本次作業的過程中,發現到不管如何修改模型架構與參數,訓練的準確度都會卡在93%無法繼續增加,仔細看過程式碼之後才發現,我使用 os.listdir()的方式讀取圖片資料夾中的檔案名稱,與 "train_truth.csv" 檔案中的順序並不相同,導致我在訓練時有許多圖片所對應的label是錯誤的!難怪不管怎麼調整模型都不會有更好的成效。 2. how did you solve the problems? 為了解決上述問題,只需要將該檔案名稱去對應 "train_truth.csv" 中 "filename" 是否相同,利用pandas套件中的loc函式去過濾資料後,再拿取旁邊 "category" 的值即可,實作的程式碼如下: ```python= label_file = 'train_truth.csv' # 設定檔案路徑 label = pd.read_csv(label_file) # 利用 pandas 讀取 csv 檔案 N = len(label) # 取得訓練資料的數量 labels = np.array([0]* N) # 建立存放標籤的空陣列 path = os.getcwd() + '\music_train' # 設定圖片數據的資料夾路徑 class_filenames = os.listdir(path) # 利用 os.listdir 讀取資料夾中的圖片檔案名稱(type is list) for i, name in enumerate(class_filenames): num = label.loc[label["filename"]==name] # 取得該圖片名稱在 train_truth.csv 中對應的 label值 labels[i] = int(num['category']) # 將label值存入上方建立的標籤空陣列中 ``` 3. is there any innovative design you've made in this assignment? 我在訓練模型前有利用 train_test_split 將資料切分成訓練集與驗證集,其中使用stratify 參數設定為label資料,使得切分後的資料集是均勻分布。並且也將每張圖片都做正規化的處理,實作程式碼如下: ```python= from sklearn.model_selection import train_test_split # 利用 train_test_split語法 將訓練資料切分成訓練集與測試集: stratify 可以根據給定的標籤數均勻切分、random_state 確保每次重複執行切分的資料都相同 x_train_image, x_test_image, y_train_label, y_test_label = train_test_split(images, labels, stratify = labels, test_size=0.2, random_state=47) x_train = x_train_image.astype('float32')/255 # 將訓練集圖片數據正規化處理 ``` * 另外因為影像分類的問題我之前有使用Tensorflow的框架訓練過,這次選擇用Pytorch來試試看,發現最大的不同是建立訓練模型架構的部分,同樣使用ResNet模型架構,在Tensorflow可以使用遷移式學習得方式,短短幾行程式碼便可以建立好;而Pytorch我是透過老師上課的程式碼一步步建立,雖然過程較為複雜,但也比較了解此模型架構中的各項layer的內容與資料是如何被傳遞的,兩種不同的框架都各有優缺點,使用Tensorflow框架的程式碼如下: ```python= # Tensorflow的框架 建立 ResNet 模型架構 # 使用遷移式學習的imagenet權重,僅保留「非後全連結層的部分」,即include_top為False,並可使用input_shape指定輸入大小。 import tensorflow.keras.applications as keras_model from tensorflow.keras.layers import Dense, GlobalAveragePooling2D from tensorflow.keras.models import Model base_model = keras_model.ResNet50(include_top=False, weights="imagenet", input_shape=(H, W, 3), pooling=None, classes=88) x = base_model.output x = GlobalAveragePooling2D()(x) x = Dense(1024, activation="relu")(x) x = Dense(512, activation="relu")(x) output = Dense(88, activation="softmax")(x) model = Model(inputs=base_model.input, outputs=output) model.summary() ``` 4. what have you learned in this assignment? 經過這次讀取檔案與label的教訓,進後會再建立訓練資料時更加小心,確保要輸入訓練模型的資料集是正確的,避免在發生調整各項參數後都沒有效果的慘案發生!