TypeError: only integer tensors of a single element can be converted to an index

ashmeet13: <p>I am facing the following error -</p>
<blockquote>
<p>TypeError: only integer tensors of a single element can be converted to an index</p>
</blockquote>
<p>In the following code. I am even doing a forceful conversion to int datatype and  yet I am facing this problem. It occurs when I try to access specific embedding layers.</p>
<pre><code class="lang-auto">userEmbeddings = self.userEmbeds[userIndex]
</code></pre>
<p>The complete code is:</p>
<pre><code class="lang-auto">class EmbeddingModel(nn.Module):
    def __init__(self,userC,movieC,embedDim):
        super(EmbeddingModel, self).__init__()
        self.userEmbeds = nn.Embedding(userC, embedDim)
        self.movieEmbeds = nn.Embedding(movieC, embedDim)
        self.fc1 = nn.Linear(2*embedDim, embedDim)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(embedDim, 5)
        
    def forward(self, userIndex, movieIndex):
        userIndex = userIndex.to(dtype = torch.int, device = device)
        movieIndex = movieIndex.to(dtype = torch.int, device = device)
        print(userIndex.type(),movieIndex.type())
        # ----- Output - torch.cuda.IntTensor torch.cuda.IntTensor
        # Error occurs in the following line --------
        userEmbeddings = self.userEmbeds[userIndex]
        movieEmbeddings = self.movieEmbeds[movieIndex]
        inp = torch.cat([userEmbeddings,movieEmbeddings],1)
        out = self.fc1(inp)
        out = self.relu(out)
        out = self.fc2(out)
        return out
</code></pre>
<p>The following is my calling code for the model -</p>
<pre><code class="lang-auto">device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
for epoch in range(epochs):
    for i, (users,movies,ratings) in enumerate(train_loader):        
        if torch.cuda.is_available():
            users = Variable(users.cuda())
            movies = Variable(movies.cuda())
            ratings = Variable(ratings.cuda())
        else:
            users = Variable(users)
            movies = Variable(movies)
            ratings = Variable(ratings)
        outputs = model(users,movies)
</code></pre>
<p>How do I index my models embedding layer this way?</p>

ptrblck: <p>Could you try to pass the indices as <code>LongTensor</code>s?<br>
If they are not already in that type, just use <code>.to(dtype=torch.long, device=device)</code>.</p>
<p>PS: <code>Variables</code> are deprecated since PyTorch <code>0.4</code>. If you are using a newer version, you can just use tensors instead.</p>

ashmeet13: <p>Thank you!<br>
It works by making the change you asked along with changing</p>
<pre><code class="lang-auto">userEmbeddings = self.userEmbeds[userIndex]
movieEmbeddings = self.movieEmbeds[movieIndex]
</code></pre>
<p>To --&gt;</p>
<pre><code class="lang-auto">userEmbeddings = self.userEmbeds(userIndex)
movieEmbeddings = self.movieEmbeds(movieIndex)
</code></pre>

xijiz: <p>This answer really helps me a lot. It is important that we must use the bracket ‘<strong>()</strong>’ instead of the bracket ‘[]’.</p>
<p>Thanks!!</p>

