我正在处理一个分类问题,其中有一个字符串列表作为类标签,我想将它们转换为张量。目前,我尝试使用numpy模块提供的np.array
函数将字符串列表转换为numpy数组。
truth = torch.from_numpy(np.array(truths))
但是我遇到了以下错误:
RuntimeError: 无法将给定的np.ndarray转换为张量-它具有无效类型。唯一支持的类型是:double、float、int64、int32和uint8。
请问有哪些替代方法?谢谢。
我正在处理一个分类问题,其中有一个字符串列表作为类标签,我想将它们转换为张量。目前,我尝试使用numpy模块提供的np.array
函数将字符串列表转换为numpy数组。
truth = torch.from_numpy(np.array(truths))
但是我遇到了以下错误:
RuntimeError: 无法将给定的np.ndarray转换为张量-它具有无效类型。唯一支持的类型是:double、float、int64、int32和uint8。
请问有哪些替代方法?谢谢。
很遗憾,现在你不能这样做。我认为这不是一个好主意,因为它会使PyTorch变得笨重。一种常用的解决方法是使用sklearn将其转换为数值类型。
以下是一个简短的示例:
from sklearn import preprocessing
import torch
labels = ['cat', 'dog', 'mouse', 'elephant', 'pandas']
le = preprocessing.LabelEncoder()
targets = le.fit_transform(labels)
# targets: array([0, 1, 2, 3, 4])
targets = torch.as_tensor(targets)
# targets: tensor([0, 1, 2, 3, 4])
因为您可能需要将真实标签和转换后的标签相互转换,所以最好存储变量 le
。
技巧是首先找到列表中单词的最大长度,然后在第二个循环中使用零填充来填充张量。请注意,UTF8字符串每个字符需要两个字节。
In[]
import torch
words = ['שלום', 'beautiful', 'world']
max_l = 0
ts_list = []
for w in words:
ts_list.append(torch.ByteTensor(list(bytes(w, 'utf8'))))
max_l = max(ts_list[-1].size()[0], max_l)
w_t = torch.zeros((len(ts_list), max_l), dtype=torch.uint8)
for i, ts in enumerate(ts_list):
w_t[i, 0:ts.size()[0]] = ts
w_t
Out[]
tensor([[215, 169, 215, 156, 215, 149, 215, 157, 0],
[ 98, 101, 97, 117, 116, 105, 102, 117, 108],
[119, 111, 114, 108, 100, 0, 0, 0, 0]], dtype=torch.uint8)
如果您不想使用sklearn,另一种解决方案是保留原始列表并创建一个额外的索引列表,您可以在之后引用它以返回到原始值。我特别需要这个功能,当我需要在批处理标记字符串时跟踪我的原始字符串时。
下面是示例:
labels = ['cat', 'dog', 'mouse']
sentence_idx = np.linspace(0,len(labels), len(labels), False)
# [0, 1, 2]
torch_idx = torch.tensor(sentence_idx)
# do what ever you would like from torch eg. pass it to a dataloader
dataset = TensorDataset(torch_idx)
loader = DataLoader(dataset, batch_size=1, shuffle=True)
for batch in iter(loader):
print(batch[0])
print(labels[int(batch[0].item())])
# output:
# tensor([0.], dtype=torch.float64)
# cat
# tensor([1.], dtype=torch.float64)
# dog
# tensor([2.], dtype=torch.float64)
# mouse
对于我的具体用例,代码看起来像这样:
input_ids, attention_masks, labels = tokenize_sentences(tokenizer, sentences, labels, max_length)
# create a indexes tensor to keep track of original sentence index
sentence_idx = np.linspace(0,len(sentences), len(sentences),False )
torch_idx = torch.tensor(sentence_idx)
dataset = TensorDataset(input_ids, attention_masks, labels, torch_idx)
loader = DataLoader(dataset, batch_size=1, shuffle=True)
for batch in loader:
_, logit = model(batch[0],
token_type_ids=None,
attention_mask=batch[1],
labels=batch[2])
pred_flat = np.argmax(logit.detach(), axis=1).flatten()
print(pred_flat)
print(batch[2])
if pred_flat == batch[2]:
print("\nThe following sentence was predicted correctly:")
print(sentences[int(batch[3].item())])
truth = [float(truths) for x in truths]
truth = np.asarray(truth)
truth = torch.from_numpy(truth)