一、使用的代码
import torch
from thop import profile
def model_info(model, verbose=False):
#打印模型参数、计算量
#train阶段会输出迭代数,等于param
n_p = sum(x.numel() for x in model.parameters()) # number parameters
n_g = sum(x.numel() for x in model.parameters() if x.requires_grad) # number gradients
if verbose:
print(f"{'layer':>5} {'name':>40} {'gradient':>9} {'parameters':>12} {'shape':>20} {'mu':>10} {'sigma':>10}")
for i, (name, p) in enumerate(model.named_parameters()):
name = name.replace('module_list.', '')
print('%5g %40s %9s %12g %20s %10.3g %10.3g' %
(i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std()))
name = 'yolact'
print(f"{name} summary: {len(list(model.modules()))} layers, {n_p} parameters, {n_g} gradients")
def summary_params_flpos():
net = Yolact()
net.load_weights('weights/yolact_base_54_800000.pth')
net.cuda().eval()
model_info(net)
img = cv2.imread('yolact-master/data/img.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (550, 550))
img = torch.from_numpy(img).permute(2, 0, 1).unsqueeze(0).float().cuda()
flops, params = thop.profile(net, inputs=(img, ))
print('flops: ', flops, 'params: ', params)
print('flops: %.2f M, params: %.2f M' % (flops / 1000000.0, params / 1000000.0))
summary_params_flpos()
二、问题记录
1. RuntimeError: Can’t add a new parameter after ScriptModule construction. Tried to add 'total_ops
问题描述:运行时错误:不能在ScriptModule构造后添加新参数。试图添加total_ops。
问题分析:由于我之前阅读过代码,知道ScriptModule在模型构造阶段用到了。
class FPN(ScriptModuleWrapper):
接着点进去看 yolact.py 里ScriptModuleWrapper的定义:
# As of March 10, 2019, Pytorch DataParallel still doesn't support JIT Script Modules
use_jit = torch.cuda.device_count() <= 1
if not use_jit:
print('Multiple GPUs detected! Turning off JIT.')
ScriptModuleWrapper = torch.jit.ScriptModule if use_jit else nn.Module
script_method_wrapper = torch.jit.script_method if use_jit else lambda fn, _rcn=None: fn
模型use_jit参数设置为了True。不知道是什么东东,但是用到了JIT,感觉是trance一些东西,反正和nn.Module 不同。那么设置为False看看,问题解决了。
问题解决:将 torch.jit.ScriptModule 模型修改为 nn.Module。具体设置:在yolact.py中,以下位置添加一行代码 use_jit = False:
use_jit = torch.cuda.device_count() <= 1
use_jit = False #在这里添加这行
if not use_jit:
print('Multiple GPUs detected! Turning off JIT.')
ScriptModuleWrapper = torch.jit.ScriptModule if use_jit else nn.Module
script_method_wrapper = torch.jit.script_method if use_jit else lambda fn, _rcn=None: fn
2. RuntimeError: legacy constructor expects device type: cpu but device type: cuda was passed
问题解决:参考https://blog.csdn.net/dong_liuqi/article/details/120099335
用tensor创建而不是Tensor:
#self.priors = torch.Tensor(prior_data, device=device).view(-1, 4).detach()
self.priors = torch.tensor(prior_data, device=device).view(-1, 4).detach()
三、参数量和浮点数统计结果
yolact backbone=resnet101的FLOPs为 82.74GB,参数量为50.14MB。