###### tags: `pytorch入門`
[參考連結 microsoft介紹](https://docs.microsoft.com/zh-tw/learn/modules/intro-machine-learning-pytorch/)
[參考連結 Datasets vs Dataloaders](https://iter01.com/524561.html)
# ch3 使用 PyTorch 資料集和 DataLoaders 載入資料
## Datasets and Dataloaders
> 因處理數據的程式碼太混亂和難維持,所以pytorch提供了2種data primitives
> `torch.utils.data.DataLoader` and `torch.utils.data.Dataset`
> 允許你使用pre-loaded的資料集和你的資料集
> `Dataset`存data和相對應的特徵(label) => 你定義一個class去代表資料集
> `DataLoader`則是將`Dataset`用一個可迭代的東西打包,讓你可以更方便的獲取samples
## 構建Dataset的子類:
### 簡單組
```python=
import torch
from torch.utils.data import Dataset,DataLoader
class MyDataset(Dataset):
def __init__(self):
self.data = torch.tensor([[1,2,3],[2,3,4],[3,4,5],[4,5,6]])
self.label = torch.LongTensor([1,1,0,0])
def __getitem__(self,index):
return self.data[index],self.label[index]
def __len__(self):
return len(self.data)
```
#### (1) __init__:
> 一般是把資料直接儲存在這個類的屬性中。像是`self.data`,`self.label`
#### (2) __getitem__:
> index是一個索引,這個索引的的取值範圍根據__len__的值決定。
> 如果是測試集,就只返回資料
#### (3) __len__:
> 資料長度
### 讀取資料夾中檔案組
```python=
import os
import pandas as pd
import torchvision.io as tvio
class CustomImageDataset(Dataset):
def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
self.img_labels = pd.read_csv(annotations_file)
self.img_dir = img_dir
self.transform = transform
self.target_transform = target_transform
def __len__(self):
return len(self.img_labels)
def __getitem__(self, idx):
img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0]) #將圖像路徑進行拼接
image = tvio.read_image(img_path) #讀取圖片
label = self.img_labels.iloc[idx, 1] #讀取csv #這裡這樣寫應該是第0列=檔名,第1列=label
if self.transform:
image = self.transform(image) #還在研究
if self.target_transform:
label = self.target_transform(label) #還在研究
sample = {"image": image, "label": label} #將資料和特徵轉換成字典格式
return sample
```
#### (1) __init__:
> `annotations_file` 代表存label的csv路徑
> `img_dir` 如其名,圖像的路徑
#### (2) __len__:
> return 長度(這裡是以label長度,要用data也可以)
#### (3) __getitem__:
> 根據輸入的索引idx,回傳一個字典格式(資料(img)+特徵(種類))
> 如果是測試集,就只返回資料
## Preparing your data for training with DataLoaders
```python=
mydataloader = DataLoader(dataset=mydataset,
batch_size=1)
```
> batch_size 一次用幾個樣本作整個神經網路的導數運算來更新導數。
> 這個時候執行結果會依照資料的順序執行
```python=
mydataloader = DataLoader(dataset=mydataset,
batch_size=2,
shuffle=True)
```
> 而在我們增加了`shuffle=True`後,他則會打亂資料順序去執行。
## 總結及補充
> Dataloader和Dataset兩個類是非常方便的,因為這個可以快速的做出來batch資料,修改batch_size和亂序都非常地方便。有下面兩個希望注意的地方:
> 1. 一般標籤值應該是Long整數的,所以標籤的tensor可以用`torch.LongTensor`(資料)或者用`.long()`來轉化成Long整數的形式。
> 2. 如果要使用PyTorch的GPU訓練的話,一般是先判斷cuda是否可用,然後把資料標籤都==用`.to()`放到GPU視訊記憶體上進行GPU加速==。
```python=
device = 'cuda' if torch.cuda.is_available() else 'cpu'
for i,(data,label) in enumerate(mydataloader):
data = data.to(device)
label = label.to(device)
print(data,label)
```