DataLoader worker process 0

Micha_Rostova: <p>I have wrote a deep learning to detect food(sushi, steak, pizza). My code is</p>
<pre><code class="lang-auto">import os
def walk_through_dir(dir_path):
    """
    Walks through dir_path returning its content.
    Args:
        DIR_PATH(str or pathlib.Path): target directory

    Returns:
        A print out of:
            number of subdirectories in dir_path
            number of Images (files) in each subdirectory
            name of each subdirectory
    """
    for dirpath, dirnames, filenames in os.walk(dir_path):
        print(f"There are {len(dirnames)} directories and {len(filenames)} images in '{dirpath}'")
</code></pre>
<pre><code class="lang-auto">
data_transform= transforms.Compose([
    transforms.Resize(size=(64, 64)),
    transforms.RandomHorizontalFlip(p=0.5), # p = probability of flip, 0.5 = 50% chance
    transforms.ToTensor() # This converts all oixel values from 0 to 255 to be between 0.0 and 1.0
])
</code></pre>
<pre><code class="lang-auto">train_data= datasets.ImageFolder(root=train_dir, #Target folder of images
                                 transform= data_transform,# transforms to perform on data (images)
                                 target_transform=None)# transforms to perform on labels (if necessary)
test_data= datasets.ImageFolder(root=test_dir, transform= data_transform)

print(f"Train data:\n {train_data}\nTest data:\n {test_data}")
</code></pre>
<pre><code class="lang-auto">
from torch.utils.data import DataLoader
train_dataloader= DataLoader(dataset= train_data, batch_size=1, num_workers=1, shuffle=True)
test_dataloader= DataLoader(dataset= test_data, batch_size= 1, num_workers=1, shuffle=False)

train_dataloader, test_dataloader
</code></pre>
<pre><code class="lang-auto">from torchvision import datasets, transforms
#1. Load and transform data
train_data_simple= datasets.ImageFolder(root= train_dir)
test_data_simple= datasets.ImageFolder(root=test_dir)

#2. Turn data into DataLoaders
import os
from torch.utils.data import DataLoader

# Setup batch size and number of workers
batch_size=32
num_workers= os.cpu_count()
print(f"Creating DataLoader's with batch size {batch_size} and {num_workers} workers")

#Create DataLoader's
train_dataloader_simple= DataLoader(train_data_simple,
                                    batch_size=batch_size,
                                    num_workers= num_workers)
test_dataloader_simple= DataLoader(test_data_simple,
                                  batch_size= batch_size,
                                  shuffle=True,
                                  num_workers= num_workers)

