AttributeError: 'str' object has no attribute 'items'

username: NagaYu
cooked: <p>I don’t know why I get this error.</p>
<pre><code class="lang-auto">model.train()

for imgs, targets, image_ids in train_loader:

    imgs = list(imgs.to(device) for img in imgs)
    targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

    loss_dict = model(imgs, targets)
    losses = sum(loss for loss in loss_dict.values())
    loss_value = losses.item()
    optimizer.zero_grad()
    losses.backward()
    optimizer.step() 
    
    for epoch in range(num_epoch):
        print('Epoch {}/{}'.format(epoch, num_epoch))
        print('-' * 10)
</code></pre>
<p>AttributeError                            Traceback (most recent call last)<br>
/var/folders/z4/_7p6fjpd2hq3n_l3dhnj0h4c0000gn/T/ipykernel_2502/1335634306.py in <br>
4<br>
5     imgs = list(imgs.to(device) for img in imgs)<br>
----&gt; 6     targets = [{k: v.to(device) for k, v in t.items()} for t in targets]<br>
7<br>
8     loss_dict = model(imgs, targets)</p>
<p>/var/folders/z4/_7p6fjpd2hq3n_l3dhnj0h4c0000gn/T/ipykernel_2502/1335634306.py in (.0)<br>
4<br>
5     imgs = list(imgs.to(device) for img in imgs)<br>
----&gt; 6     targets = [{k: v.to(device) for k, v in t.items()} for t in targets]<br>
7<br>
8     loss_dict = model(imgs, targets)</p>
<p>AttributeError: ‘str’ object has no attribute ‘items’</p>

username: tobiaaa
cooked: <p>What type is <code>targets</code>? If it’s a dict, then with  <code>for t in targets</code>, you are iterating over the keys of the dict, not the values, which is why t is a str.</p>

username: NagaYu
cooked: <p>It looks like this. The data is a csv file.</p>
<pre><code class="lang-auto">class PennFudanDataset(Dataset):
    def __init__(self, dataframe, image_dir, transform=None):
        
        self.image_ids = dataframe['ImageID'].unique()
        self.df = dataframe
        self.image_dir = image_dir
        self.transform = transform

    def __getitem__(self, index):
        
        image_id = self.image_ids[index]
        records = self.df[self.df['ImageID'] == image_id]     
        img = np.array(Image.open(f'{self.image_dir}data/{image_id}.jpg'), dtype=np.float32)
        img /= 255.0
        
        boxes = records[['XMin', 'YMin', 'XMax', 'YMax']].values
        boxes[:, 2] = boxes[:, 0] + boxes[:, 2]
        boxes[:, 3] = boxes[:, 1] + boxes[:, 3]
        
        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
        area = torch.as_tensor(area, dtype=torch.float32)

        # there is only one class
        labels = torch.ones((records.shape[0],), dtype=torch.int64)
        
        # suppose all instances are not crowd
        iscrowd = torch.zeros((records.shape[0],), dtype=torch.int64)

        target = {}
        target['boxes'] = boxes
        target['labels'] = labels
        target['image_id'] = torch.tensor([index])
        target['area'] = area
        target['iscrowd'] = iscrowd
        target['boxes'] = torch.stack(list((map(torch.tensor, target['boxes'])))).type(torch.float32)

        #if self.transform:
        #    img = self.transform(img)

        return img, target, image_id

    def __len__(self) -&gt; int:
        return self.image_ids.shape[0]
</code></pre>

username: tobiaaa
cooked: <p>Ok so it’s a dict. If I understand your code correctly, you want to apply <code>to(device)</code> to all values in the dict. You could do that like this:</p>
<pre><code class="lang-auto">targets = {k: v.to(device) for k, v in targets.items()}
</code></pre>