'tuple' object has no attribute 'to' in pytorch

MJChoi: <p>I got this error while trying to test CNN model.<br>
I already checked type about this error point’variable.</p>
<p>Here is error point<br>
10. imgs = imgs.to(device)                       <span class="hashtag">#imgs</span> type &lt;class ‘torch.Tensor’&gt;<br>
—&gt; 11             labels =  labels.to(device) <span class="hashtag">#labels</span> type &lt;class ‘torch.Tensor’&gt;</p>
<p>AttributeError: ‘tuple’ object has no attribute ‘to’</p>
<p>Both are Tensor type, there is not tuple type.</p>
<p>I try to make image classification to use multiple folders<br>
ex)</p>
<pre><code class="lang-auto">folderA  &gt; folderB&gt; folderC
CatDataSet    -Train - White
                     - Black
                     - Brown

              -Test  - White
                     - Black
                     - Brown

              -Val   - White
                     - Black
                     - Brown
</code></pre>
<p>Here is my test function</p>
<pre><code class="lang-auto">def test(model, data_loader, device):
    print('Start test..')
    model.eval()
    with torch.no_grad():
        correct = 0
        total = 0
        for i, (imgs, labels) in enumerate(data_loader): 
            imgs = imgs.to(device)   #imgs type &lt;class 'torch.Tensor'&gt; 
            print("first labels",type(label))
            labels =  labels.to(device)  
            print("second labels",type(label))
            outputs = model(imgs)   
            print(outputs)     
            _, argmax = torch.max(outputs, 1)  
            total += imgs.size(0)
            correct += (labels == argmax).sum().item()
    print('Test accuracy for {} images: {:.2f}%'.format(total, correct / total * 100))
    model.train()
</code></pre>
<p>Here is my CNN function</p>
<pre><code class="lang-auto">class SimpleCNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv = nn.Sequential(   
            nn.Conv2d(3, 32, 3),  
            nn.BatchNorm2d(32),
            nn.ReLU(), 
            nn.MaxPool2d(2),   
            
            nn.Conv2d(32,64,3),    
            nn.BatchNorm2d(64),    
            nn.ReLU(),    
            nn.MaxPool2d(2),    
            
            nn.Conv2d(64,128,3),   
            nn.BatchNorm2d(128), 
            nn.ReLU(),   
            nn.MaxPool2d(2),  
            
            nn.Conv2d(128,128,3),  
            nn.BatchNorm2d(128),    
            nn.ReLU(),   
            nn.MaxPool2d(2),  
        )        
       
        self.fc1 = nn.Linear(128*5*5,512) 
        self.fc2 = nn.Linear(512,3) 
        self.relu = nn.ReLU()
    
    def forward(self, x):
        x = self.conv(x)
        x = x.view(x.shape[0], -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x
</code></pre>
<p>Here is DataSet function</p>
<pre><code class="lang-auto">class CatDataset(Dataset):
    def __init__(self, data_dir, mode, transform=None):    
        self.all_data = sorted(glob.glob(os.path.join(data_dir, mode, '*', '*')))        
        self.transform = transform
    
    def __getitem__(self, index):
        data_path = self.all_data[index]   
        imgs = Image.open(data_path)
        imgs = self.transform(imgs)       
        label = os.path.basename(data_path) 
        print("data_path label",type(label)) #label type : str
        if label.startswith("Black"):
            label=0
        elif label.startswith("White"):
            label=1
        elif label.startswith("Brown"):
            label=2
        print("label",type(label)) #label type : int
        return imgs, label
    
    def __len__(self):
        length = len(self.all_data)
        return length
</code></pre>
<p>Please help me where did I wrote wrong code.</p>

ptrblck: <p>Based on the error message it seems that <code>labels</code> is indeed a <code>tuple</code>, while you expect it to be a tensor. You can check it by printing its type before calling the <code>to()</code> operation during the training and see, if this type changes in a specific iteration:</p>
<pre><code class="lang-python">print(type(labels))
labels = labels.to(device)
</code></pre>

MJChoi: <p>Hi <a class="mention" href="/u/ptrblck">@ptrblck</a> , Thank you for the helping.<br>
I try to what you saying and here is the debugging result.</p>
<p>I did “print(type(labels))” in train function and test function.<br>
When I did in train, It worked well. (before and after to() type print ‘torch.Tensor’)</p>
<p>But, in test function, It wasn’t.<br>
Until 59s, It worked well.(Print 13 times like below)<br>
CatDataset print →  label type : class ‘str’ (data_path label)-&gt;class ‘int’(label)<br>
Test print → labels type : &lt;class ‘torch.Tensor’&gt; → &lt;class ‘torch.Tensor’&gt;</p>
<p>And after 59s, It print like below.<br>
CatDataset print →  label type : class ‘str’ (data_path label)-&gt;<strong>class ‘str’(label)</strong><br>
Test print → labels type : <strong>&lt;class ‘Tuple’’&gt;</strong></p>
<p>I’m not sure which point make it to change tuple.</p>
<p>Here is my debug result in test.</p>
<pre><code class="lang-auto">data_path label &lt;class 'str'&gt;
label &lt;class 'int'&gt;
...
first labels &lt;class 'torch.Tensor'&gt;
second labels &lt;class 'torch.Tensor'&gt;
tensor([[  5.1988, -10.0191,   5.5972],
        [  5.4772,  -8.9061,   4.4289],
		...
        [  2.7645,  -6.2371,   3.9978]])

...
x 13 times 
...

data_path label &lt;class 'str'&gt;
label &lt;class 'str'&gt;
first labels&lt;class 'torch.Tensor'&gt;
second labels&lt;class 'torch.Tensor'&gt;
tensor([[-2.4606,  4.5739, -2.4098],
        [-1.8784,  4.2095, -2.1987]])
first labels &lt;class 'tuple'&gt;
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
&lt;ipython-input-30-b1da10816353&gt; in &lt;module&gt;()
----&gt; 1 test(model, test_loader, device)

&lt;ipython-input-28-297ea79abffe&gt; in test(model, data_loader, device)
     10             imgs = imgs.to(device)
     11             print("first labels",type(labels))
---&gt; 12             labels =  labels.to(device)       
     13             print("second labels",type(labels))

AttributeError: 'tuple' object has no attribute 'to'
</code></pre>

ptrblck: <p>Based on the output it seems that the working iterations are creating the <code>label</code> initially as a <code>str</code> and in the conditions are replacing it with an <code>int</code>:</p>
<pre><code class="lang-python">        print("data_path label",type(label)) #label type : str
        if label.startswith("Black"):
            label=0
        elif label.startswith("White"):
            label=1
        elif label.startswith("Brown"):
            label=2
</code></pre>
<p>However, the breaking case seems to fall through the condition (no condition returns <code>True</code>) and thus the <code>label</code> stays as a <code>str</code> type and raises the error in the test loop.<br>
In that case, you should check why no condition is met and if you would need to define a default <code>else</code> branch in the <code>__getitem__</code> method.</p>

MJChoi: <p>Thank you a lot <a class="mention" href="/u/ptrblck">@ptrblck</a>!!<br>
I spend a lot of time to fix the bug <img src="https://discuss.pytorch.org/images/emoji/apple/disappointed_relieved.png?v=9" title=":disappointed_relieved:" class="emoji" alt=":disappointed_relieved:">…</p>