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

动手学习深度学习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日