索引张量必须与自张量具有相同的维数

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

我有一个看起来像

的数据集
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)和目标(邻居)组成,它被用作测试标签传播的样本。 Classes/Labels 位于 Scale_num 列内,可以一步一步地从 -2 到 2 取值。标签 9 表示未标记,这是我想使用标签传播算法预测的标签。 在 Google 上寻找一些关于标签传播的例子,我发现这段代码很有用(区别在于标签分配,因为在我的 df 中我已经有关于标记的数据的信息 - 从 -2 到 2 一步一步, 和未标记的, 即 9): https://mybinder.org/v2/gh/thibaudmartinez/label-propagation/master?filepath=notebook.ipynb 但是,尝试使用我的 类 而不是原始代码中的 (-1,0,1),我遇到了一些错误。用户在这里提供了一些帮助:,用于修复 RunTimeError,不幸的是仍然没有成功。
在link上提供的答案中,随机生成了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 的方式,在那个 link 提供的答案中从未定义过)。 原代码中导致错误的两个函数如下:

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()

我想了解如何以正确的方式使用我的 classes/labels 定义和来自我的 df 的信息,以便 运行 标签传播算法没有错误。

我怀疑它在抱怨 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,它 return 就是 (40,1)。但是,当您只是将 pandas 级数转换为张量时,它将 return 形状为 (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)