# ML2021Spring-hw3 解題筆記 ## 題目說明 Modified Food-11 Dataset 128x128 食物圖片,可被分成 11 類 labeled data 只有 3080 張,unlabeled 有 6786 張 Validation 660 labeled data、Testing 3347 images ## 成果(未達標) ![Screenshot_20240206_134121](https://hackmd.io/_uploads/rkb9LB1oa.png) 過 Medium baseline,但距離 Strong baseline 還有很長一段距離 原始碼:[Github](https://github.com/yzu1103309/ml2021spring-hw3) ## 做了什麼? ### Network 嘗試過 ResNet18,但規定不能使用 Pre-trained Weights 效果沒有到特別突出(有偷偷嘗試了一下 Pre-trained,效果很好,但不行用) 所以最後還是使用自己定義的 Network 為主: ```python= class Classifier(nn.Module): def __init__(self): super(Classifier, self).__init__() # The arguments for commonly used modules: # torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding) # torch.nn.MaxPool2d(kernel_size, stride, padding) # input image size: [3, 128, 128] self.cnn_layers = nn.Sequential( nn.Conv2d(3, 128, 5, 1), nn.BatchNorm2d(128), nn.ReLU(), nn.MaxPool2d(2, 2, 0), nn.Conv2d(128, 256, 3, 1), nn.BatchNorm2d(256), nn.ReLU(), nn.MaxPool2d(2, 2, 0), nn.Conv2d(256, 512, 3, 1), nn.BatchNorm2d(512), nn.ReLU(), nn.MaxPool2d(2, 2, 0), nn.Conv2d(512, 512, 3, 1), nn.BatchNorm2d(512), nn.ReLU(), nn.MaxPool2d(2, 2, 0), ) self.fc_layers = nn.Sequential( nn.Linear(512 * 6 * 6, 512), nn.BatchNorm1d(512), nn.ReLU(), nn.Linear(512, 256), nn.BatchNorm1d(256), nn.ReLU(), nn.Linear(256, 64), nn.BatchNorm1d(64), nn.ReLU(), nn.Linear(64, 11) ) def forward(self, x): x = self.cnn_layers(x) x = x.flatten(1) x = self.fc_layers(x) return x ``` ### 訓練設定 * 嘗試 Train 了 200 epoch 左右,但 Accuracy 上升到 60% 左右就很難再提高 * 有加入 Data Augmentation(詳見:[Data Augmentation](#Data-Augmentation)) * 有加入 semi-supervised learning,並設定一些觸發條件(詳見:[Semi-Supervised](#Semi-Supervised)) * batch size 設定 150,但影響不大(只要確保 Ram 不要被塞爆就好) * 在 Valid Accuracy 最高時將 Model 儲存,最後用最好的進行 predict ### Data Augmentation ```pyhton= train_tfm = transforms.Compose([ # Resize the image into a fixed shape (height = width = 128) transforms.Resize((128, 128)), # You may add some transforms here. # ToTensor() should be the last one of the transforms. # transforms.RandomPosterize(bits=2, p=0.5), transforms.RandomAutocontrast(p=0.5), transforms.RandomRotation(degrees=(0, 90)), transforms.RandomHorizontalFlip(p=0.5), transforms.RandomPerspective(distortion_scale=0.3, p=0.5), transforms.ToTensor(), ]) ``` 選定以上幾種增強方式,包括調整對比度、旋轉 0~90 度,水平翻轉、隨機視角 在使用 semi-supervised 之前,可以讓 Accuracy 上升 也試過其他的 Augmentation 組合,但結果的差距不大 ### Semi-Supervised 經過測試,因為 Labeled Data 真的太少,很容易 Overfit,所以加入 Semi-supervised 但是如果在 Model 很不穩定時直接開始做 Semi-supervised,反而造成反效果 所以先加入一些限制: * 當 Valid Accuracy 大於 0.55 時,下一個 iteration 用此 Model 進行 Labeling * Labeling 時,信心值要 > 0.8 才進行 Label 但此時發現,雖然可以使 Accuracy 升高,不過後面重複循環於 Labeling 和 Training,除了速度很慢之外,Accuracy 也無法有所突破 於是修改了一些機制: * 當 Valid Accuracy 大於目前 Best Accuracy 、並且大於 0.55 時,將此 Model 儲存 * 下一個 Iteration 用此 Best Model 進行 Labeling * Labeling 時,信心值要 > 0.8 才進行 Label 但是,Model 進步到一定程度,沒辦法再超過 Best Accuracy,就無法再 Label 新的 Data,Training 停滯 最後將限制改為以下設置: * 當 Valid Accuracy 大於域值(預設:0.5),下一個 iteration 用此 Model 進行 Labeling * 每一次域值提高一點點(0.1 或 0.2) * Labeling 時,信心值要 > 0.9 才進行 Label 但還是一樣沒有找到突破點