PyTorch OCR任务调用cuda()报错:'str'对象无'cuda'属性
问题分析与解决
错误原因
你的标签是字符串类型,而.cuda()和.to('cuda')是PyTorch Tensor专属方法,字符串对象没有这些属性,因此触发报错。从Dataset代码可以看到,item['label'] = imagefile.split('_')[0]直接提取了文件名中的文本作为标签,确实是字符串格式。
解决方案
方案1:跳过字符串标签的GPU迁移
字符串标签无需放到GPU上,OCR任务中通常需要先将字符串转为对应的数值索引序列(通过字符字典映射),这一步可在预处理或自定义Collator中完成,转成Tensor后再迁移GPU。只需处理图像数据即可:
batch["img"] = [img.cuda() for img in batch["img"]] # 字符串标签无需执行cuda()迁移,后续转成tensor再处理
方案2:将字符串标签转为数值Tensor后再迁移GPU
如果模型需要Tensor类型的标签,先定义字符到索引的映射字典,再将字符串标签转为数值序列Tensor:
- 定义字符映射字典(根据实际任务的字符集合调整):
char2idx = {'0':0, '1':1, 'a':26, 'b':27, ...} # 覆盖所有可能出现的字符
- 修改Dataset的
__getitem__方法,将字符串标签转为Tensor:
label_str = imagefile.split('_')[0] label_tensor = torch.tensor([char2idx[c] for c in label_str], dtype=torch.long) item['label'] = label_tensor
- 此时即可正常执行GPU迁移:
batch["img"] = [img.cuda() for img in batch["img"]] batch["label"] = [label.cuda() for label in batch["label"]]
方案3:用自定义Collator统一处理数据与设备迁移
更规范的做法是在SynthCollator中完成Tensor整理和设备迁移,避免在训练循环中手动处理:
class SynthCollator: def __init__(self, char2idx=None, device='cuda'): self.char2idx = char2idx self.device = device def __call__(self, batch): # 整理图像为batch tensor并迁移GPU imgs = [item['img'] for item in batch] imgs_tensor = torch.stack(imgs).to(self.device) if self.char2idx: # 将字符串标签转成数值tensor并做padding(适配OCR标签长度不一致的情况) labels = [torch.tensor([self.char2idx[c] for c in item['label']]) for item in batch] labels_tensor = torch.nn.utils.rnn.pad_sequence(labels, batch_first=True).to(self.device) return {'img': imgs_tensor, 'label': labels_tensor} else: # 保留字符串标签,不迁移到GPU labels = [item['label'] for item in batch] return {'img': imgs_tensor, 'label': labels}
后续训练时,DataLoader会直接输出已完成设备迁移的batch数据,无需手动调用.cuda()。
内容的提问来源于stack exchange,提问作者Chaine
相关产品推荐
相关产品推荐