desmond13: <p>I am new to pytorch and I am having the same error posted here as you can see below:</p>
<pre><code class="lang-auto">File "/home/.../CenterFusion/src/lib/utils/pointcloud.py", line 282, in pc_dep_to_hm_torch
    bbox_int = torch.tensor([torch.floor(bbox[0]), 
TypeError: only integer tensors of a single element can be converted to an index
</code></pre>
<p>which is thrown by the following piece of code:</p>
<pre><code class="lang-auto"> bbox_int = torch.tensor([torch.floor(bbox[0]), 
                         torch.floor(bbox[1]), 
                         torch.ceil(bbox[2]), 
                         torch.ceil(bbox[3])], dtype=torch.int32)# format: xyxy
</code></pre>
<p>where:</p>
<p><code>type bbox:  &lt;class 'torch.Tensor'&gt;</code></p>
<p>Can anyone please help me? I could not seem to apply the solution <a class="mention" href="/u/ptrblck">@ptrblck</a> provided in his comment to my problem.</p>
<p>Thanks!</p>

ptrblck: <p>That’s a bit weird, since you are already passing an integer index.<br>
Could you <code>print(bbox)</code> and post the output here, please?</p>

desmond13: <p>Hi <a class="mention" href="/u/ptrblck">@ptrblck</a> , thanks for your quick reply.</p>
<p>I solved my problem.</p>
<p>I think that the problem was a pytorch version issue. I am trying to use for what I do <code>pytorch 1.9.1</code></p>
<p>I found out that between previous versions of torch and mine (pytorch 1.9.1) the functions<br>
<code>torch.floor()</code> and <code>torch.ceil()</code> return different types. For pytorch 1.4.0 they returned an <code>int</code> while now they return a tensor.</p>
<p>Therefore, the solution to my problem was to change (in the file <code>CenterFusion/src/lib/utils/pointcloud.py</code>) the lines:</p>
<pre><code class="lang-auto">    bbox_int = torch.tensor([torch.floor(bbox[0]), 
                         torch.floor(bbox[1]), 
                         torch.ceil(bbox[2]), 
                         torch.ceil(bbox[3])], dtype=torch.int32)# format: xyxy
</code></pre>
<p>to</p>
<pre><code class="lang-auto">    bbox_int = torch.tensor([int(torch.floor(bbox[0])), 
                         int(torch.floor(bbox[1])), 
                         int(torch.ceil(bbox[2])), 
                         int(torch.ceil(bbox[3]))], dtype=torch.int32)# format: xyxy
</code></pre>
<p>Does it sound reasonable?<br>
Thanks for the help!</p>

desmond13: <p>I printed what you asked too:</p>
<pre><code class="lang-auto">type bbox:  &lt;class 'torch.Tensor'&gt;
bbox[0]:  tensor(137.9395, device='cuda:0')
type(bbox[0]):  &lt;class 'torch.Tensor'&gt;

</code></pre>

ptrblck: <p>Hmm, that’s strange. Let me check, if this is expected behavior:</p>
<pre><code class="lang-python">torch.tensor([torch.tensor(0.), torch.tensor(1.)]) # works
torch.tensor([torch.tensor(0), torch.tensor(1)], dtype=torch.int32) # works
torch.tensor([torch.tensor(0.), torch.tensor(1.)], dtype=torch.int32) # fails
# &gt; TypeError: only integer tensors of a single element can be converted to an index
</code></pre>

Dealon_let: <p>Any update? I also have the same error</p>
<pre><code class="lang-auto">
torch.tensor([torch.tensor(0.), torch.tensor(1.)]) # works
torch.tensor([torch.tensor(0), torch.tensor(1)], dtype=torch.int32) # works
torch.tensor([torch.tensor(0.), torch.tensor(1.)], dtype=torch.int32) # fails
# &gt; TypeError: only integer tensors of a single element can be converted to an index
</code></pre>

tcuongd: <p>Hello, I might be having a related issue. I have a custom Dataset where <code>__getitem__</code> can take a list / tensor of integers as the index and return arrays from the data.</p>
<p>Indexing the custom Dataset works as expected, e.g.</p>
<pre><code class="lang-python">data = InteractionDataset(TRAIN_PATH, n_rows=200000)
data[torch.tensor([2, 1, 23])]
# works
</code></pre>
<p>However when I take subsets of the data (train / validation split), the same indexing gives me the error described above:</p>
<pre><code class="lang-python">validation_size = int(0.2 * len(data))
dtrain, dval = torch.utils.data.random_split(data, [len(data) - validation_size, validation_size])
dval[torch.tensor([2, 1, 23])]
# fails with only integer tensors of a single element can be converted to an index
</code></pre>
<p>I’ve tried converting to a long tensor as well (<code>torch.tensor([2, 1, 23], dtype=torch.long)</code>) but get the same results. Do you have any idea what might be going on here?</p>
<p>Thank you!</p>

mathfirst: <p><a class="mention" href="/u/tcuongd">@tcuongd</a>  I have the same issue, have you solved it?</p>

tcuongd: <p>Hey, it’s been a while so I’ve forgotten exactly what I was using the code for, but it seems like I pinned the problem down to the random_split() function and avoided using it altogether. So for training and validation I:</p>
<ul>
<li>Manually created two <code>List[int]</code> (one for training and one for validation).</li>
<li>Extracted the validation data using the Dataset indexing which worked fine.</li>
<li>Within each epoch, used a custom sampler to create and access the training batches, e.g.</li>
</ul>
<pre><code class="lang-python">for j in range(epochs):
        train_loader = torch.utils.data.DataLoader(
            data, batch_size=None, sampler=ArrayBatchSampler(data, batch_size, train_indices)
        )
</code></pre>

mathfirst: <p>Thanks for your response.</p>

drscotthawley: <p>I’m getting the same error, but I’m <em>not</em> doing indexing: The line that throws this error is just a series of additions and multiplications between tensors:</p>
<pre><code class="lang-python">return out_masked + (out - out_masked) * embedding_scale
</code></pre>
<p>and yet the error at this line reads</p>
<pre><code class="lang-python">TypeError: only integer tensors of a single element can be converted to an index
</code></pre>
<p>I’m not sure how to debug this, given the difference between my code and error message.</p>
<p><a class="mention" href="/u/ptrblck">@ptrblck</a> Any suggestions?   Thanks.</p>
<hr>
<p><strong>UPDATE:</strong> Turns out that <code>embedding_scale</code> was not the single number it was supposed to be, but rather a list (“<code>[4]</code>”).  So apparently multiplying by a list was getting regarded as indexing?  Interesting.</p>
<p>One can reproduce this error with the simple code</p>
<pre><code class="lang-python">torch.tensor([1,2,3])*[4]
</code></pre>
<p>I wonder if there might be a more appropriate error message in this case, such as “<code>Cannot multiply tensor by list</code>”?</p>
<p>To fix the error, one can either unwrap the [4] or wrap it in <code>torch.Tensor</code>: both<br>
<code>torch.tensor([1,2,3])*[4][0]</code> and <code>torch.tensor([1,2,3])*torch.tensor([4])</code> work fine.</p>

ptrblck: <p>The error is indeed not really helpful. Would you mind creating an issue on GitHub so that we could track and improve it, please?</p>

drscotthawley: <p>Sure!  Would that be a “Bug Report” or a “Feature Request”?</p>

ptrblck: <p>I think you could start with a featue request and someone could edit it if needed. I’m not in front of my workstation to check if this is a regression or if your code snippet was already failing in older releases.</p>