train_dataloader_simple, test_dataloader_simple
</code></pre>
<pre><code class="lang-auto">class TinyVGG(nn.Module):
    def __init__(self, input_shape: int, hidden_units: int, output_shape: int) -&gt;None:
        super().__init__()
        self.conv_block_1 = nn.Sequential(
            nn.Conv2d(in_channels= input_shape, out_channels= hidden_units,
                      kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.Conv2d(in_channels= hidden_units, out_channels= hidden_units,
                     kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)
            
        )
        self.conv_block_2= nn.Sequential(
            nn.Conv2d(hidden_units, hidden_units, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(hidden_units, hidden_units, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2)
        )
        self.classifier= nn.Sequential(
            nn.Flatten(),
            nn.Linear(in_features= hidden_units*16*16, out_features=output_shape))
        def forward(self, x:torch.Tensor):
            x= self.conv_block_1(x)
            x= self.conv_block_2(x)
            x= self.classifier(x)
            return x


torch.manual_seed(42)
model_0= TinyVGG(input_shape=3, hidden_units= 10, output_shape= len(train_data.classes))
model_0
</code></pre>
<pre><code class="lang-auto">def train_step(model: torch.nn.Module, dataloader: torch.utils.data.DataLoader,
              loss_fn: torch.nn.Module, optimizer: torch.optim.Optimizer):
    #Put model in train mode
    model.train()

    #Setup train loss and train accuracy values
    train_loss, train_acc= 0, 0

    # Loop through data loader data batches
    for batch, (X, y) in enumerate(dataloader):
        #1.Forward pass
        y_pred= model(X)

        #2. Calculate and accumulate loss
        loss= loss_fn(y_pred, y)
        train_loss += loss

        #3. Optimizer zero grad
        optimizer.zero_grad()

        #4. Loss Backward
        loss.backward()

        # 5. Optimizer step
        optimizer.step()

        # Calculate and accumulate accuracy metric across all batches
        y_pred_class= torch.argmax(torch.softmax(y_pred, dim=1), dim=1)
        train_acc += (y_pred_class==y).sum().item()/len(y_pred)

    # Adjust metrics to get average loss and accuracy per batch
    train_loss = train_loss/ len(dataloader)
    train_acc= train_acc/len(dataloader)
    return train_loss, train_acc
</code></pre>
<pre><code class="lang-auto">def test_step(model: torch.nn.Module, dataloader: torch.utils.data.DataLoader,
             loss_fn: torch.nn.Module):
    # Put model in eval mode
    model.eval()

    # Setup test loss and test accuracy values
    test_loss, test_acc = 0, 0

    # Turn on inference context manager
    with torch.inference_mode():
        #Loop through DataLoader batches
        for batch, (X, y) in enumerate(dataloader):
            #1. Forward pass
            test_pred_logits= model(X)

            # 2. Calculate and accumulate loss
            loss= loss_fn(test_pred_logits, y)
            test_loss += loss.item()

            # Calculate and accumulate accuracy
            test_pred_labels= test_pred_logits.argmax(dim=1)
            test_acc +=((test_pred_labels==y).sum().item()/len(test_pred_labels))

    # Adjust metrics to get average loss and accuracy per batch
    test_loss= test_loss/len(dataloader)
    test_acc= test_acc/len(dataloader)
    return test_loss, test_acc
</code></pre>
<pre><code class="lang-auto">from tqdm.auto import tqdm

def train( model: torch.nn.Module, train_dataloader: torch.utils.data.DataLoader,
          test_dataloader: torch.utils.data.DataLoader, optimizer: torch.optim.Optimizer,
          loss_fn: torch.nn.Module= nn.CrossEntropyLoss(), epochs: int=5):
    
    #2. Create empty results dictionary
    results= {"train_loss":[],
             "train_acc": [],
             "test_loss": [],
             "test_acc": []}
    #3. Loop through training and testing steps for a number of epochs
    for epoch in tqdm(range(epochs)):
        train_loss, train_acc= train_step(model= model, dataloader= train_dataloader,
                                         loss_fn= loss_fn, optimizer=optimizer)
        test_loss, test_acc= test_step(model= model, dataloader= test_dataloader,
                                      loss_fn= loss_fn)
        #4. Print out what is happening
        print(
            f"Epoch: {epoch+1}"
            f"train_loss: {train_loss:.4f}"
            f"train_acc: {train_acc:.4f}"
            f"test_loss: {test_loss:.4f}"
            f"test_acc: {test_acc:.4f}"
        )
    #5. Update results dictionary
    results["train_loss"].append(train_loss)
    results["train_acc"].append(train_acc)
    results["test_loss"].append(test_loss)
    results["test_acc"].append(test_acc)
    #6. Return the filled results at the end of the epochs
    return results
</code></pre>
<pre><code class="lang-auto"># Set random seeds
torch.manual_seed(42) 
torch.cuda.manual_seed(42)

# Set number of epochs
NUM_EPOCHS = 5

# Recreate an instance of TinyVGG
model_0 = TinyVGG(input_shape=3, # number of color channels (3 for RGB) 
                  hidden_units=10, 
                  output_shape=len(train_data.classes))

# Setup loss function and optimizer
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(params=model_0.parameters(), lr=0.001)

# Start the timer
from timeit import default_timer as timer 
start_time = timer()

# Train model_0 
model_0_results = train(model=model_0, 
                        train_dataloader=train_dataloader_simple,
                        test_dataloader=test_dataloader_simple,
                        optimizer=optimizer,
                        loss_fn=loss_fn, 
                        epochs=NUM_EPOCHS)

# End the timer and print out how long it took
end_time = timer()
print(f"Total training time: {end_time-start_time:.3f} seconds")
</code></pre>
<p>So These were all of codes that I have wrote but it returns this error:</p>
<pre><code class="lang-auto">
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[32], line 22
     19 start_time = timer()
     21 # Train model_0 
---&gt; 22 model_0_results = train(model=model_0, 
     23                         train_dataloader=train_dataloader_simple,
     24                         test_dataloader=test_dataloader_simple,
     25                         optimizer=optimizer,
     26                         loss_fn=loss_fn, 
     27                         epochs=NUM_EPOCHS)
     29 # End the timer and print out how long it took
     30 end_time = timer()

Cell In[31], line 14, in train(model, train_dataloader, test_dataloader, optimizer, loss_fn, epochs)
     12 #3. Loop through training and testing steps for a number of epochs
     13 for epoch in tqdm(range(epochs)):
---&gt; 14     train_loss, train_acc= train_step(model= model, dataloader= train_dataloader,
     15                                      loss_fn= loss_fn, optimizer=optimizer)
     16     test_loss, test_acc= test_step(model= model, dataloader= test_dataloader,
     17                                   loss_fn= loss_fn)
     18     #4. Print out what is happening

Cell In[29], line 10, in train_step(model, dataloader, loss_fn, optimizer)
      7 train_loss, train_acc= 0, 0
      9 # Loop through data loader data batches
---&gt; 10 for batch, (X, y) in enumerate(dataloader):
     11     #1.Forward pass
     12     y_pred= model(X)
     14     #2. Calculate and accumulate loss

File ~/anaconda3/lib/python3.11/site-packages/torch/utils/data/dataloader.py:630, in _BaseDataLoaderIter.__next__(self)
    627 if self._sampler_iter is None:
    628     # TODO(https://github.com/pytorch/pytorch/issues/76750)
    629     self._reset()  # type: ignore[call-arg]
--&gt; 630 data = self._next_data()
    631 self._num_yielded += 1
    632 if self._dataset_kind == _DatasetKind.Iterable and \
    633         self._IterableDataset_len_called is not None and \
    634         self._num_yielded &gt; self._IterableDataset_len_called:

File ~/anaconda3/lib/python3.11/site-packages/torch/utils/data/dataloader.py:1344, in _MultiProcessingDataLoaderIter._next_data(self)
   1342 else:
   1343     del self._task_info[idx]
-&gt; 1344     return self._process_data(data)

File ~/anaconda3/lib/python3.11/site-packages/torch/utils/data/dataloader.py:1370, in _MultiProcessingDataLoaderIter._process_data(self, data)
   1368 self._try_put_index()
   1369 if isinstance(data, ExceptionWrapper):
-&gt; 1370     data.reraise()
   1371 return data

File ~/anaconda3/lib/python3.11/site-packages/torch/_utils.py:706, in ExceptionWrapper.reraise(self)
    702 except TypeError:
    703     # If the exception takes multiple arguments, don't try to
    704     # instantiate since we don't know how to
    705     raise RuntimeError(msg) from None
--&gt; 706 raise exception

TypeError: Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "/home/micha/anaconda3/lib/python3.11/site-packages/torch/utils/data/_utils/worker.py", line 309, in _worker_loop
    data = fetcher.fetch(index)  # type: ignore[possibly-undefined]
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/micha/anaconda3/lib/python3.11/site-packages/torch/utils/data/_utils/fetch.py", line 55, in fetch
    return self.collate_fn(data)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/micha/anaconda3/lib/python3.11/site-packages/torch/utils/data/_utils/collate.py", line 317, in default_collate
    return collate(batch, collate_fn_map=default_collate_fn_map)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/micha/anaconda3/lib/python3.11/site-packages/torch/utils/data/_utils/collate.py", line 174, in collate
    return [collate(samples, collate_fn_map=collate_fn_map) for samples in transposed]  # Backwards compatibility.
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/micha/anaconda3/lib/python3.11/site-packages/torch/utils/data/_utils/collate.py", line 174, in &lt;listcomp&gt;
    return [collate(samples, collate_fn_map=collate_fn_map) for samples in transposed]  # Backwards compatibility.
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/micha/anaconda3/lib/python3.11/site-packages/torch/utils/data/_utils/collate.py", line 192, in collate
    raise TypeError(default_collate_err_msg_format.format(elem_type))
TypeError: default_collate: batch must contain tensors, numpy arrays, numbers, dicts or lists; found &lt;class 'PIL.Image.Image'&gt;
</code></pre>
<p>I use PyTorch 2.4.0.  I appreciate any help</p>

ptrblck: <p>You are using the <code>_simple</code> datasets, which do not use any transformations. The error message points out that tensors etc. are expected while <code>PIL.Image</code>s are used. Transform the samples via <code>transforms.ToTensor()</code> and it should work.</p>

Micha_Rostova: <aside class="quote no-group" data-username="Micha_Rostova" data-post="1" data-topic="207321">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/micha_rostova/48/62401_2.png" class="avatar"> Micha_Rostova:</div>
<blockquote>
<p><code> transforms.ToTensor() # This</code></p>
</blockquote>
</aside>
<p>As you can see, here I have transformed the Image to Tensor</p>

Jameson_Crate: <p>The top datasets are correctly transformed, but the issue is with the <code>train_data_simple</code> and <code>test_data_simple</code> datasets which don’t have any transforms applied to them. Adding transforms.ToTensor() to the _simple datasets as ptrblck suggested should work.</p>