tjdnbj 2024-03-03 10:35 采纳率: 41.2%
浏览 3
已结题

动手学习深度学习LENET模型提问2

以下是我的代码,想问一下为何会出现Boolean value of Tensor with more than one value is ambiguous的错误?该如何修改呢?

import time
import torch
from torch import nn,optim
from torch.nn import init
import torchvision
import torchvision.transforms as transforms
import sys
sys.path.append("C:/Users/zyx20/Desktop/深度学习编程/pythonProject")
import d2lzh_pytorch as d2l
device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')

batch_size=256
if sys.platform.startswith('win'):
    num_workers = 0  # 0表示不用额外的进程来加速读取数据
else:
    num_workers = 4

mnist_train = torchvision.datasets.FashionMNIST(root='C:/Users/zyx20/Desktop/深度学习编程/MNIST/raw', train=True, download=True, transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(root='C:/Users/zyx20/Desktop/深度学习编程/MNIST/raw', train=False, download=True, transform=transforms.ToTensor())
train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet,self).__init__()
        self.conv=nn.Sequential(nn.Conv2d(1,6,5),
                                nn.Sigmoid(),
                                nn.MaxPool2d(2,2),
                                nn.Conv2d(6,16,5),
                                nn.Sigmoid(),
                                nn.MaxPool2d(2,2))
        self.fc=nn.Sequential(
            nn.Linear(16*4*4,120),
            nn.Sigmoid(),
            nn.Linear(120,84),
            nn.Sigmoid(),
            nn.Linear(84,10)
        )
    def forward(self,img):
        feature=self.conv(img)
        output=self.fc(feature.view(img.shape[0],-1))
        return output
net=LeNet()

def evaluate_accuracy(data_iter,net,device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')):
    acc_sum,n=0.0,0
    with torch.no_grad():
        for X,y in data_iter:
            if isinstance(net,torch.nn.Module):
                net.eval()#评估模式,这会关闭dropout
                acc_sum+=(net(X.to(device)).argmax(dim=1)==y.to(device)).float().sum().cpu().item()
                net.train()#改回训练模式
            else:
                if('is_training' in net.__code__.co_varnames):#如果有is_training这个参数
                    #将is_training设置为False
                    acc_sum+=(net(X,is_training=False).argmax(dim=1)==y).float().sum().cpu().item()
                else:
                    acc_sum += (net(X).argmax(dim=1) == y).float().sum().cpu().item()
            n += y.shape[0]
    return acc_sum/n

def train_ch5(net,train_iter,test_iter,loss,num_epochs,batch_size,params=None,lr=None,optimizer=None):
    net=net.to(device)
    print("training on",device)
    loss=torch.nn.CrossEntropyLoss
    batch_count=0
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n,start = 0.0, 0.0, 0,time.time()
        for X,y in train_iter:
            y_hat = net(X)
            X=X.to(device)
            y=y.to(device)
            l=loss(y_hat,y)
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
            train_l_sum+=l.cpu().item()
            train_acc_sum+=(y_hat.argmax(dim=1)==y).float().sum().cpu().item()
            n += y.shape[0]
            batch_count+=1
        test_acc=evaluate_accuracy(test_iter,net)
        print('epoch %d,loss %.4f,train acc %.3f,test acc %.3f%,time %.lf sec'%(epoch+1,train_l_sum/batch_count,train_acc_sum/n,test_acc,time.time()-start))

lr,num_epochs=0.001,5
optimizer=torch.optim.Adam(net.parameters(),lr=lr)
train_ch5(net,train_iter,test_iter,num_epochs,batch_size,optimizer,device,num_epochs)

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-03 10:35
    关注

    引自免费微信小程序:皆我百晓生

    您在代码中提到的错误信息"Boolean value of Tensor with more than one value is ambiguous"并没有直接出现在您提供的代码片段中。通常,这个错误是因为尝试将一个多元素张量(如一个布尔张量)当作单一布尔值来使用,这在PyTorch中是不明确的。

    在您的训练函数train_ch5中,我注意到您没有正确实例化损失函数torch.nn.CrossEntropyLoss。您需要创建一个损失函数对象而不是引用类本身。修改如下:

    loss = torch.nn.CrossEntropyLoss()  # 实例化损失函数
    

    此外,在调用train_ch5函数时,参数列表有误。不需要传入devicenum_epochs两次,修正后的调用应该是:

    train_ch5(net, train_iter, test_iter, loss, num_epochs, batch_size, optimizer=optimizer)
    

    以下是修正后的完整训练部分:

    def train_ch5(net, train_iter, test_iter, loss, num_epochs, batch_size, params=None, lr=None, optimizer=None):
        net = net.to(device)
        print("training on", device)
        if optimizer is None:
            optimizer = torch.optim.Adam(net.parameters(), lr=lr)
    
        for epoch in range(num_epochs):
            train_l_sum, train_acc_sum, n, start = 0.0, 0.0, 0, time.time()
            for X, y in train_iter:
                y_hat = net(X)
                l = loss(y_hat, y)  # 使用实例化的损失函数计算损失
                optimizer.zero_grad()
                l.backward()
                optimizer.step()
    
                train_l_sum += l.cpu().item()
                train_acc_sum += (y_hat.argmax(dim=1) == y).float().sum().cpu().item()
                n += y.shape[0]
    
            test_acc = evaluate_accuracy(test_iter, net)
            print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f%%, time %.1f sec' %
                  (epoch + 1, train_l_sum / (batch_count or 1), train_acc_sum / n, test_acc, time.time() - start))
    
    # 正确实例化损失函数并训练模型
    lr, num_epochs = 0.001, 5
    loss = torch.nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(net.parameters(), lr=lr)
    train_ch5(net, train_iter, test_iter, loss, num_epochs, batch_size, optimizer=optimizer)
    

    这样应该能解决潜在的问题,并且能够正确运行LENET模型的训练过程。如果还有其他问题或者错误,请提供具体的错误信息以便更准确地定位问题所在。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 3月12日
  • 已采纳回答 3月4日
  • 创建了问题 3月3日

悬赏问题

  • ¥15 vscode编译ros找不到头文件,cmake.list文件出问题,如何解决?(语言-c++|操作系统-linux)
  • ¥15 通过AT指令控制esp8266发送信息
  • ¥15 有哪些AI工具提供可以通过代码上传EXCEL文件的API接口,并反馈分析结果
  • ¥15 二维装箱算法、矩形排列算法(相关搜索:二维装箱)
  • ¥20 nrf2401上电之后执行特定任务概率性一直处于最大重发状态
  • ¥15 二分图中俩集合中节点数与连边概率的关系
  • ¥20 wordpress如何限制ip访问频率
  • ¥15 自研小游戏,需要后台服务器存储用户数据关卡配置等数据
  • ¥15 请求解答odoo17外发加工某工序的实操方法
  • ¥20 IDEA ssm项目 跳转页面报错500