• vcjmhg
    2021-11-16
    class MyCNN(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3) # conv1输出的特征图为222x222大小 self.fc = nn.Linear(16 * 222 * 222, 10) def forward(self, input): x = self.conv1(input) # 进去全连接层之前,先将特征图铺平 x = x.view(x.shape[0], -1) x = self.fc(x) return x # 尽量使用gpu进行训练,如果没有cpu则使用gpu来训练 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") cnn = MyCNN().to(device) transform = transforms.Compose([ # 修改裁剪图片的尺寸 transforms.RandomResizedCrop((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) cifar10_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, transform=transform, target_transform=None, download=True) dataloader = DataLoader(dataset=cifar10_dataset, # 传入的数据集, 必须参数 batch_size=32, # 输出的batch大小 shuffle=True, # 数据是否打乱 num_workers=2) # 进程数, 0表示只有主进程 # 定义优化器 optimizer = torch.optim.SGD(cnn.parameters(), lr=1e-4, weight_decay=1e-2, momentum=0.9) steps = 0 for epoch in range(16): for item in dataloader: steps += 1 output = cnn(item[0].to(device)) target = item[1].to(device) # 使用交叉熵损失函数 loss = nn.CrossEntropyLoss()(output, target) # 每100步打印一次loss if steps % 100 == 0: print('Epoch {}, Loss {}'.format(epoch + 1, loss)) cnn.zero_grad() loss.backward() optimizer.step() # 测试分类结果 im = Image.open('data/img.png') input_tensor = transform(im).unsqueeze(0) result = cnn(input_tensor.to(device)).argmax() print(result) # tensor(3, device='cuda:0')
    展开

    作者回复: 👍🏻👍🏻 ^^

    共 2 条评论
    13
  • Mr_李冲
    2022-03-15
    我在使用预训练好的alexnet-owt-7be5be79.pth模型,反复执行下面这段代码的时候 alexnet(input_tensor).argmax() 得到的结果并不总是263,而有时候会得到151和264或者其他的数值,请问我最终应该相信哪一个预测结果呢,是进行多次预测取预测次数最多的那个吗?还是有别的科学的方法呢?

    作者回复: 你好,感谢你的留言。 如果保证输入一样,正常不会这样的。 你检查检查你的预处理的resize是不是会随机切割。 还是不行的话,可以把你的代码发给我看看。

    共 8 条评论
    2
  • clee
    2021-11-16
    调整之后,可以正常训练了,但是测试数据的时候我发现有些图片分类会有问题,比如狗和猫,鹿和马就容易分类错误,这是因为欠拟合吗?应该如何优化?

    作者回复: hi。 CIFAR10的图片比较小,猫和狗、鹿和马比较像,一部分图片预测错误是可以接受的。可以在下面尝试1之后,用验证集评估一下模型精确与召回,看看是否为一个可接受的结果,如果是的话,那部分图片分错是没问题的。 可以做如下尝试: 1. 把train=Fasle改为True。我为了讲解方便直接使用验证集训练的。 cifar10_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, transform=transform, target_transform=None, download=True) 2. 把学习率调小一点试试。^^

    
    2
  • zhangting
    2022-05-12
    老师请教个问题,为什么改全连接后,训练出来的模型,总是输出的是5。而未做改动前,预测出来的是263.源码如下: alexnet = models.alexnet() alexnet.load_state_dict(torch.load('./model/alexnet-owt-7be5be79.pth')) fc_in_features = alexnet.classifier[6].in_features alexnet.classifier[6] = torch.nn.Linear(fc_in_features, 10) print(alexnet) transform = transforms.Compose([ transforms.RandomResizedCrop((224,224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) cifar10_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, transform=transform, target_transform=None, download=False) dataloader = DataLoader(dataset=cifar10_dataset, batch_size=32, shuffle=True, num_workers=4) optimizer = torch.optim.SGD(alexnet.parameters(), lr=1e-4, weight_decay=1e-2, momentum=0.9) for epoch in range(3): for item in dataloader: output = alexnet(item[0]) target = item[1] loss = nn.CrossEntropyLoss()(output, target) print('Epoch {}, Loss {}'.format(epoch + 1 , loss)) alexnet.zero_grad() loss.backward() optimizer.step() im = Image.open('dog.jpg') transform = transforms.Compose([ transforms.Resize((224,224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) input_tensor = transform(im).unsqueeze(0) alexnet.eval() print(alexnet(input_tensor).argmax())
    展开

    作者回复: 你好,感谢你的留言。 输出5不是正确的吗? cifar10里dog就是5啊

    共 3 条评论
    1
  • 刘利
    2022-05-03
    hi,老师,微调的时候,如果这样写,参数都不更新了,那还有哪部分参数会被训练呢?是需要再接一层全连接层么? alexnet = models.alexnet() alexnet.load_state_dict(torch.load('./model/alexnet-owt-4df8aa71.pth')) for param in alexnet.parameters(): param.requires_grad = False

    作者回复: 你好,刘利,感谢留言。 就只训练全连接层了。 finetune的时候会根据你的分类任务,新加一个全连接层(而不是使用原模型的)

    共 2 条评论
    1
  • 马克图布
    2021-11-12
    思考: 使用 `nn.CrossEntropyLoss` 作为 loss function 时,会自动在网络最后添加 `nn.LogSoftmax` 和 `nn.nLLLos`,因此不用再在 fc 层后面手动添加 Softmax 层; 问题: transform 中,标准化的 mean 和 std 是如何确定的(我们需要使用均值为[0.485, 0.456, 0.406],标准差为[0.229, 0.224, 0.225]对数据进行正规化)?

    作者回复: 你好,马克图布,感谢你的留言。 对,内置了Softmax。 均值[0.485, 0.456, 0.406],标准差[0.229, 0.224, 0.225] 是ImageNet的均值与标准差。torchvision中的模型都是在ImageNet上训练的。

    
    1
  • Monroe He
    2023-03-19 来自北京
    老师请教一个问题,在梯度清零代码中 13 节课用的是优化器 optimizer.zero_grad() 这节课用的是模型 alexnet.zero_grad() 这两行代码有什么区别吗?

    作者回复: 抱歉,回复的太迟了。本质上没有太大区别。 但optimizer可以优化多个模型的参数。alexnet. zero_grad()指定只对alexnet的梯度进行清零。 例如,下面的代码。 # 创建多个模型 model1 = torch.nn.Linear(10, 5) model2 = torch.nn.Linear(10, 3) # 将模型的参数合并 all_parameters = list(model1.parameters()) + list(model2.parameters()) # 创建优化器,同时优化多个模型的参数 optimizer = optim.SGD(all_parameters, lr=0.01) # 在训练迭代中使用优化器来更新模型参数 for _ in range(num_epochs): optimizer.zero_grad()

    
    
  • 杨杰
    2022-10-04 来自北京
    import torchvision.models as models from PIL import Image import torchvision import torchvision.transforms as transforms alexnet = models.alexnet(pretrained=True) im = Image.open('./data/dog.jpg') transform = transforms.Compose([ transforms.RandomResizedCrop((224,224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) input_tensor = transform(im).unsqueeze(0) print(alexnet(input_tensor).argmax()) 以上代码输出的不一定是264,这个是啥情况?

    作者回复: 你好,因为使用了随机剪裁。 transforms.RandomResizedCrop((224,224))。 并且没有加alexnet.eval()

    
    
  • Geek_827444
    2022-08-09 来自北京
    老师您好:我一步一步按照咱们那个步骤来的,为什么代码运行不了那?谢谢您! import torch import torch.nn as nn import torch.optim as optim import torchvision.models as models import torchvision.models as models alexnet = models.alexnet(pretrained=True) import torchvision.transforms as transforms transform = transforms.Compose([ transforms.RandomResizedCrop((224,224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485,0.456,0.406],std=[0.229,0.224,0.225]) ]) import torchvision cifar10_dataset = torchvision.datasets.CIFAR10(root='./data',#注:这里是存在 pycharm文件当中的data文件夹里 train=False, transform=transform, target_transform=None, download=True) from torch.utils.data import DataLoader dataloader = DataLoader(dataset=cifar10_dataset, batch_size=32, shuffle=True, num_workers=2) fc_in_features = alexnet.classifier[6].in_features alexnet.classifier[6] = torch.nn.Linear(fc_in_features,10) optimizer = torch.optim.SGD(alexnet.parameters(), lr=1e-4, weight_decay=1e-2, momentum=0.9) for epoch in range(3): # ↓定义比对的元素 for item in dataloader: output = alexnet(item[0]) target = item[1] # ↓使用损失函数 loss = nn.CrossEntropyLoss()(output, target) print('Epoch{},Loss{}'.format(epoch + 1, loss)) # ↓更新损失函数和优化函数 alexnet.zero_grad() loss.backward() optimizer.step()
    展开

    作者回复: 抱歉,回复迟了。 我执行了你的代码,并没有报错。你提示什么错误呢?

    共 2 条评论
    
  • John(易筋)
    2022-08-07 来自北京
    巨人肩膀@马克图库 import torch import torch.nn as nn import torchvision import torchvision.transforms as transforms from PIL import Image transform = transforms.Compose([ transforms.RandomResizedCrop((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) cifar10_train_dataset = torchvision.datasets.CIFAR10(root='./data',train=True,transform=transform,target_transform=None) train_loader = torch.utils.data.DataLoader(dataset=cifar10_train_dataset,batch_size=32,shuffle=True,num_workers=2) classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck') n_total_steps = len(train_loader) class MyCNN(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3) self.fc = nn.Linear(16 * 222 * 222, 10) def forward(self, input): x = self.conv1(input) x = x.view(x.shape[0], -1) x = self.fc(x) return x device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') model = MyCNN().to(device) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=1e-4, weight_decay=1e-2, momentum=0.9) print('Start training...') for epoch in range(4): for i, (images, labels) in enumerate(train_loader): images = images.to(device) labels = labels.to(device) labels_pred = model(images) loss = criterion(labels_pred, labels) optimizer.zero_grad() loss.backward() optimizer.step if (i+1) % 100 == 0: print(f'Epoch [{epoch+1}/{4}], Step [{i+1:5d}/{n_total_steps}], Loss={loss.item():.4f}') print('Training complete!') with torch.no_grad(): im = Image.open('./images/dog.jpg') input_tensor = transform(im).unsqueeze(0).to(device) label_pred = model(input_tensor).argmax() print(f'Your label predicted: {classes[label_pred]}')
    展开

    作者回复: 👍🏻

    
    