TypeError: tuple indices must be integers or slices, not tuple

username: Apro
cooked: <p>I am trying to run Node2Vec from the torch_geometric.nn library. For reference, I am following <a href="https://github.com/rusty1s/pytorch_geometric/blob/master/examples/node2vec.py" rel="noopener nofollow ugc">this</a> example.</p>
<p>While running the train() function I keep getting <code>TypeError: tuple indices must be integers or slices, not tuple</code></p>
<p>I am using torch version 1.6.0 with CUDA 10.1 and the latest versions of torch-scatter,torch-sparse,torch-cluster, torch-spline-conv and torch-geometric.</p>
<p>Please excuse my formatting mistakes, this is my first post.</p>
<p>Thanks for any help.</p>
<p>Here is the detailed error:</p>
<pre><code class="lang-auto">---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

&lt;ipython-input-11-cf6dc0596f64&gt; in &lt;module&gt;()
      1 for epoch in range(1, 101):
----&gt; 2     loss = train()
      3     print(f'Epoch: {epoch:02d}, Loss: {loss:.4f}')

4 frames

&lt;ipython-input-10-dfee452d1f45&gt; in train()
      3     total_loss = 0
      4     # print(loader)
----&gt; 5     for pos_rw, neg_rw in loader:
      6         optimizer.zero_grad()
      7         loss = model.loss(pos_rw.to(device), neg_rw.to(device))

/usr/local/lib/python3.6/dist-packages/torch/utils/data/dataloader.py in __next__(self)
    343 
    344     def __next__(self):
--&gt; 345         data = self._next_data()
    346         self._num_yielded += 1
    347         if self._dataset_kind == _DatasetKind.Iterable and \

/usr/local/lib/python3.6/dist-packages/torch/utils/data/dataloader.py in _next_data(self)
    854             else:
    855                 del self._task_info[idx]
--&gt; 856                 return self._process_data(data)
    857 
    858     def _try_put_index(self):

/usr/local/lib/python3.6/dist-packages/torch/utils/data/dataloader.py in _process_data(self, data)
    879         self._try_put_index()
    880         if isinstance(data, ExceptionWrapper):
--&gt; 881             data.reraise()
    882         return data
    883 

/usr/local/lib/python3.6/dist-packages/torch/_utils.py in reraise(self)
    393             # (https://bugs.python.org/issue2651), so we work around it.
    394             msg = KeyErrorMessage(msg)
--&gt; 395         raise self.exc_type(msg)

TypeError: Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/worker.py", line 178, in _worker_loop
    data = fetcher.fetch(index)
  File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/fetch.py", line 47, in fetch
    return self.collate_fn(data)
  File "/usr/local/lib/python3.6/dist-packages/torch_geometric/nn/models/node2vec.py", line 116, in sample
    return self.pos_sample(batch), self.neg_sample(batch)
  File "/usr/local/lib/python3.6/dist-packages/torch_geometric/nn/models/node2vec.py", line 97, in pos_sample
    walks.append(rw[:, j:j + self.context_size])
TypeError: tuple indices must be integers or slices, not tuple

</code></pre>

username: agt
cooked: <p>The error suggests that rw is a tuple. Check if your dataloader or dataset is yielding tuples instead of arrays/tensors and if so, re-organize it so that it outputs an array or tensor.</p>

username: Abhilash_Srivastava
cooked: <p>I think you’re doing it right. But the Node2Vec implementation has issues. Raise a bug.</p>

username: agt
cooked: <p>Looks like <code>torch.ops.torch_cluster.random_walk</code> is providing tuples instead of arrays/tensors.</p>

username: Apro
cooked: <p>I am getting a tuple of tensors in the <code>pos_sample</code> given in Node2Vec.</p>
<pre><code class="lang-auto">    def pos_sample(self, batch):
        batch = batch.repeat(self.walks_per_node)
        rowptr, col, _ = self.adj.csr()
        rw = random_walk(rowptr, col, batch, self.walk_length, self.p, self.q) 
        # rw is a tuple of tensors 
        walks = []
        num_walks_per_rw = 1 + self.walk_length + 1 - self.context_size
        for j in range(num_walks_per_rw):
            walks.append(rw[:,j:j + self.context_size])
        return torch.cat(walks, dim=0)
</code></pre>
<p>Any Idea on how to fix this?</p>

username: Apro
cooked: <p>SOLVED by replacing <code>pos_sample</code> and <code>neg_sample</code></p>
<pre><code class="lang-auto">def pos_sample(self, batch):
        batch = batch.repeat(self.walks_per_node)
        rowptr, col, _ = self.adj.csr()
        rw = random_walk(rowptr, col, batch, self.walk_length, self.p, self.q)
        if not isinstance(rw, torch.Tensor):
            rw = rw[0]

        walks = []
        num_walks_per_rw = 1 + self.walk_length + 1 - self.context_size
        for j in range(num_walks_per_rw):
            walks.append(rw[:, j:j + self.context_size])
        return torch.cat(walks, dim=0)
</code></pre>
<pre><code class="lang-auto">def neg_sample(self, batch):
        batch = batch.repeat(self.walks_per_node * self.num_negative_samples)

        rw = torch.randint(self.adj.sparse_size(0),
                           (batch.size(0), self.walk_length))
        rw = torch.cat([batch.view(-1, 1), rw], dim=-1)

        walks = []
        num_walks_per_rw = 1 + self.walk_length + 1 - self.context_size
        for j in range(num_walks_per_rw):
            walks.append(rw[:, j:j + self.context_size])
        return torch.cat(walks, dim=0)
</code></pre>
<p>Refer to PyTorch Node2Vec <a href="https://pytorch-geometric.readthedocs.io/en/latest/_modules/torch_geometric/nn/models/node2vec.html" rel="noopener nofollow ugc">documentation</a>.</p>