Yanwei Liu

本文把文章標題取名成PyTorch深度學習工具箱的用意是在於:

日常在進行PyTorch模型訓練的時候,如果想知道模型的好壞,我們會用不少方式去評估。例如:train/val loss、train/val accuracy、Confusion Matrix、per class accuracy、F1 Score、t-SNE視覺化、GradCAM、觀看模型分類時,判斷錯誤的圖片,及其原始圖片路徑。

然而,目前大多數research公開的程式碼當中,幾乎找不太到有一個將前述評估方法整合在一起的程式。也因此,如果我們想要得到這些資訊,就必須到Google搜尋,找別人是怎麼完成這些功能的,往往花上不少時間。

在本文當中,我將彙整過去寫過關於這些主題的文章及程式碼,製作成一個目錄,供讀者及自己查詢使用:

1.使用TensorBoard視覺化train/val loss、train/val accuracy
https://pytorch.org/docs/stable/tensorboard.html

2. Confusion Matrix和per class accuracy
如何根據PyTorch的Model預測的output繪製出混淆矩陣(Confusion Matrix)並取得每個class的accuracy?

3. F1 Score(imblanced dataset可用macro和weighted)
sklearn官方F1 Score文檔

4. t-SNE視覺化
如何使用PyTorch的Feature Extractor輸出進行t-SNE視覺化?

5. GradCAM
如何在PyTorch上使用GradCAM進行神經網路分類依據視覺化?

6. 觀看模型預測時,判斷錯誤的圖片
這個功能將預測錯誤的圖片保存到TensorBoard的log當中,再從中使用Tensorflow==1.13.1版本還原出來到資料夾中,有兩篇文章需要參考。

如何顯示PyTorch中預測錯誤的圖片?
如何將保存到TensorBoard的圖片擷取出來?

7.檢查模型的參數量及模型檔案大小
PyTorch如何檢查模型的參數量及模型檔案大小?

8.列出分類錯誤之原始圖片路徑?
PyTorch如何列出分類錯誤之原始圖片路徑?

9.讓訓練結果具有再現性(Reproducibility)
如何確保PyTorch訓練的結果具有再現性?

10.將模型的多個Label輸出改成只有2種輸出
如何修改PyTorch的Prediction結果?

11.快速使用一些基於PyTorch所開發的套件
基於PyTorch的實用Library

12.降低訓練模型所需的時間
如何縮減PyTorch訓練時所需要的時間?

13.計算資料集的mean和std,用來作為Normalize的參數
PyTorch計算dataset的mean和std

14.計算Overkill和Leakage
PyTorch如何計算Overkill和Leakage並輸出成Excel檔案?

15.在訓練過程中,使用自定義的DataAugmentation方法
如何在PyTorch的transforms.Compose中使用自定義的Data Augmentation?

16.訓練過程中,讓各個類別的樣本數量平均被抽取
如何在訓練PyTorch時的每個Batch中使各個類別擁有相同數量的樣本?

17.搭配TensorBoard進行2D或3D的T-SNE視覺化
如何使用TensorBoard針對PyTorch的embedding輸出進行2D或3D的T-SNE視覺化?

18.進行Transfer Learning
PyTorch如何進行Transfer Learning

19.提取神經網路指定層輸出之特徵
使用PyTorch實作ResNet並提取指定層輸出之特徵

20.提取圖片資料集特徵並存成單獨的Pickle檔案
如何將PyTorch圖像資料集提取出Tensor特徵並保存成Pickle檔案?

--

--

在使用matplotlib將視覺化效果進行存檔的時候,我們除了可以存成png格式的圖片之外,還能保存成PDF格式。

保存成PDF格式的好處是,PDF中的圖片不會因為縮放而產生失真(也可以說,圖片不會因為縮放變模糊)。

如果我們想進一步的對這些PDF中的圖片進行修改,我們可以怎麼做?

在遍尋了網路上的各種有關PDF編輯的軟體後,我發現大多都:

(1)需要付費
(2 …

--

--

對多數的package來說,開發者會針對function的每個argument提供詳細的文字說明,以方便使用者。

但有時新舊版本的同個function,可能會因為版本的更動,有些argument就被移除或是新增。

若官方直接更新文檔,而將舊版的移除,這時,要知道舊版本的function存在哪些argument就變的相當麻煩。

所幸inspect這個套件提供了getargspec這個功能,在不查詢文檔的情況下,也能讓使用者知道某個function具備哪些argument。

# https://www.geeksforgeeks.org/how-to-get-list-of-parameters-name-from-a-function-in-python/import inspect
from pytorch_metric_learning import samplers
print(inspect.getargspec(samplers.MPerClassSampler))
# output
ArgSpec(args=[‘self’, ‘labels’, ‘m’, ‘length_before_new_iter’], varargs=None, keywords=None, defaults=(100000,))

--

--

在特定條件下,我們希望能修改List和Dict資料型態的順序,具體上該怎麼做呢?

以下2則簡單的程式碼範例,介紹如何對List和Dict去更改順序:

範例1:假設name_list = [0, 1, 2, 3, 8],我們該如何將name_list改成[0, 1, 2, 3, 4]?

範例2:假設idx_to_class = {0: ‘good’, 2: ‘bad’},我們該如何將idx_to_class改成{0: ‘good’, 1: ‘bad’}?

--

--

Transfer learning有分成兩種:

Finetuning the convnet:
一種是Fine-tuning,並不會固定神經網路的權重參數。重新訓練分類器層時,會進行反向傳播,更新權重
ConvNet as fixed feature extractor:
將pre-trained model的權重固定住,當作特徵提取器,單純針對分類器進行訓練。

實作方法:

本範例僅提供Finetuning的方式,ConvNet as fixed feature extractor可參考官方教學

1.使用PyTorch官方在ImageNet上的預訓練模型
# Finetuning the convnet
import torch
from torch import nn
from torchvision import models
model_ft = models.resnet18(pretrained=True)
num_ftrs = model_ft.fc.in_features
# 透過修改model_ft.fc,使輸出的channel符合自己Task的需求,例如out_ch。
model_ft.fc = nn.Linear(num_ftrs, out_ch)
2.使用自己或他人在訓練好的模型 - 以MobileNetV3 Large為例
rom mobilenetv3 import mobilenetv3_large
model = mobilenetv3_large()
model.load_state_dict(torch.load('mobilenetv3-large-1cd25616.pth'))
# 透過修改model.classifier,使輸出的channel符合自己Task的需求,例如out_ch。
model.classifier = nn.Sequential(
nn.Linear(960, 1280),
h_swish(),
nn.Dropout(0.2),
nn.Linear(1280, out_ch),
)

參考資料

--

--

A ConvNet for the 2020s這篇研究當中,提出了ConvNeXt架構,介紹了許多提升卷積神經網路性能的方法,其中一個特別的點在於:將CNN常用的Batch Normalization改成Layer Normalization

PyTorch官方雖然有提供一個torch.nn.LayerNorm 的API,但是該API要求的輸入維度(batch_size, height, width, channels)與一般CNN的輸入維度(batch_size, channels, height, width)不同,因此需要額外的調整Tensor的shape

--

--