Index 2169 is out of bounds for dimension 0 with size 4

Mike_Taylor: <p>I launched my project in a year and had next error. I used a pic with IMG_SIZE[64, 64].</p>
<h1><a name="what-uses-1" class="anchor" href="#what-uses-1"></a>What uses:</h1>
<ul>
<li>Python 3.8.2</li>
<li>Torch==1.7.1</li>
<li>TorchVision==0.8.2</li>
</ul>
<h1><a name="os-2" class="anchor" href="#os-2"></a>OS</h1>
<ul>
<li>Mac OS 11.2.3</li>
</ul>
<h1><a name="for-image-classification-3" class="anchor" href="#for-image-classification-3"></a>For image classification:</h1>
<pre><code class="lang-auto">imgs = []

directory = 'photo'
files = os.listdir(directory)
for x in files:
    files_dir = directory +'/'+ x
    imgs_dir = os.listdir(files_dir)

    for imgsX in imgs_dir:
        img_dir = files_dir +'/'+ imgsX
        img = cv2.imread(img_dir)
        img = cv2.resize(img, (64, 64))  
        img = skimage.color.rgb2gray(img)
        imgs.append(img)


Image size (64, 64)

</code></pre>
<h2><a name="my-som-class-4" class="anchor" href="#my-som-class-4"></a>My SOM class:</h2>
<pre><code class="lang-auto">class SOM(nn.Module):

    def __init__(self, input_size, out_size, lr=0.3, sigma=None):
        '''
        :param input_size:
        :param out_size:
        :param lr:
        :param sigma:
        '''
        super(SOM, self).__init__()
        self.input_size = input_size
        self.out_size = out_size

        self.lr = lr
        if sigma is None:
            self.sigma = max(out_size) / 2
        else:
            self.sigma = float(sigma)

        self.weight = nn.Parameter(torch.randn(input_size, out_size[0] * out_size[1]), requires_grad=False)
        self.locations = nn.Parameter(torch.Tensor(list(self.get_map_index())), requires_grad=False)
        self.pdist_fn = nn.PairwiseDistance(p=2)

    def get_map_index(self):
        # Two-dimensional mapping function
        for x in range(self.out_size[0]):
            for y in range(self.out_size[1]):
                yield (x, y)

    def _neighborhood_fn(self, input, current_sigma):
        '''e^(-(input / sigma^2))'''
        input.div_(current_sigma ** 2)
        input.neg_()
        input.exp_()

        return input

    def forward(self, input):
        '''
        Find the location of best matching unit.
        :param input: data
        :return: location of best matching unit, loss
        '''
        batch_size = input.size()[0]
        input = input.view(batch_size, -1, 1)
        batch_weight = self.weight.expand(batch_size, -1, -1)

        dists = self.pdist_fn(input, batch_weight)
        # Find best matching unit
        losses, bmu_indexes = dists.min(dim=1, keepdim=True)
        bmu_locations = self.locations[bmu_indexes]

        return bmu_locations, losses.sum().div_(batch_size).item()

    def self_organizing(self, input, current_iter, max_iter):
        '''
        Train the Self Oranizing Map(SOM)
        :param input: training data
        :param current_iter: current epoch of total epoch
        :param max_iter: total epoch
        :return: loss (minimum distance)
        '''
        batch_size = input.size()[0]
        #Set learning rate
        iter_correction = 1.0 - current_iter / max_iter
        lr = self.lr * iter_correction
        sigma = self.sigma * iter_correction

        #Find best matching unit
        bmu_locations, loss = self.forward(input)

        distance_squares = self.locations.float() - bmu_locations.float()
        distance_squares.pow_(2)
        distance_squares = torch.sum(distance_squares, dim=2)


        lr_locations = self._neighborhood_fn(distance_squares, sigma)
        lr_locations.mul_(lr).unsqueeze_(1)

        delta = lr_locations * (input.unsqueeze(2) - self.weight)
        delta = delta.sum(dim=0)
        delta.div_(batch_size)
        self.weight.data.add_(delta)

        return loss

    def save_result(self, dir, im_size=(0, 0, 0)):
        '''
        Visualizes the weight of the Self Oranizing Map(SOM)
        :param dir: directory to save
        :param im_size: (channels, size x, size y)
        :return:
        '''
        images = self.weight.view(im_size[0], im_size[1], im_size[2], self.out_size[0] * self.out_size[1])

        images = images.permute(3, 0, 1, 2)
        save_image(images, dir, normalize=True, padding=1, nrow=self.out_size[0])
</code></pre>
<h1><a name="training-5" class="anchor" href="#training-5"></a>Training:</h1>
<pre><code class="lang-auto">from ipywidgets import widgets
from IPython.display import display

