计算模型Params和Flops
·
from CSNET import CSNet
import profile
width = 360
height = 240
model = CSNet.CSNET(num_channels=1, base_filter=102)
flops, params = profile(model, input_size=(1, 1, height, width))
print('IMDN_light: {} x {}, flops: {:.10f} GFLOPs, params: {}'.format(height,width,flops/(1e9),params))
以下代码来自IMDN-master
import logging
import torch
import torch.nn as nn
from torch.nn.modules.conv import _ConvNd
from .count_hooks import *
register_hooks = {
nn.Conv1d: count_convNd,
nn.Conv2d: count_convNd,
nn.Conv3d: count_convNd,
nn.ConvTranspose2d: count_convtranspose2d,
nn.BatchNorm1d: count_bn,
nn.BatchNorm2d: count_bn,
nn.BatchNorm3d: count_bn,
nn.ReLU: count_relu,
nn.ReLU6: count_relu,
nn.LeakyReLU: count_relu,
nn.PReLU: count_relu,
nn.MaxPool1d: count_maxpool,
nn.MaxPool2d: count_maxpool,
nn.MaxPool3d: count_maxpool,
nn.AdaptiveMaxPool1d: count_adap_maxpool,
nn.AdaptiveMaxPool2d: count_adap_maxpool,
nn.AdaptiveMaxPool3d: count_adap_maxpool,
nn.AvgPool1d: count_avgpool,
nn.AvgPool2d: count_avgpool,
nn.AvgPool3d: count_avgpool,
nn.AdaptiveAvgPool1d: count_adap_avgpool,
nn.AdaptiveAvgPool2d: count_adap_avgpool,
nn.AdaptiveAvgPool3d: count_adap_avgpool,
nn.Linear: count_linear,
nn.Dropout: None,
nn.PixelShuffle: count_pixelshuffle,
nn.Sigmoid: count_sigmoid,
}
def profile(model, input_size, custom_ops={}, device="cpu"):
handler_collection = []
def add_hooks(m):
if len(list(m.children())) > 0:
return
m.register_buffer('total_ops', torch.zeros(1))
m.register_buffer('total_params', torch.zeros(1))
for p in m.parameters():
m.total_params += torch.Tensor([p.numel()])
m_type = type(m)
fn = None
if m_type in custom_ops:
fn = custom_ops[m_type]
elif m_type in register_hooks:
fn = register_hooks[m_type]
else:
print("Not implemented for ", m)
if fn is not None:
#print("Register FLOP counter for module %s" % str(m))
handler = m.register_forward_hook(fn)
handler_collection.append(handler)
original_device = model.parameters().__next__().device
training = model.training
model.eval().to(device)
model.apply(add_hooks)
x = torch.zeros(input_size).to(device)
with torch.no_grad():
model(x)
total_ops = 0
total_params = 0
for m in model.modules():
if len(list(m.children())) > 0: # skip for non-leaf module
continue
total_ops += m.total_ops
total_params += m.total_params
total_ops = total_ops.item()
total_params = total_params.item()
model.train(training).to(original_device)
for handler in handler_collection:
handler.remove()
return total_ops, total_params
import argparse
import torch
import torch.nn as nn
multiply_adds = 1
def count_convNd(m, x, y):
x = x[0]
cin = m.in_channels
batch_size = x.size(0)
kernel_ops = m.weight.size()[2:].numel()
bias_ops = 1 if m.bias is not None else 0
ops_per_element = kernel_ops + bias_ops
output_elements = y.nelement()
# cout x oW x oH
total_ops = batch_size * cin * output_elements * ops_per_element // m.groups
# total_ops = batch_size * output_elements * (cin * kernel_ops // m.groups + bias_ops)
m.total_ops = torch.Tensor([int(total_ops)])
def count_conv2d(m, x, y):
x = x[0]
cin = m.in_channels
cout = m.out_channels
kh, kw = m.kernel_size
batch_size = x.size()[0]
out_h = y.size(2)
out_w = y.size(3)
# ops per output element
# kernel_mul = kh * kw * cin
# kernel_add = kh * kw * cin - 1
kernel_ops = multiply_adds * kh * kw
bias_ops = 1 if m.bias is not None else 0
ops_per_element = kernel_ops + bias_ops
# total ops
# num_out_elements = y.numel()
output_elements = batch_size * out_w * out_h * cout
total_ops = output_elements * ops_per_element * cin // m.groups
m.total_ops = torch.Tensor([int(total_ops)])
def count_convtranspose2d(m, x, y):
x = x[0]
cin = m.in_channels
cout = m.out_channels
kh, kw = m.kernel_size
batch_size = x.size()[0]
out_h = y.size(2)
out_w = y.size(3)
# ops per output element
# kernel_mul = kh * kw * cin
# kernel_add = kh * kw * cin - 1
kernel_ops = multiply_adds * kh * kw * cin // m.groups
bias_ops = 1 if m.bias is not None else 0
ops_per_element = kernel_ops + bias_ops
# total ops
# num_out_elements = y.numel()
# output_elements = batch_size * out_w * out_h * cout
ops_per_element = m.weight.nelement()
output_elements = y.nelement()
total_ops = output_elements * ops_per_element
m.total_ops = torch.Tensor([int(total_ops)])
def count_bn(m, x, y):
x = x[0]
nelements = x.numel()
# subtract, divide, gamma, beta
total_ops = 4 * nelements
m.total_ops = torch.Tensor([int(total_ops)])
def count_relu(m, x, y):
x = x[0]
nelements = x.numel()
total_ops = nelements
m.total_ops = torch.Tensor([int(total_ops)])
def count_sigmoid(m, x, y):
x = x[0]
nelements = x.numel()
total_exp = nelements
total_add = nelements
total_div = nelements
total_ops = total_exp + total_add + total_div
m.total_ops = torch.Tensor([int(total_ops)])
def count_pixelshuffle(m, x, y):
x = x[0]
nelements = x.numel()
total_ops = nelements
m.total_ops = torch.Tensor([int(total_ops)])
def count_softmax(m, x, y):
x = x[0]
batch_size, nfeatures = x.size()
total_exp = nfeatures
total_add = nfeatures - 1
total_div = nfeatures
total_ops = batch_size * (total_exp + total_add + total_div)
m.total_ops = torch.Tensor([int(total_ops)])
def count_maxpool(m, x, y):
kernel_ops = torch.prod(torch.Tensor([m.kernel_size]))
num_elements = y.numel()
total_ops = kernel_ops * num_elements
m.total_ops = torch.Tensor([int(total_ops)])
def count_adap_maxpool(m, x, y):
kernel = torch.Tensor([*(x[0].shape[2:])]) // torch.Tensor(list((m.output_size,))).squeeze()
kernel_ops = torch.prod(kernel)
num_elements = y.numel()
total_ops = kernel_ops * num_elements
m.total_ops = torch.Tensor([int(total_ops)])
def count_avgpool(m, x, y):
total_add = torch.prod(torch.Tensor([m.kernel_size]))
total_div = 1
kernel_ops = total_add + total_div
num_elements = y.numel()
total_ops = kernel_ops * num_elements
m.total_ops = torch.Tensor([int(total_ops)])
def count_adap_avgpool(m, x, y):
kernel = torch.Tensor([*(x[0].shape[2:])]) // torch.Tensor(list((m.output_size,))).squeeze()
total_add = torch.prod(kernel)
total_div = 1
kernel_ops = total_add + total_div
num_elements = y.numel()
total_ops = kernel_ops * num_elements
m.total_ops = torch.Tensor([int(total_ops)])
def count_linear(m, x, y):
# per output element
total_mul = m.in_features
total_add = m.in_features - 1
num_elements = y.numel()
total_ops = (total_mul + total_add) * num_elements
m.total_ops = torch.Tensor([int(total_ops)])
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)