Skip to content

Commit 88f79e8

Browse files
authored
Update README.md
1 parent 255526a commit 88f79e8

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

README.md

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ There are some official custom dataset examples on PyTorch repo like [this](http
1212
- [Using Torchvision Transforms](#using-torchvision-transforms)
1313
- [Another Way to Use Torchvision Transforms](#another-way-to-use-torchvision-transforms)
1414
- [Incorporating Pandas (Reading csv)](#incorporating-pandas)
15-
15+
- [Incorporating Pandas with More Logic in `__getitem__()`](#incorporating-pandas-with-more-logic)
16+
- [Using Data Loader with Custom Datasets](#using-data-loader)
17+
- [What's Next?](#future-updates)
1618

1719
## Custom Dataset Fundamentals
1820
The first and foremost part is creating a dataset class.
@@ -193,13 +195,21 @@ if __name__ == "__main__":
193195
CustomDatasetFromImages('../data/mnist_labels.csv')
194196
```
195197

196-
## Incorporating Pandas - Puttng More Stuff in in `__getitem__()`
198+
## Incorporating Pandas with More Logic
199+
200+
Yet another example might be reading an image from CSV where the value of each pixel is listed in a column. (Sometimes MNIST is given this way). This just changes the logic in `__getitem__()`. In the end, you just return images as tensors and their labels. The data is divided into pixels like
201+
202+
Label | pixel_1 | pixel_2 | ... |
203+
| ------------- |:-------------:| :-----:| :-----:|
204+
| 1 | 50 | 99 | ... |
205+
| 0 | 21 | 223 | ... |
206+
| 9 | 44 | 112 | ... |
207+
197208

198-
Yet another example might be reading an image from CSV where the value of each pixel is listed in a column. (Sometimes MNIST is given this way). This just changes the logic in `__getitem__()`. In the end, you just return images as tensors and their labels.
199209

200210
```python
201211
class CustomDatasetFromCSV(Dataset):
202-
def __init__(self, csv_path, height, width, transform=None):
212+
def __init__(self, csv_path, height, width, transforms=None):
203213
"""
204214
Args:
205215
csv_path (string): path to csv file
@@ -211,7 +221,7 @@ class CustomDatasetFromCSV(Dataset):
211221
self.labels = np.asarray(self.data.iloc[:, 0])
212222
self.height = height
213223
self.width = width
214-
self.transform = transform
224+
self.transforms = transform
215225

216226
def __getitem__(self, index):
217227
single_image_label = self.labels[index]
@@ -226,15 +236,51 @@ class CustomDatasetFromCSV(Dataset):
226236
img_as_img = Image.fromarray(img_as_np)
227237
img_as_img = img_as_img.convert('L')
228238
# Transform image to tensor
229-
if self.transform is not None:
230-
img_as_tensor = self.transform(img_as_img)
239+
if self.transforms is not None:
240+
img_as_tensor = self.transforms(img_as_img)
231241
# Return image and the label
232242
return (img_as_tensor, single_image_label)
233243

234244
def __len__(self):
235245
return len(self.data.index)
246+
247+
248+
if __name__ == "__main__":
249+
transformations = transforms.Compose([transforms.ToTensor()])
250+
custom_mnist_from_csv = \
251+
CustomDatasetFromCSV('../data/mnist_in_csv.csv', 28, 28, transformations)
252+
236253
```
237254

255+
## Using Data Loader
256+
Pytorch DataLoaders just call `__getitem__()` and wrap them up to a batch. We can technically not use Data Loaders and call `__getitem__()` one at a time and feed data to the models (even though it is super convenient to use data loader). Continuing from the example above, if we assume there is a custom dataset called *CustomDatasetFromCSV* then we can call the data loader like:
257+
258+
```python
259+
...
260+
if __name__ == "__main__":
261+
# Define transforms
262+
transformations = transforms.Compose([transforms.ToTensor()])
263+
# Define custom dataset
264+
custom_mnist_from_csv = \
265+
CustomDatasetFromCSV('../data/mnist_in_csv.csv',
266+
28, 28,
267+
transformations)
268+
# Define data loader
269+
mn_dataset_loader = torch.utils.data.DataLoader(dataset=custom_mnist_from_csv,
270+
batch_size=10,
271+
shuffle=False)
272+
273+
for images, labels in mn_dataset_loader:
274+
# Feed the data to the model
275+
```
276+
277+
The firsts argument of the dataloader is the dataset, from there it calls `__getitem__()` of that dataset. *batch_size* determines how many individual data points will be wrapped with a single batch. If we assume a single image tensor is of size: 1x28x28 (D:1, H:28, W:28) then, with this dataloader the returned tensor will be 10x1x28x28 (Batch-Depth-Height-Width).
278+
279+
A note on using **multi GPU**. The way that multi gpu is used with Pytorch data loaders is that, it tries to divide the batches evenly among all GPUs you have. So, if you use batch size that is less than amount of GPUs you have, it won't be able utilize all GPUs.
280+
281+
## Future Updates
238282

283+
I will continue updating this repository whenever I find spare time. Below, are some of the stuff I plan to include. Please let me know if you would like to see some other specific examples.
239284

240-
I will continue updating this repo if I do some fancy stuff in the future that is different than these examples.
285+
- A working custom dataset for Imagenet with normalizations etc.
286+
- A custom dataset example for encoder-decoder networks like U-Net.

0 commit comments

Comments
 (0)