TypeError: Variable data has to be a tensor, but got tuple

一、问题原因
  1. 类型错误:变量数据必须是张量,但得到元组
二、 源代码
1. 训练数据集
for epoch in range(10):  # 设置训练的迭代次数
    # 在测试集中迭代数据
    for i, (images,labels) in enumerate(train_loader):  # enumerate枚举数据并从下标0开始

        # 输入数据
        # 读取数据的数据内容和标签
        images = images
        labels = labels
#------------------------------------------------------------
		# 出错位置
		images, labels = Variable(images), Variable(labels) 
#------------------------------------------------------------
        print(images,labels)
        print(images.size())

        # forward+backward
        # 得到网络的输出
        outputs = model(images) # 这里卡住了
        print('outputs = ',outputs)
        
        # 计算损失值,将输出的outputs和原来导入的labels作为loss函数的输入就可以得到损失了:
        loss = criterion(outputs, labels)  # output 和 labels的交叉熵损失
三、测试办法
  1. 修改源码:打印images,labels类型,发现labels类型为元组类型:tuple
for epoch in range(10):  # 设置训练的迭代次数
    # 在测试集中迭代数据
    for i, (images,labels) in enumerate(train_loader):  # enumerate枚举数据并从下标0开始

        # 输入数据
        # 读取数据的数据内容和标签
        images = images
        labels = labels
#------------------------------------------------------------
		# 出错位置
		images, labels = Variable(images), Variable(labels) 
#-------------------------------------------------------------
#---------------------------增加代码--------------------------
		print('type(images) = ',type(images))
		print('type(labels) = ',type(labels))
#------------------------------------------------------------
        print(images,labels)
        print(images.size())

        # forward+backward
        # 得到网络的输出
        outputs = model(images) # 这里卡住了
        print('outputs = ',outputs)
        
        # 计算损失值,将输出的outputs和原来导入的labels作为loss函数的输入就可以得到损失了:
        loss = criterion(outputs, labels)  # output 和 labels的交叉熵损失
  1. 打印结果打印类型
四、验证数据集类型
  1. 在文件读取中,照片路径和标签类型都是str类型
  2. 在形成训练集过程中,照片类型转成了Tensor,而标签类型还是str类型
  3. 在开始训练,执行损失函数时,照片从Tensor转Variable,而标签是tuple转Variable。
    数据类型
五、解决方法:labels采用one hot编码
  1. 在使用损失函数时,参数output,labels都要是Variabel类型,而labels是字符串类型,采用one-hot编码的方式。
  2. 源代码:
txt_path = 'G:/train/path.txt'

num_classes = 2
batch_size = 1  # 一个batch 的大小

class MyDataset(Dataset):
    # 初始化
    def __init__(self, txt_path,transform = None, target_transform = None):
        fh = open(txt_path, 'r')
        imgs = []
        for line in fh:
            # 存储txt时 加了'\t'
            line = line.strip('\n')
            line = line.rsplit('\t')
#            print('line: = ',line)
#            print('line[0 = ]',line[0])
#            print(line[0],line[1])
#--------------------将str类型转成[]类型----------------------------
            print('type(line[1])=',type(line[1]))
            if line[1]=='dog':
                label=[0]
            else:
                label=[1]
#-------------------将[]类型转成Tensor类型-------------------------
            label = torch.Tensor(label)
#---------------将Tensor类型转成one hot类型------------------------
            label = torch.zeros(batch_size, num_classes)#.scatter_(1, label, 1)
            print(label)
            print('type(label) = ',type(label))
            imgs.append((line[0],label)) # 以元组的形式存储imgs
            self.imgs = imgs
            self.transform = transform
            arget_transform = target_transform
    # 返回df的长度 长度可能不固定,测试通过
    def __len__(self):
        return len(self.imgs)

    # 获取第index列的数据
    def __getitem__(self, index):
        img_path,label = self.imgs[index]
        # 这里是读取图片
        img = Image.open(img_path).convert('RGB')
        # 图像处理 格式转换
        img = img.resize((224,224),Image.ANTIALIAS)
        # 这里可以读取CSV文件格式
        if self.transform is not None:
            img = self.transform(img)
        return img,label
  1. 参考资料

Pytorch中,将label变成one hot编码的两种方式

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值