Torchvision.models包里面包含了常见的各种基础模型架构,主要包括以下几种:(我们以ResNet50模型作为此次演示的例子)

AlexNet VGGResNet SqueezeNet DenseNet Inception v3 GoogLeNet ShuffleNet v2 MobileNet v2 ResNeXt Wide ResNet MNASNet

首先加载ResNet50模型,如果如果需要加载模型本身的参数,需要使用pretrained=True,代码如下

import torchvision

from torchvision import models

resnet50 = models.resnet50(pretrained=True) #pretrained=True 加载模型以及训练过的参数

print(resnet50) # 打印输出观察一下resnet50到底是怎么样的结构

打印输出后ResNet50部分结构如下图,其中红框的全连接层是需要关注的点。全连接层中,“resnet50” 的out_features=1000,这也就是说可以进行class=1000的分类。

 由于我们正常所使用的分类场景大概率与resnet50的分类数不一样,所以在调用时,要使用out_features=分类数进行调整。假设我们采用CIFAR10数据集(10 class)进行测试,那么我们就需要修改全连接层,out_features=10。具体代码如下:

resnet50 = models.resnet50(pretrained=True)

num_ftrs = resnet50.fc.in_features

for param in resnet50.parameters():

param.requires_grad = False #False:冻结模型的参数,也就是采用该模型已经训练好的原始参数。只需要训练我们自己定义的Linear层

#保持in_features不变,修改out_features=10

resnet50.fc = nn.Sequential(nn.Linear(num_ftrs,10),

nn.LogSoftmax(dim=1))

一个简单完整的 CIFAR10+ResNet50 训练代码如下:

import torch

import torchvision

from torch import nn

from torch.utils.data import DataLoader

from torchvision import models

#下载CIFAR10数据集

train_data = torchvision.datasets.CIFAR10(root="../data",train=True,transform=torchvision.transforms.ToTensor(),

download=False)

test_data = torchvision.datasets.CIFAR10(root="../data",train=False,transform=torchvision.transforms.ToTensor(),

download=False)

train_data_size = len(train_data)

test_data_size = len(test_data)

print("The size of Train_data is {}".format(train_data_size))

print("The size of Test_data is {}".format(test_data_size))

#dataloder进行数据集的加载

train_dataloader = DataLoader(train_data,batch_size=128)

test_dataloader = DataLoader(test_data,batch_size=128)

resnet50 = models.resnet50(pretrained=True)

num_ftrs = resnet50.fc.in_features

for param in resnet50.parameters():

param.requires_grad = False #False:冻结模型的参数,

# 也就是采用该模型已经训练好的原始参数。

#只需要训练我们自己定义的Linear层

resnet50.fc = nn.Sequential(nn.Linear(num_ftrs,10),

nn.LogSoftmax(dim=1))

# 网络模型cuda

if torch.cuda.is_available():

resnet50 = resnet50.cuda()

#loss

loss_fn = nn.CrossEntropyLoss()

if torch.cuda.is_available():

loss_fn = loss_fn.cuda()

#optimizer

learning_rate = 0.01

optimizer = torch.optim.SGD(resnet50.parameters(),lr=learning_rate,)

#设置网络训练的一些参数

#记录训练的次数

total_train_step = 0

#记录测试的次数

total_test_step = 0

#训练的轮数

epoch = 10

for i in range(epoch):

print("-------第{}轮训练开始-------".format(i+1))

resnet50.train()

#训练步骤开始

for data in train_dataloader:

imgs, targets = data

if torch.cuda.is_available():

# 图像cuda;标签cuda

# 训练集和测试集都要有

imgs = imgs.cuda()

targets = targets.cuda()

outputs = resnet50(imgs)

loss = loss_fn(outputs, targets)

# 优化器优化模型

optimizer.zero_grad()

loss.backward()

optimizer.step()

total_train_step = total_train_step + 1

if total_train_step % 100 == 0:

print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))

#writer.add_scalar("train_loss", loss.item(), total_train_step)

#测试集

total_test_loss = 0

with torch.no_grad():

for data in test_dataloader:

imgs, targets = data

if torch.cuda.is_available():

# 图像cuda;标签cuda

# 训练集和测试集都要有

imgs = imgs.cuda()

targets = targets.cuda()

outputs = resnet50(imgs)

loss = loss_fn(outputs,targets)

total_test_loss += loss.item()

total_test_step += 1

if total_test_step % 100 ==0:

print("测试次数:{},Loss:{}".format(total_test_step,total_test_loss))

完美!!!!!

剩下的大家可以举一反三,继续探索。。。。

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: