def create_network(self, blocks): models = nn.ModuleList() prev_filters = 3 out_filters = [] prev_stride = 1 out_strides = [] conv_id = 0 for block in blocks: if block['type'] == 'net': prev_filters = int(block['channels']) continue elif block['type'] == 'convolutional': conv_id = conv_id + 1 batch_normalize = int(block['batch_normalize']) filters = int(block['filters']) kernel_size = int(block['size']) stride = int(block['stride']) is_pad = int(block['pad']) pad = (kernel_size - 1) // 2 if is_pad else 0 activation = block['activation'] model = nn.Sequential() if batch_normalize: model.add_module( 'conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias=False)) model.add_module('bn{0}'.format(conv_id), nn.BatchNorm2d(filters)) # model.add_module('bn{0}'.format(conv_id), BN2d(filters)) else: model.add_module( 'conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad)) if activation == 'leaky': model.add_module('leaky{0}'.format(conv_id), nn.LeakyReLU(0.1, inplace=True)) elif activation == 'relu': model.add_module('relu{0}'.format(conv_id), nn.ReLU(inplace=True)) elif activation == 'mish': model.add_module('mish{0}'.format(conv_id), Mish()) else: print("convalution havn't activate {}".format(activation)) prev_filters = filters out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'maxpool': pool_size = int(block['size']) stride = int(block['stride']) if stride == 1 and pool_size % 2: # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=3 stride=1 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=pool_size // 2) elif stride == pool_size: # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=2 stride=2 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=0) else: model = MaxPoolDark(pool_size, stride) out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'avgpool': model = GlobalAvgPool2d() out_filters.append(prev_filters) models.append(model) elif block['type'] == 'softmax': model = nn.Softmax() out_strides.append(prev_stride) out_filters.append(prev_filters) models.append(model) elif block['type'] == 'cost': if block['_type'] == 'sse': model = nn.MSELoss(size_average=True) elif block['_type'] == 'L1': model = nn.L1Loss(size_average=True) elif block['_type'] == 'smooth': model = nn.SmoothL1Loss(size_average=True) out_filters.append(1) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'reorg': stride = int(block['stride']) prev_filters = stride * stride * prev_filters out_filters.append(prev_filters) prev_stride = prev_stride * stride out_strides.append(prev_stride) models.append(Reorg(stride)) elif block['type'] == 'upsample': stride = int(block['stride']) out_filters.append(prev_filters) prev_stride = prev_stride // stride out_strides.append(prev_stride) models.append(Upsample_expand(stride)) # models.append(Upsample_interpolate(stride)) elif block['type'] == 'route': layers = block['layers'].split(',') ind = len(models) layers = [ int(i) if int(i) > 0 else int(i) + ind for i in layers ] if len(layers) == 1: if 'groups' not in block.keys() or int( block['groups']) == 1: prev_filters = out_filters[layers[0]] prev_stride = out_strides[layers[0]] else: prev_filters = out_filters[layers[0]] // int( block['groups']) prev_stride = out_strides[layers[0]] // int( block['groups']) elif len(layers) == 2: assert (layers[0] == ind - 1 or layers[1] == ind - 1) prev_filters = out_filters[layers[0]] + out_filters[ layers[1]] prev_stride = out_strides[layers[0]] elif len(layers) == 4: assert (layers[0] == ind - 1) prev_filters = out_filters[layers[0]] + out_filters[layers[1]] + out_filters[layers[2]] + \ out_filters[layers[3]] prev_stride = out_strides[layers[0]] else: print("route error!!!") out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'shortcut': ind = len(models) prev_filters = out_filters[ind - 1] out_filters.append(prev_filters) prev_stride = out_strides[ind - 1] out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'connected': filters = int(block['output']) if block['activation'] == 'linear': model = nn.Linear(prev_filters, filters) elif block['activation'] == 'leaky': model = nn.Sequential(nn.Linear(prev_filters, filters), nn.LeakyReLU(0.1, inplace=True)) elif block['activation'] == 'relu': model = nn.Sequential(nn.Linear(prev_filters, filters), nn.ReLU(inplace=True)) prev_filters = filters out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'region': loss = RegionLoss() anchors = block['anchors'].split(',') loss.anchors = [float(i) for i in anchors] loss.num_classes = int(block['classes']) loss.num_anchors = int(block['num']) loss.anchor_step = len(loss.anchors) // loss.num_anchors loss.object_scale = float(block['object_scale']) loss.noobject_scale = float(block['noobject_scale']) loss.class_scale = float(block['class_scale']) loss.coord_scale = float(block['coord_scale']) out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(loss) elif block['type'] == 'yolo': yolo_layer = YoloLayer() anchors = block['anchors'].split(',') anchor_mask = block['mask'].split(',') yolo_layer.anchor_mask = [int(i) for i in anchor_mask] yolo_layer.anchors = [float(i) for i in anchors] yolo_layer.num_classes = int(block['classes']) self.num_classes = yolo_layer.num_classes yolo_layer.num_anchors = int(block['num']) yolo_layer.anchor_step = len( yolo_layer.anchors) // yolo_layer.num_anchors yolo_layer.stride = prev_stride yolo_layer.scale_x_y = float(block['scale_x_y']) # yolo_layer.object_scale = float(block['object_scale']) # yolo_layer.noobject_scale = float(block['noobject_scale']) # yolo_layer.class_scale = float(block['class_scale']) # yolo_layer.coord_scale = float(block['coord_scale']) out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(yolo_layer) else: print('unknown type %s' % (block['type'])) return models
def create_network(self, blocks): """根据 blocks 创建网络models :param blocks: blocks模块配置 :return: nn.ModuleList() """ models = nn.ModuleList() prev_filters = 3 # 前一层 channels个数 out_filters = [] # 所有层(无输入层)的通道数 prev_stride = 1 # 前一层 stride 大小,相对于原始图像大小 out_strides = [] # 所有层(无输入层)的stride大小,相对于原始图像大小 conv_id = 0 # 每一层ID for block in blocks: if block['type'] == 'net': # 网络配置 prev_filters = int(block['channels']) continue elif block['type'] == 'convolutional': # 卷积 conv_id = conv_id + 1 batch_normalize = int(block['batch_normalize']) filters = int(block['filters']) kernel_size = int(block['size']) stride = int(block['stride']) is_pad = int(block['pad']) pad = (kernel_size - 1) // 2 if is_pad else 0 activation = block['activation'] model = nn.Sequential() if batch_normalize: model.add_module( 'conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias=False)) model.add_module('bn{0}'.format(conv_id), nn.BatchNorm2d(filters)) else: model.add_module( 'conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad)) if activation == 'leaky': model.add_module('leaky{0}'.format(conv_id), nn.LeakyReLU(0.1, inplace=True)) elif activation == 'relu': model.add_module('relu{0}'.format(conv_id), nn.ReLU(inplace=True)) elif activation == 'mish': model.add_module('mish{0}'.format(conv_id), Mish()) else: print( "Your activation is {}, but YOLO Layer ID {} convalution havn't activate {}" .format(activation, conv_id, activation)) prev_filters = filters out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'maxpool': # maxpool pool_size = int(block['size']) stride = int(block['stride']) if stride == 1 and pool_size % 2: # stride为1,3,5,... # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=3 stride=1 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=pool_size // 2) elif stride == pool_size: # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=2 stride=2 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=0) else: model = MaxPoolDark(pool_size, stride) out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'avgpool': model = GlobalAvgPool2d() out_filters.append(prev_filters) models.append(model) elif block['type'] == 'softmax': model = nn.Softmax() out_strides.append(prev_stride) out_filters.append(prev_filters) models.append(model) elif block['type'] == 'cost': if block['_type'] == 'sse': model = nn.MSELoss(reduction='mean') elif block['_type'] == 'L1': model = nn.L1Loss(reduction='mean') elif block['_type'] == 'smooth': model = nn.SmoothL1Loss(reduction='mean') out_filters.append(1) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'reorg': stride = int(block['stride']) prev_filters = stride * stride * prev_filters out_filters.append(prev_filters) prev_stride = prev_stride * stride out_strides.append(prev_stride) models.append(Reorg(stride)) elif block['type'] == 'upsample': stride = int(block['stride']) out_filters.append(prev_filters) prev_stride = prev_stride // stride out_strides.append(prev_stride) models.append(Upsample_expand(stride)) # 上采样 方式1 # models.append(Upsample_interpolate(stride)) # 上采样 方式2 elif block['type'] == 'route': layers = block['layers'].split(',') # -1, -7 ind = len(models) layers = [ int(i) if int(i) > 0 else int(i) + ind for i in layers ] # 通过layers定位到整个网络的下标 if len(layers) == 1: # 一条路径 if 'groups' not in block.keys() or int( block['groups']) == 1: prev_filters = out_filters[layers[0]] prev_stride = out_strides[layers[0]] else: prev_filters = out_filters[layers[0]] // int( block['groups']) prev_stride = out_strides[layers[0]] // int( block['groups']) elif len(layers) == 2: # 两条路径 assert (layers[0] == ind - 1 or layers[1] == ind - 1) prev_filters = out_filters[layers[0]] + out_filters[ layers[1]] prev_stride = out_strides[layers[0]] elif len(layers) == 4: # 四条路径 assert (layers[0] == ind - 1) prev_filters = out_filters[layers[0]] + out_filters[layers[1]] + out_filters[layers[2]] + \ out_filters[layers[3]] prev_stride = out_strides[layers[0]] else: print("route error!!!") out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'shortcut': ind = len(models) prev_filters = out_filters[ind - 1] out_filters.append(prev_filters) prev_stride = out_strides[ind - 1] out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'connected': filters = int(block['output']) if block['activation'] == 'linear': model = nn.Linear(prev_filters, filters) elif block['activation'] == 'leaky': model = nn.Sequential(nn.Linear(prev_filters, filters), nn.LeakyReLU(0.1, inplace=True)) elif block['activation'] == 'relu': model = nn.Sequential(nn.Linear(prev_filters, filters), nn.ReLU(inplace=True)) prev_filters = filters out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'region': loss = RegionLoss() anchors = block['anchors'].split(',') loss.anchors = [float(i) for i in anchors] loss.num_classes = int(block['classes']) loss.num_anchors = int(block['num']) loss.anchor_step = len(loss.anchors) // loss.num_anchors loss.object_scale = float(block['object_scale']) loss.noobject_scale = float(block['noobject_scale']) loss.class_scale = float(block['class_scale']) loss.coord_scale = float(block['coord_scale']) out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(loss) elif block['type'] == 'yolo': yolo_layer = YoloLayer() anchors = block['anchors'].split(',') # all anchors anchor_mask = block['mask'].split(',') # anchor mask yolo_layer.anchor_mask = [ int(i) for i in anchor_mask ] # 当前yolo layer的 anchor mask eg.[0,1,2] yolo_layer.anchors = [float(i) for i in anchors ] # 当前yolo layer的 anchors eg.[xx,xx,xx] yolo_layer.num_classes = int( block['classes']) # 当前yolo layer的 classes类别数 eg.80 self.num_classes = yolo_layer.num_classes # DarkNet 类别数 eg.80 yolo_layer.num_anchors = int( block['num']) # 当前yolo layer的 所有的anchors数量 eg.9 yolo_layer.anchor_step = len( yolo_layer.anchors ) // yolo_layer.num_anchors # 索引 anchor的步长 eg.18/9=2 yolo_layer.stride = prev_stride # 此yolo layer特征图相对于原图的步长 yolo_layer.scale_x_y = float(block['scale_x_y']) # xy比例 out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(yolo_layer) else: print('unknown type %s' % (block['type'])) return models
def create_network(self, blocks): models = nn.ModuleList() # 创建一个空的ModuleList prev_filters = 3 out_filters = [] prev_stride = 1 out_strides = [] conv_id = 0 for block in blocks: if block['type'] == 'net': # 只有一个net prev_filters = int(block['channels']) # 3 continue elif block['type'] == 'convolutional': # 卷积层,yolov4.cfg共有110个卷积层 conv_id = conv_id + 1 # 按顺序将卷积层编号,后面进行模块命名 # 得到该卷积层的各项参数 batch_normalize = int(block['batch_normalize']) filters = int(block['filters']) kernel_size = int(block['size']) stride = int(block['stride']) is_pad = int(block['pad']) # darknet只有两种kernel_size,若kernel_size=1,则pad=0 若kernel_size=3,则pad=1 # 补充:output_size =1+ (input_size+2*padding-kernel_size)/stride pad = (kernel_size - 1) // 2 if is_pad else 0 activation = block['activation'] model = nn.Sequential() # 创建一个空的Sequential # 公式:卷积层=ConvBnAct,有个别卷积层没有BN,有的层没有激活(linear) if batch_normalize: # 有BN,不需要偏置 model.add_module( 'conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias=False)) model.add_module('bn{0}'.format(conv_id), nn.BatchNorm2d(filters)) # model.add_module('bn{0}'.format(conv_id), BN2d(filters)) else: # 没有BN,需要偏置(nn.Conv2d中的bias默认为True) model.add_module( 'conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad)) if activation == 'leaky': # inplace表示原地操作,在原变量不存在分支的情况下是没问题的,可以节省内存 model.add_module('leaky{0}'.format(conv_id), nn.LeakyReLU(0.1, inplace=True)) elif activation == 'relu': # yolov4里没有用relu model.add_module('relu{0}'.format(conv_id), nn.ReLU(inplace=True)) elif activation == 'mish': model.add_module('mish{0}'.format(conv_id), Mish()) else: # yolov4里除了leaky和mish,就是linear,表示没有激活层 # 这个打印信息没用,改成空语句pass # print("convolution haven't activate {}".format(activation)) pass prev_filters = filters out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'maxpool': # 最大池化层,yolov4.cfg只有3个 # 池化层只有两个参数,核大小和步长 pool_size = int(block['size']) # yolov4三个最大池化层的步长分别为5,9,13 stride = int(block['stride']) if stride == 1 and pool_size % 2: # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=3 stride=1 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=pool_size // 2) elif stride == pool_size: # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=2 stride=2 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=0) else: # yolov4用的都是MaxPoolDark model = MaxPoolDark(pool_size, stride) out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'avgpool': # yolov4.cfg里没有avgpool model = GlobalAvgPool2d() out_filters.append(prev_filters) models.append(model) elif block['type'] == 'softmax': # yolov4.cfg里没有softmax model = nn.Softmax() out_strides.append(prev_stride) out_filters.append(prev_filters) models.append(model) elif block['type'] == 'cost': # yolov4.cfg里没有cost if block['_type'] == 'sse': model = nn.MSELoss(reduction='mean') elif block['_type'] == 'L1': model = nn.L1Loss(reduction='mean') elif block['_type'] == 'smooth': model = nn.SmoothL1Loss(reduction='mean') out_filters.append(1) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'reorg': # yolov4.cfg里没有reorg stride = int(block['stride']) prev_filters = stride * stride * prev_filters out_filters.append(prev_filters) prev_stride = prev_stride * stride out_strides.append(prev_stride) models.append(Reorg(stride)) elif block['type'] == 'upsample': # yolov4.cfg里有两个upsample stride = int(block['stride']) out_filters.append(prev_filters) prev_stride = prev_stride // stride out_strides.append(prev_stride) models.append(Upsample_expand(stride)) # Upsample_expand上采样 # models.append(Upsample_interpolate(stride)) elif block['type'] == 'route': # yolo中的一个特殊层,作用是路由和拼接 layers = block['layers'].split(',') ind = len(models) # 如果layers索引大于0,则代表层数,如果小于0,代表从当前层往前减 layers = [ int(i) if int(i) > 0 else int(i) + ind for i in layers ] if len(layers) == 1: # 如果layers只有一个 if 'groups' not in block.keys() or int( block['groups']) == 1: # 对于yolov4.cfg,为True # 获取指定layer的核数量和步长 prev_filters = out_filters[layers[0]] prev_stride = out_strides[layers[0]] else: prev_filters = out_filters[layers[0]] // int( block['groups']) prev_stride = out_strides[layers[0]] // int( block['groups']) elif len(layers) == 2: # 如果layer有两个 # 如果layer有两个,肯定有一个是-1 assert (layers[0] == ind - 1 or layers[1] == ind - 1) # 核数量为两个层的核数量之和 prev_filters = out_filters[layers[0]] + out_filters[ layers[1]] prev_stride = out_strides[layers[0]] elif len(layers) == 4: # 如果layer有4个 # 如果layer有四个,肯定有一个是-1 assert (layers[0] == ind - 1) # 核数量为四个层的核数量之和 prev_filters = out_filters[layers[0]] + out_filters[layers[1]] + out_filters[layers[2]] + \ out_filters[layers[3]] prev_stride = out_strides[layers[0]] else: print("route error!!!") # 设置虚空的核数量和步长,以及用于占位的空层 out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'shortcut': # yolov4里有23个shortcut ind = len(models) # 设置虚空的核数量和步长,以及用于占位的空层 prev_filters = out_filters[ind - 1] out_filters.append(prev_filters) prev_stride = out_strides[ind - 1] out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'connected': # yolov4.cfg里没有connected filters = int(block['output']) if block['activation'] == 'linear': model = nn.Linear(prev_filters, filters) elif block['activation'] == 'leaky': model = nn.Sequential(nn.Linear(prev_filters, filters), nn.LeakyReLU(0.1, inplace=True)) elif block['activation'] == 'relu': model = nn.Sequential(nn.Linear(prev_filters, filters), nn.ReLU(inplace=True)) prev_filters = filters out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'region': # yolov4.cfg里没有region loss = RegionLoss() anchors = block['anchors'].split(',') loss.anchors = [float(i) for i in anchors] loss.num_classes = int(block['classes']) loss.num_anchors = int(block['num']) loss.anchor_step = len(loss.anchors) // loss.num_anchors loss.object_scale = float(block['object_scale']) loss.noobject_scale = float(block['noobject_scale']) loss.class_scale = float(block['class_scale']) loss.coord_scale = float(block['coord_scale']) out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(loss) elif block['type'] == 'yolo': # yolov4.cfg里有3个yolo yolo_layer = YoloLayer() anchors = block['anchors'].split(',') anchor_mask = block['mask'].split(',') yolo_layer.anchor_mask = [int(i) for i in anchor_mask] yolo_layer.anchors = [float(i) for i in anchors] yolo_layer.num_classes = int(block['classes']) self.num_classes = yolo_layer.num_classes yolo_layer.num_anchors = int(block['num']) yolo_layer.anchor_step = len( yolo_layer.anchors) // yolo_layer.num_anchors yolo_layer.stride = prev_stride yolo_layer.scale_x_y = float(block['scale_x_y']) # yolo_layer.object_scale = float(block['object_scale']) # yolo_layer.noobject_scale = float(block['noobject_scale']) # yolo_layer.class_scale = float(block['class_scale']) # yolo_layer.coord_scale = float(block['coord_scale']) out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(yolo_layer) else: print('unknown type %s' % (block['type'])) return models
def create_network(self, blocks): """ nn.ModuleList仅仅类似于pytho中的list类型,只是将一系列层装入列表,并没有实现forward()方法,因此也不会有网络模型产生的副作用, 但它有和纯python中的list不同,用nn.ModuleList或者ParameterList包裹模型各个层之后,我们不光可以像python里的list一样对模型的各个层进行索引, 同时这些层的参数将会被自动注册,这些层的参数只有被正确注册之后,优化器才能发现和训练这些参数 这个操作只会生成一个空的list """ models = nn.ModuleList() prev_filters = 3 out_filters = [] prev_stride = 1 out_strides = [] conv_id = 0 for block in blocks: # 遍历 blocks 的时候,模型不断累加到一起 if block['type'] == 'net': #网络参数 prev_filters = int(block['channels']) #第一次的卷积核个数就是看看有多少个通道 continue # 一共就一个net参数表 elif block['type'] == 'convolutional': #卷积层 conv_id = conv_id + 1 # 数据经过多层神经网络后,数据分布发生变化,导致各层参数需要不到调整适应分布变化,这会让收敛速度变慢, # 超参数设定也变得比较复杂,这在论文里作者称作Internal Covariate Shift # batch_normalize 用于防止梯度消失,就是将后面的数据分布进行规整, batch_normalize = int(block['batch_normalize']) # always 1, 除了最后的输出层,每一层都是用了 batch_normalize filters = int(block['filters']) # 卷积核,其实就是滤波器。在每次迭代中会进行更新参数 kernel_size = int(block['size']) stride = int(block['stride']) # 步长 is_pad = int(block['pad']) # padding 过程 这里的padding 始终=1,仅用于表示:需要 padding pad = (kernel_size - 1) // 2 if is_pad else 0 # padding 大小 activation = block['activation'] # 激活层,激活函数是用来加入非线性因素的,因为线性模型的表达能力不够。 model = nn.Sequential() # 模型为空,通过add_module添加模型结构 if batch_normalize: # add_module(self, name, module) # nn.Conv2d(self, in_channels, out_channels, kernel_size, stride=1, # padding=0, dilation=1, groups=1, # bias=True, padding_mode='zeros') model.add_module('conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias=False)) # print('create_network: conv{0}'.format(conv_id)) # 块标准化的目的就是让传输的数据合理的分布,加速训练的过程 model.add_module('bn{0}'.format(conv_id), nn.BatchNorm2d(filters)) # model.add_module('bn{0}'.format(conv_id), BN2d(filters)) else: model.add_module('conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad)) if activation == 'leaky': model.add_module('leaky{0}'.format(conv_id), nn.LeakyReLU(0.1, inplace=True)) elif activation == 'relu': model.add_module('relu{0}'.format(conv_id), nn.ReLU(inplace=True)) elif activation == 'mish': model.add_module('mish{0}'.format(conv_id), Mish()) else: print(conv_id,"convalution havn't activate {}".format(activation)) prev_filters = filters out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'maxpool': pool_size = int(block['size']) stride = int(block['stride']) if stride == 1 and pool_size % 2: # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=3 stride=1 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=pool_size // 2) elif stride == pool_size: # You can use Maxpooldark instead, here is convenient to convert onnx. # Example: [maxpool] size=2 stride=2 model = nn.MaxPool2d(kernel_size=pool_size, stride=stride, padding=0) else: model = MaxPoolDark(pool_size, stride) out_filters.append(prev_filters) prev_stride = stride * prev_stride out_strides.append(prev_stride) models.append(model) elif block['type'] == 'avgpool': model = GlobalAvgPool2d() out_filters.append(prev_filters) models.append(model) elif block['type'] == 'softmax': model = nn.Softmax() out_strides.append(prev_stride) out_filters.append(prev_filters) models.append(model) elif block['type'] == 'cost': if block['_type'] == 'sse': model = nn.MSELoss(reduction='mean') elif block['_type'] == 'L1': model = nn.L1Loss(reduction='mean') elif block['_type'] == 'smooth': model = nn.SmoothL1Loss(reduction='mean') out_filters.append(1) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'reorg': stride = int(block['stride']) prev_filters = stride * stride * prev_filters out_filters.append(prev_filters) prev_stride = prev_stride * stride out_strides.append(prev_stride) models.append(Reorg(stride)) elif block['type'] == 'upsample': stride = int(block['stride']) out_filters.append(prev_filters) prev_stride = prev_stride // stride out_strides.append(prev_stride) models.append(Upsample_expand(stride)) # models.append(Upsample_interpolate(stride)) elif block['type'] == 'route': layers = block['layers'].split(',') ind = len(models) layers = [int(i) if int(i) > 0 else int(i) + ind for i in layers] if len(layers) == 1: if 'groups' not in block.keys() or int(block['groups']) == 1: prev_filters = out_filters[layers[0]] prev_stride = out_strides[layers[0]] else: prev_filters = out_filters[layers[0]] // int(block['groups']) prev_stride = out_strides[layers[0]] // int(block['groups']) elif len(layers) == 2: assert (layers[0] == ind - 1 or layers[1] == ind - 1) prev_filters = out_filters[layers[0]] + out_filters[layers[1]] prev_stride = out_strides[layers[0]] elif len(layers) == 4: assert (layers[0] == ind - 1) prev_filters = out_filters[layers[0]] + out_filters[layers[1]] + out_filters[layers[2]] + \ out_filters[layers[3]] prev_stride = out_strides[layers[0]] else: print("route error!!!") out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'shortcut': ind = len(models) prev_filters = out_filters[ind - 1] out_filters.append(prev_filters) prev_stride = out_strides[ind - 1] out_strides.append(prev_stride) models.append(EmptyModule()) elif block['type'] == 'connected': filters = int(block['output']) if block['activation'] == 'linear': model = nn.Linear(prev_filters, filters) elif block['activation'] == 'leaky': model = nn.Sequential( nn.Linear(prev_filters, filters), nn.LeakyReLU(0.1, inplace=True)) elif block['activation'] == 'relu': model = nn.Sequential( nn.Linear(prev_filters, filters), nn.ReLU(inplace=True)) prev_filters = filters out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(model) elif block['type'] == 'region': loss = RegionLoss() anchors = block['anchors'].split(',') loss.anchors = [float(i) for i in anchors] loss.num_classes = int(block['classes']) loss.num_anchors = int(block['num']) loss.anchor_step = len(loss.anchors) // loss.num_anchors loss.object_scale = float(block['object_scale']) loss.noobject_scale = float(block['noobject_scale']) loss.class_scale = float(block['class_scale']) loss.coord_scale = float(block['coord_scale']) out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(loss) elif block['type'] == 'yolo': yolo_layer = YoloLayer() anchors = block['anchors'].split(',') anchor_mask = block['mask'].split(',') yolo_layer.anchor_mask = [int(i) for i in anchor_mask] yolo_layer.anchors = [float(i) for i in anchors] yolo_layer.num_classes = int(block['classes']) self.num_classes = yolo_layer.num_classes yolo_layer.num_anchors = int(block['num']) yolo_layer.anchor_step = len(yolo_layer.anchors) // yolo_layer.num_anchors yolo_layer.stride = prev_stride yolo_layer.scale_x_y = float(block['scale_x_y']) # yolo_layer.object_scale = float(block['object_scale']) # yolo_layer.noobject_scale = float(block['noobject_scale']) # yolo_layer.class_scale = float(block['class_scale']) # yolo_layer.coord_scale = float(block['coord_scale']) out_filters.append(prev_filters) out_strides.append(prev_stride) models.append(yolo_layer) else: print('unknown type %s' % (block['type'])) return models