專題鏈接:https://blog.csdn.net/qq_33345365/category_12591348.html
本教程翻譯自微軟教程:https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/
初次編輯:2024/3/2;最后編輯:2024/3/2
本教程第一篇介紹pytorch基礎和張量操作
這是本教程的第二篇,介紹以下內容:
- 數據集與數據加載器
- 歸一化
另外本人還有pytorch CV相關的教程,見專題:
https://blog.csdn.net/qq_33345365/category_12578430.html
數據集與數據加載器 Datasets and Dataloaders
處理數據樣本的代碼可能會變得復雜且難以維護。通常希望數據集代碼與模型訓練代碼解耦,以獲得更好的可讀性和模塊化性。PyTorch提供了兩個數據原語:torch.utils.data.DataLoader
和torch.utils.data.Dataset
,它們使您能夠使用預加載的數據集以及您自己的數據。Dataset存儲樣本及其對應的標簽,而DataLoader則在Dataset周圍包裝了一個可迭代對象,以便輕松訪問樣本。
PyTorch庫提供了許多預加載的樣本數據集(例如FashionMNIST),它們是torch.utils.data.Dataset
的子類,并實現了特定于特殊數據的功能。用于模型原型設計(prototyping)和基準測試(benchmark)的樣本包括:
- 圖像數據集
- 文本數據集
- 音頻數據集
加載數據集
此處使用TorchVision來加載Fashion-MNIST數據集。Fashion-MNIST是Zalando的服裝圖像數據集,包含60,000個訓練樣本和10,000個測試樣本。每個樣本包括一個28×28的灰度圖像和一個來自10個類別中的關聯標簽。
- 每個圖像高度為28個像素,寬度為28個像素,總共有784個像素。
- 這10個類別告訴圖像是什么類型,例如:T恤/上衣、褲子、套頭衫、連衣裙、包、短靴等。
- 灰度像素的值介于0到255之間,用于衡量黑白圖像的強度。強度值從白色到黑色遞增。例如:白色的顏色值為0,而黑色的顏色值為255。
我們使用以下參數加載FashionMNIST數據集:
- root 是存儲訓練/測試數據的路徑。
- train 指定訓練或測試數據集。
- download=True 如果數據在
root
中不可用,則從互聯網下載數據。 - transform 和
target_transform
指定特征和標簽的轉換。
加載訓練和測試數據集的代碼如下所示:
import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda
import matplotlib.pyplot as plttraining_data = datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor()
)test_data = datasets.FashionMNIST(root="data",train=False,download=True,transform=ToTensor()
)
數據集的迭代與可視化
可以像列表一樣手動索引Datasets
: training_data[index]
。此處使用matplotlib對訓練數據中的一些樣本進行可視化。代碼如下所示:
labels_map = {0: "T-Shirt",1: "Trouser",2: "Pullover",3: "Dress",4: "Coat",5: "Sandal",6: "Shirt",7: "Sneaker",8: "Bag",9: "Ankle Boot",
}
figure = plt.figure(figsize=(8, 8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):sample_idx = torch.randint(len(training_data), size=(1,)).item()img, label = training_data[sample_idx]figure.add_subplot(rows, cols, i)plt.title(labels_map[label])plt.axis("off")plt.imshow(img.squeeze(), cmap="gray")
plt.show()
得到如下圖片:
使用數據加載器(DataLoaders)準備自定義數據
Dataset
逐個樣本檢索數據集的特征和標簽。在訓練模型時,通常希望以“minibatch”的形式傳遞樣本,在每個周期重混洗(reshuffle)數據以減少模型過擬合,并使用Python的多進程加速數據檢索。
在機器學習中,需要指定數據集中的特征和標簽。**特征(Feature)**是輸入,**標簽(label)**是輸出。我們訓練特征,然后訓練模型以預測標簽。
- 特征是圖像像素中的模式。
- 標簽是10個類別類型:T恤,涼鞋,連衣裙等。
DataLoader
是一個可迭代對象,用簡單的API抽象了這種復雜性。為了使用DataLoader,我們需要設置以下參數:
- data 用于訓練模型的訓練數據,以及用于評估模型的測試數據。
- batch size 每個批次要處理的記錄數。
- shuffle 按索引隨機抽取數據樣本。
使用DataLoader
處理兩個數據集的代碼如下所示:
from torch.utils.data import DataLoadertrain_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)
使用DataLoader進行迭代
我們已將數據集加載到 DataLoader
中,現在可以根據需要迭代數據集。 下面的每次迭代都會返回一個批次的 train_features
和 train_labels
(分別包含 batch_size=64
個特征和標簽)。由于我們指定了 shuffle=True
,在遍歷完所有批次后,數據將被混洗(shuffle),以更精細地控制數據加載順序。
展示圖片和標簽的代碼如下所示:
# Display image and label.
train_features, train_labels = next(iter(train_dataloader))
print(f"Feature batch shape: {train_features.size()}")
print(f"Labels batch shape: {train_labels.size()}")
img = train_features[0].squeeze()
label = train_labels[0]
plt.imshow(img, cmap="gray")
plt.show()
label_name = list(labels_map.values())[label]
print(f"Label: {label_name}")
得到圖片:
歸一化
標準化是一種常見的數據預處理技術,用于對數據進行縮放或轉換,以確保每個特征都有相等的學習貢獻。例如,灰度圖像中的每個像素的值都介于0和255之間,這些是特征。如果一個像素值為17,另一個像素為197,則像素重要性的分布將不均勻,因為較高的像素值會偏離學習。標準化改變了數據的范圍,而不會扭曲其特征之間的區別。這種預處理是為了避免:
- 減少預測精度
- 模型學習困難
- 特征數據范圍的不利分布
Transforms
數據并不總是以最終處理過的形式呈現,這種形式適合訓練機器學習算法。可以使用transforms來操作數據,使其適合訓練。
所有 TorchVision 數據集都有兩個參數(transform
用于修改特征,target_transform
用于修改標簽),這些參數接受包含轉換邏輯的可調用對象。torchvision.transforms
模塊提供了幾種常用的轉換。
FashionMNIST 的特征是 PIL 圖像格式,標簽是整數。 對于訓練,需要將特征轉換為歸一化的張量,將標簽轉換為 one-hot 編碼的張量。 為了進行這些轉換,將使用 ToTensor
和 Lambda
。
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambdads = datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor(),target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)
解釋上述代碼:
ToTensor()
ToTensor 將PIL圖像或NumPy ndarray
轉換為FloatTensor,并將圖像的像素強度值縮放到范圍 [0., 1.]內。
Lambda transforms
Lambda transforms 應用任何用戶定義的lambda函數。在這里,我們定義了一個函數來將整數轉換為一個one-hot編碼的張量。它首先創建一個大小為10的零張量(數據集中標簽的數量),然后調用scatter,根據標簽y的索引為其分配值為1。也可以使用torch.nn.functional.one_hot
的方式來實現這一點。