1. 程式人生 > 其它 >PyTorch之Dataset和TensorDataset

PyTorch之Dataset和TensorDataset

技術標籤:Deep Learning深度學習pytorchtensorflow人工智慧機器學習

Deep Learning系列 @cxx

Dataset v.s. TensorDataset

使用PyTorch搭建過Neural Network的小夥伴們都知道,在資料準備步驟裡,我們需要把訓練集的x和y分裝在dataset裡,然後將dataset分裝到DataLoader中去,便於之後在搭建好的模型中訓練。
簡言之,dataset是用來做打包和預處理(比如輸入資料路徑自動讀取);DataLoader則是將整個資料集(dataset)按照batch進行迭代分裝或者shuffle(可以得到一個iterator以利於for迴圈讀取)。

Dataset

如果使用繼承Dataset的方式,那麼在自定義的dataset類中必須給予__len__和__getitem__的定義。
進行圖片處理的時候,可以定義一個transforms來隨機旋轉訓練圖片,將圖片格式變成tensor等
(這裡有一個坑)

假設我們讀取了一個有如下格式的圖片
在這裡插入圖片描述
將圖片分裝到dataset裡,再放到dataloader裡

from torch.utils.data import TensorDataset
batch_size = 128
train_transform = transforms.Compose([
    transforms.ToPILImage(
), transforms.RandomHorizontalFlip(), transforms.RandomRotation(15), transforms.ToTensor(),] ) test_transform = transforms.Compose( [transforms.ToPILImage(), transforms.ToTensor(),] ) #測試集不需要翻轉或旋轉圖片 #繼承Dataset class ImgDataset(Dataset): def __init__(self, x, y=None, transform=
None): self.x = x self.y = y # label is required to be a LongTensor if y is not None: self.y = torch.LongTensor(y) self.transform = transform def __len__(self): return len(self.x) def __getitem__(self, index): X = self.x[index] if self.transform is not None: X = self.transform(X) if self.y is not None: Y = self.y[index] return X, Y else: return X #將dataset分裝到dataloader裡 train_dataloader = DataLoader( train_dataset, batch_size=batch_size, shuffle=True ) test_dataloader = DataLoader( val_dataset, batch_size=batch_size, shuffle=False )

接下來我們可以輸出一個batch看看圖片的格式
在這裡插入圖片描述
我們發現一個batch的x[0]的shape由原先的(128, 128, 3)變成了(3, 128, 128)。
原因在於transformers.toTensor()方法有自動轉換維度的功能,它會將channel變成第一維(奪麼坑爹的功能,導致我排查了好久不知道是哪裡出了問題==)
具體可以參照這篇部落格 transforms.ToTensor()本身有維度轉換功能

TensorDataset

張量資料集tensrdataset是最常見的形式,因為PyTorch本身有提供方便的TensorDataset給我們使用

torch.utils.data.TensorDataset(data_tensor, target_tensor)

用TensorDataset寫會少寫很多東西

#將資料轉換成tensor
tsr_x_train, tsr_y_train = torch.tensor(x_train), torch.tensor(y_train)
tsr_x_val, tsr_y_val = torch.tensor(x_val), torch.tensor(y_val)
tsr_x_testing = torch.tensor(x_test)

#然後只需要一行就可以啦
train_dataset = TensorDataset(tsr_x_train, tsr_y_train)
val_dataset = TensorDataset(tsr_x_val, tsr_y_val)

#裝入dataloader的步驟同上
train_dataloader = DataLoader(
    train_dataset,
    batch_size=batch_size,
    shuffle=True
)
test_dataloader = DataLoader(
    val_dataset,
    batch_size=batch_size,
    shuffle=False
)

我們跑一個loop看看這次維度是否被轉換了
在這裡插入圖片描述
答案是:這次沒有!
這次的x[0]的shape同我們一開始設定的shape,TensorDataset並沒有幫我們把channel數調成第一維
這裡真的要注意呀。