《Pytorch模型推理及多任务通用范式》第二节作业

1 课程学习

本节课主要对于大白AI课程:

《Pytorch模型推理及多任务通用范式》课程中的第二节课进行学习。

2 作业题目

题目描述

必做题:
(1)    从torchvision中加载resnet18模型结构,并载入预训练好的模型权重 'resnet18-5c106cde.pth' (在物料包的weights文件夹中)。
(2)    将(1)中加载好权重的resnet18模型,保存成onnx文件。
(3)    以torch.rand([1,3,224,224]).type(torch.float32)作为输入,求resnet18的模型计算量和参数量。
(4)    以torch.rand([1,3,448,448]).type(torch.float32)作为输入,求resnet18的模型计算量和参数量。
思考题:
(1)    比较必做题中的(3)和(4)的结果,有什么规律?
(2)    尝试用netron可视化resnet18的onnx文件
(3)    model作为torch.nn.Module的子类,除了用 model.state_dict()查看网络层外,还可以用model.named_parameters()和model.parameters()。它们三儿有啥不同?
(4)    加载模型权重时用的model.load_state_dict(字典, strict=True),里面的strict参数什么情况下要赋值False?

实现及结果

from thop import profile
from torchvision.models import resnet18

# 检测使用GPU或者CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 加载模型结构
model = resnet18(num_classes=1000).to(device)

# 加载权重文件
pretrained_state_dict = torch.load('./weights/resnet18-5c106cde.pth')
model.load_state_dict(pretrained_state_dict, strict=True)

inputs = torch.ones([1, 3, 224, 224]).type(torch.float32).to(torch.device('cuda:0'))
torch.onnx.export(model, inputs, './weights/resnet18.onnx',  verbose=False)

inputs1 = torch.rand([1, 3, 224, 224]).type(torch.float32).to(torch.device('cuda:0'))
inputs2 = torch.rand([1, 3, 448, 448]).type(torch.float32).to(torch.device('cuda:0'))

flops1, params1 = profile(model=model, inputs=(inputs1,))
flops2, params2 = profile(model=model, inputs=(inputs2,))
print('Model([1, 3, 224, 224]): {:.2f} GFLOPs and {:.2f}M parameters'.format(flops1/1e9, params1/1e6))
print('Model([1, 3, 448, 448]): {:.2f} GFLOPs and {:.2f}M parameters'.format(flops2/1e9, params2/1e6))

生成的resnet18.onnx文件为45M
在这里插入图片描述
以torch.rand([1,3,224,224]).type(torch.float32)作为输入,ResNet18的模型计算量为1.82 GFLOPs,参数量为11.69M
以torch.rand([1,3,448,448]).type(torch.float32)作为输入,ResNet18的模型计算量为7.27 GFLOPs,参数量为11.69M
在这里插入图片描述

思考

1 模型计算量和参数量的分析

模型的参数量与网络结构本身相关,但与输入图片无关,因此对于前面分别以torch.rand([1,3,224,224]).type(torch.float32)和torch.rand([1,3,448,448]).type(torch.float32)作为输入而言,resnet18的参数量都是一致的,即都为11.69M;但模型计算量与输入图片相关,且可以看到,torch.rand([1,3,448,448]).type(torch.float32)比torch.rand([1,3,224,224]).type(torch.float32)作为输入,要多4倍计算量,因此结果分别为7.27 GFLOPs和1.82 GFLOPs

2 netron可视化resnet18的onnx文件

在这里插入图片描述

3 model.state_dict()、model.named_parameters()、model.parameters()三者的比较

model.named_parameters()返回list中,每个元组包含两个内容,分别是layer-name和layer-param
model.parameters()返回list中,只包含layer-param

model.named_parameters()的结果测试
from torchvision.models import resnet18

# 检测使用GPU或者CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 加载模型结构
model = resnet18(num_classes=1000).to(device)

for layer_name, layer_param in model.named_parameters():
    print('layer_name: ', layer_name)
    print('layer_param: ', layer_param)

在这里插入图片描述

model.parameters()的结果测试
from torchvision.models import resnet18

# 检测使用GPU或者CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 加载模型结构
model = resnet18(num_classes=1000).to(device)

for layer_param in model.parameters():
    print('layer_param: ', layer_param)

在这里插入图片描述

model.state_dict()的结果测试
from torchvision.models import resnet18

# 检测使用GPU或者CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 加载模型结构
model = resnet18(num_classes=1000).to(device)

for layer_name, layer_param in model.state_dict().items():
    print('layer_name: ', layer_name)
    print('layer_param: ', layer_param)

在这里插入图片描述

model.named_parameters()与model.state_dict()的不同

(1)返回值类型不同
model.named_parameters():将layer_name和layer_param打包成一个元组然后再存到list当中,因此遍历方式为for layer_name, layer_param in model.named_parameters()
model.state_dict():将layer_name和layer_param以键值对信息的形式存储,因此遍历方式为for layer_name, layer_param in model.state_dict().items()
(2)存储的模型参数的种类不同
model.named_parameters():只保存可学习、可被更新的参数
model.state_dict():存储model中包含的所有layer中的所有参数
(3)返回的值的require_grad属性不同
model.named_parameters():require_grad属性都是True
model.state_dict():require_grad属性都是False

4 model.load_state_dict(字典, strict=True)中,strict的作用?

这个字典一般就是权重文件,strict即严格的意思。
若strict=True,说明权重文件的参数值要跟该model严格匹配
若strict=False,则允许只将model内需要加载的参数,用权重文件进行加载;无需让权重文件的参数和model的参数严格对应

学习心得

本节课主要通过加载模型、权重文件等方式,来了解模型参数量、计算量等内容,进而为后续的模型训练和测试打下基础。

参考

https://blog.csdn.net/weixin_41712499/article/details/110198423

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值