|
|
@ -125,8 +125,8 @@ def fuse_conv_and_bn(conv, bn):
|
|
|
|
|
|
|
|
|
|
|
|
def model_info(model, verbose=False, imgsz=640):
|
|
|
|
def model_info(model, verbose=False, imgsz=640):
|
|
|
|
# Model information. img_size may be int or list, i.e. img_size=640 or img_size=[640, 320]
|
|
|
|
# Model information. img_size may be int or list, i.e. img_size=640 or img_size=[640, 320]
|
|
|
|
n_p = sum(x.numel() for x in model.parameters()) # number parameters
|
|
|
|
n_p = get_num_params(model)
|
|
|
|
n_g = sum(x.numel() for x in model.parameters() if x.requires_grad) # number gradients
|
|
|
|
n_g = get_num_gradients(model) # number gradients
|
|
|
|
if verbose:
|
|
|
|
if verbose:
|
|
|
|
print(f"{'layer':>5} {'name':>40} {'gradient':>9} {'parameters':>12} {'shape':>20} {'mu':>10} {'sigma':>10}")
|
|
|
|
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()):
|
|
|
|
for i, (name, p) in enumerate(model.named_parameters()):
|
|
|
@ -134,18 +134,31 @@ def model_info(model, verbose=False, imgsz=640):
|
|
|
|
print('%5g %40s %9s %12g %20s %10.3g %10.3g' %
|
|
|
|
print('%5g %40s %9s %12g %20s %10.3g %10.3g' %
|
|
|
|
(i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std()))
|
|
|
|
(i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std()))
|
|
|
|
|
|
|
|
|
|
|
|
try: # FLOPs
|
|
|
|
flops = get_flops(model, imgsz)
|
|
|
|
|
|
|
|
fs = f', {flops:.1f} GFLOPs' if flops else ''
|
|
|
|
|
|
|
|
name = Path(model.yaml_file).stem.replace('yolov5', 'YOLOv5') if hasattr(model, 'yaml_file') else 'Model'
|
|
|
|
|
|
|
|
LOGGER.info(f"{name} summary: {len(list(model.modules()))} layers, {n_p} parameters, {n_g} gradients{fs}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_num_params(model):
|
|
|
|
|
|
|
|
return sum(x.numel() for x in model.parameters())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_num_gradients(model):
|
|
|
|
|
|
|
|
return sum(x.numel() for x in model.parameters() if x.requires_grad)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_flops(model, imgsz=640):
|
|
|
|
|
|
|
|
try:
|
|
|
|
p = next(model.parameters())
|
|
|
|
p = next(model.parameters())
|
|
|
|
stride = max(int(model.stride.max()), 32) if hasattr(model, 'stride') else 32 # max stride
|
|
|
|
stride = max(int(model.stride.max()), 32) if hasattr(model, 'stride') else 32 # max stride
|
|
|
|
im = torch.empty((1, p.shape[1], stride, stride), device=p.device) # input image in BCHW format
|
|
|
|
im = torch.empty((1, p.shape[1], stride, stride), device=p.device) # input image in BCHW format
|
|
|
|
flops = thop.profile(deepcopy(model), inputs=(im,), verbose=False)[0] / 1E9 * 2 # stride GFLOPs
|
|
|
|
flops = thop.profile(deepcopy(model), inputs=(im,), verbose=False)[0] / 1E9 * 2 # stride GFLOPs
|
|
|
|
imgsz = imgsz if isinstance(imgsz, list) else [imgsz, imgsz] # expand if int/float
|
|
|
|
imgsz = imgsz if isinstance(imgsz, list) else [imgsz, imgsz] # expand if int/float
|
|
|
|
fs = f', {flops * imgsz[0] / stride * imgsz[1] / stride:.1f} GFLOPs' # 640x640 GFLOPs
|
|
|
|
flops = flops * imgsz[0] / stride * imgsz[1] / stride # 640x640 GFLOPs
|
|
|
|
|
|
|
|
return flops
|
|
|
|
except Exception:
|
|
|
|
except Exception:
|
|
|
|
fs = ''
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
name = Path(model.yaml_file).stem.replace('yolov5', 'YOLOv5') if hasattr(model, 'yaml_file') else 'Model'
|
|
|
|
|
|
|
|
LOGGER.info(f"{name} summary: {len(list(model.modules()))} layers, {n_p} parameters, {n_g} gradients{fs}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def initialize_weights(model):
|
|
|
|
def initialize_weights(model):
|
|
|
|