niter = 20
m = 2 # output fields
n = 2
model = SOM(
    input_size=img.shape[0] * img.shape[1] * 1,
    out_size=(m, n, 1), sigma=1)

out = widgets.Output()
out_clusters = widgets.Output()
out_history = widgets.Output()
display(widgets.VBox([out, out_clusters, out_history]))

print("Start train")
X = torch.from_numpy(img)
model.train()
losses = []
for it in tqdm(range(niter), total=niter):
  loss = 0
  n_ = 0
  for (X, ) in dataset:
    loss += model.self_organizing(X.view(X.size()[0], -1), it, niter)
    n_ += 1
  if (it+1) % 5 == 0 or it == 0:
    with out:
      plt.figure()
      buf = model.weight.view(64, 64, -1).argmax(2).float() / 10
      out.clear_output(True)
      plt.imshow(buf, cmap='Accent')
      plt.title(f'{it+1}/{niter} iters (Error: {loss/n_})')
      plt.show()
    
    with out_clusters:
      out_clusters.clear_output(True)
      plt.figure()
      for i in range(m*n):
        plt.subplot(2, 5, i+1)
        plt.imshow(model.weight.view(64, 64, -1)[..., i])
      plt.show()

  with out_history:
    out_history.clear_output(True)
    plt.figure(figsize=(10, 3))
    plt.plot(list(range(len(losses))), (losses), 'b-')
    plt.scatter(list(range(len(losses))), (losses))
    plt.show()
    
  losses.append(loss / n_)
</code></pre>
<h1><a name="error-6" class="anchor" href="#error-6"></a>Error:</h1>
<pre><code class="lang-auto">---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
/var/folders/y5/pchlt5l12gx5_65v0_bn_fcm0000gn/T/ipykernel_60901/2590886534.py in &lt;module&gt;
     22   n_ = 0
     23   for (X, ) in dataset:
---&gt; 24     loss += model.self_organizing(X.view(X.size()[0], -1), it, niter)
     25     n_ += 1
     26   if (it+1) % 5 == 0 or it == 0:

/var/folders/y5/pchlt5l12gx5_65v0_bn_fcm0000gn/T/ipykernel_60901/671413781.py in self_organizing(self, input, current_iter, max_iter)
     74 
     75     #Find best matching unit
---&gt; 76     bmu_locations, loss = self.forward(input)
     77 
     78     distance_squares = self.locations.float() - bmu_locations.float()

/var/folders/y5/pchlt5l12gx5_65v0_bn_fcm0000gn/T/ipykernel_60901/671413781.py in forward(self, input)
     55     print(f"losses: {losses}")
     56     print(f"bmu_indexes: {bmu_indexes}")
---&gt; 57     bmu_locations = self.locations[bmu_indexes]
     58 
     59     return bmu_locations, losses.sum().div_(batch_size).item()

IndexError: index 2169 is out of bounds for dimension 0 with size 4
</code></pre>
<h1><a name="what-must-be-7" class="anchor" href="#what-must-be-7"></a>What must be:</h1>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/1/6/160e77ca6aa64df3baf63e636500d6cd3b67e229.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/160e77ca6aa64df3baf63e636500d6cd3b67e229" title="Снимок экрана 2021-12-01 в 05.55.42"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/1/6/160e77ca6aa64df3baf63e636500d6cd3b67e229_2_350x500.jpeg" alt="Снимок экрана 2021-12-01 в 05.55.42" data-base62-sha1="397v6JyS7bzlr4KYsE3IMExwebT" width="350" height="500" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/1/6/160e77ca6aa64df3baf63e636500d6cd3b67e229_2_350x500.jpeg, https://discuss.pytorch.org/uploads/default/optimized/3X/1/6/160e77ca6aa64df3baf63e636500d6cd3b67e229_2_525x750.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/1/6/160e77ca6aa64df3baf63e636500d6cd3b67e229_2_700x1000.jpeg 2x" data-dominant-color="BDCED7"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Снимок экрана 2021-12-01 в 05.55.42</span><span class="informations">984×1404 108 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>

ptrblck: <p>Based on the error message <code>self.locations</code> has a size of <code>4</code> in <code>dim0</code> while you are trying to index it with a value of <code>2169</code>. Make sure to initialize <code>self.locations</code> with the appropriate shape.<br>
Also, don’t use <code>torch.Tensor</code> as it could yield unexpected results.<br>
E.g. you are currently initializing <code>self.locations</code> via:</p>
<pre><code class="lang-python">self.locations = nn.Parameter(torch.Tensor(list(self.get_map_index())), requires_grad=False)
</code></pre>
<p>which would create a <code>FloatTensor</code> containing the list values while you might want to use the list values as a shape.<br>
Use the factory methods (<code>torch.randn</code>, <code>torch.ones</code>, <code>torch.tensor</code> etc.) instead.</p>