【问题标题】:Index tensor must have the same number of dimensions as self tensor索引张量必须与自张量具有相同的维数
【发布时间】:2021-09-10 03:18:22
【问题描述】:

我有一个看起来像的数据集

ID  Target  Weight    Score   Scale_Cat   Scale_num
0   A   D   65.1       87        Up  1
1   A   X   35.8       87        Up  1
2   B   C   34.7       37.5    Down    -2
3   B   P   33.4       37.5    Down    -2
4   C   B   33.1       37.5    Down    -2
5   S   X   21.4       12.5    NA  9

该数据集由节点(ID)和目标(邻居)组成,它已被用作测试标签传播的样本。类/标签在 Scale_num 列内,可以一步一步地取值从 -2 到 2。标签 9 表示未标记,它是我想使用标签传播算法预测的标签。 在 Google 上寻找一些关于标签传播的示例,我发现这段代码很有用(区别在于标签分配,因为在我的 df 中,我已经有关于已标记数据的信息 - 从 -2 到 2 以 1 为单位,并且未标记,即 9): https://mybinder.org/v2/gh/thibaudmartinez/label-propagation/master?filepath=notebook.ipynb 但是,尝试使用我的类而不是原始代码中的 (-1,0,1),我遇到了一些错误。一位用户在这里提供了一些帮助:RunTimeError during one hot encoding,用于修复 RunTimeError,不幸的是仍然没有成功。
在该链接提供的答案中,随机生成了 40 个 obs 和标签。

import random
labels = list()
for i in range(0,40):
    labels.append(list([(lambda x: x+2 if x !=9 else 5)(random.sample(classes,1)[0])]))  

index_aka_labels = torch.tensor(labels)
torch.zeros(40, 6, dtype=src.dtype).scatter_(1, index_aka_labels, 1)

我得到的错误仍然是 RunTimeError,似乎仍然是由于编码错误。我尝试的是以下内容:

import random
labels = list(df['Scale_num']) 


index_aka_labels = torch.tensor(labels)
torch.zeros(len(df), 6, dtype=src.dtype).scatter_(1, index_aka_labels, 1)

得到错误

---> 7 torch.zeros(len(df), 6, dtype=src.dtype).scatter_(1, index_aka_labels, 1)

RuntimeError: Index tensor must have the same number of dimensions as self tensor

当然,我遗漏了一些东西(例如,使用类和标签以及 src 的方式,该链接中提供的答案中从未定义过)。 原代码中导致错误的两个函数如下:

def _one_hot_encode(self, labels):
    # Get the number of classes
    classes = torch.unique(labels) # probably this should be replaced
    classes = classes[classes != -1] # unlabelled. In my df the unlabelled class is identified by 9 
    self.n_classes = classes.size(0)

    # One-hot encode labeled data instances and zero rows corresponding to unlabeled instances
    unlabeled_mask = (labels == -1) # In my df the unlabelled class is identified by 9 
    labels = labels.clone()  # defensive copying
    labels[unlabeled_mask] = 0
    self.one_hot_labels = torch.zeros((self.n_nodes, self.n_classes), dtype=torch.float)
    self.one_hot_labels = self.one_hot_labels.scatter(1, labels.unsqueeze(1), 1)
    self.one_hot_labels[unlabeled_mask, 0] = 0

    self.labeled_mask = ~unlabeled_mask

def fit(self, labels, max_iter, tol):
    
    self._one_hot_encode(labels)

    self.predictions = self.one_hot_labels.clone()
    prev_predictions = torch.zeros((self.n_nodes, self.n_classes), dtype=torch.float)

    for i in range(max_iter):
        # Stop iterations if the system is considered at a steady state
        variation = torch.abs(self.predictions - prev_predictions).sum().item()
        

        prev_predictions = self.predictions
        self._propagate()

我想了解如何以正确的方式使用我的类/标签定义和我的 df 中的信息,以便正确运行标签传播算法。

【问题讨论】:

  • 您的示例不完整。您能否更新并定义所有变量?
  • 嗨 Berriel,我添加了所有信息。问题在于使用来自我的数据框中的信息,其中我的数据已经标记为 (-2,-1,0,1,2) 和未标记 (9)。这是一个标签传播的例子。在示例中(从笔记本到答案),数据是随机生成的。就我而言,我使用的是具有多类目标的数据框,并包含我想要预测的标签信息 (9)。
  • 我指的是你的第一个例子,它仍然不完整。 classessrc 仍未定义。 IMO,您添加的代码只是使问题变得混乱。
  • 关于 src,我不知道它是如何定义的,因为我在这里的问题的答案中也缺少它:stackoverflow.com/questions/68045496/…。类最初定义如下classes = torch.unique(labels),但按照答案中的示例,我将其重新定义为classes = list([-2,-1,0,1,2,9]) classes = classes[classes != 9] # unlabelled 。我正在尝试重写问题以提供更多清晰度

标签: python pytorch torch one-hot-encoding


【解决方案1】:

我怀疑它在抱怨 index_aka_labels 缺少单例维度。请注意,在您的示例中有效:

import random
labels = list()
for i in range(0,40):
    labels.append(list([(lambda x: x+2 if x !=9 else 5)(random.sample(classes,1)[0])]))  

index_aka_labels = torch.tensor(labels)
torch.zeros(40, 6, dtype=src.dtype).scatter_(1, index_aka_labels, 1)

如果你运行index_aka_labels.shape,它会返回(40,1)。但是,当您将 pandas 系列转换为张量时,它将返回形状为 (M) 的张量(其中 M 是系列的长度)。如果你只是运行:

import random
labels = list(df['Scale_num']) 
index_aka_labels = torch.tensor(labels)[:,None] #create another dimension
torch.zeros(len(df), 6, dtype=src.dtype).scatter_(1, index_aka_labels, 1)

错误应该会消失。

还有一件事,您并没有像在上面的示例中那样将标签转换为索引。为此,您可以运行:

import random
labels = list(df['Scale_num']) 
index_aka_labels = torch.tensor(labels)[:,None] #create another dimension
index_aka_labels = index_aka_labels + 2 # labels are [-2,-1,0,1,2] and convert them to [0,1,2,3,4]
index_aka_labels[index_aka_labels==11] = 5 #convert label 9 to index 5
torch.zeros(len(df), 6, dtype=src.dtype).scatter_(1, index_aka_labels, 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    相关资源
    最近更新 更多