首页 > 解决方案 > 索引张量必须与自张量具有相同的维数

问题描述

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

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 表示未标记,它是我想使用标签传播算法预测的标签。在谷歌上寻找一些关于标签传播的例子,我发现这段代码很有用(区别在于标签分配,因为在我的 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 中的信息,以便在没有错误的情况下运行标签传播算法。

标签: pythonpytorchtorchone-hot-encoding

解决方案


我怀疑它在抱怨 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)

推荐阅读