예제 #1
0
 def __init__(self, n_classes, inference):
     super().__init__()
     self.inference = inference
     self.conv1 = Conv_Bn_Activation(512, 512, 3, 1, 'leaky')
     self.conv2 = Conv_Bn_Activation(512, 256, 1, 1, 'leaky')
     self.conv3 = Conv_Bn_Activation(256, 512, 3, 1, 'leaky')
     self.conv4 = Conv_Bn_Activation(512, (4 + 1 + n_classes) * 3,
                                     1,
                                     1,
                                     'linear',
                                     bn=False,
                                     bias=True)
     self.yolo1 = YoloLayer(
         anchor_mask=[3, 4, 5],
         num_classes=n_classes,
         anchors=[10, 14, 23, 27, 37, 58, 81, 82, 135, 169, 344, 319],
         num_anchors=6,
         stride=32)
     self.conv5 = Conv_Bn_Activation(256, 128, 1, 1, 'leaky')
     self.upsample1 = Upsample()
     self.conv6 = Conv_Bn_Activation(384, 256, 3, 1, 'leaky')
     self.conv7 = Conv_Bn_Activation(256, (4 + 1 + n_classes) * 3,
                                     1,
                                     1,
                                     'linear',
                                     bn=False,
                                     bias=True)
     self.yolo2 = YoloLayer(
         anchor_mask=[1, 2, 3],
         num_classes=n_classes,
         anchors=[10, 14, 23, 27, 37, 58, 81, 82, 135, 169, 344, 319],
         num_anchors=6,
         stride=16)
예제 #2
0
    def __init__(self, output_ch, n_classes, inference=False):
        super().__init__()
        self.inference = inference

        self.conv1 = Conv_Bn_Activation(128, 256, 3, 1, 'leaky')
        self.conv2 = Conv_Bn_Activation(256, output_ch, 1, 1, 'linear', bn=False, bias=True)

        self.yolo1 = YoloLayer(
            anchor_mask=[0, 1, 2], num_classes=n_classes,
            anchors=[12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401],
            num_anchors=9, stride=8
        )

        # R -4
        self.conv3 = Conv_Bn_Activation(128, 256, 3, 2, 'leaky')

        # R -1 -16
        self.conv4 = Conv_Bn_Activation(512, 256, 1, 1, 'leaky')
        self.conv5 = Conv_Bn_Activation(256, 512, 3, 1, 'leaky')
        self.conv6 = Conv_Bn_Activation(512, 256, 1, 1, 'leaky')
        self.conv7 = Conv_Bn_Activation(256, 512, 3, 1, 'leaky')
        self.conv8 = Conv_Bn_Activation(512, 256, 1, 1, 'leaky')
        self.conv9 = Conv_Bn_Activation(256, 512, 3, 1, 'leaky')
        self.conv10 = Conv_Bn_Activation(512, output_ch, 1, 1, 'linear', bn=False, bias=True)

        self.yolo2 = YoloLayer(
            anchor_mask=[3, 4, 5], num_classes=n_classes,
            anchors=[12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401],
            num_anchors=9, stride=16
        )

        # R -4
        self.conv11 = Conv_Bn_Activation(256, 512, 3, 2, 'leaky')

        # R -1 -37
        self.conv12 = Conv_Bn_Activation(1024, 512, 1, 1, 'leaky')
        self.conv13 = Conv_Bn_Activation(512, 1024, 3, 1, 'leaky')
        self.conv14 = Conv_Bn_Activation(1024, 512, 1, 1, 'leaky')
        self.conv15 = Conv_Bn_Activation(512, 1024, 3, 1, 'leaky')
        self.conv16 = Conv_Bn_Activation(1024, 512, 1, 1, 'leaky')
        self.conv17 = Conv_Bn_Activation(512, 1024, 3, 1, 'leaky')
        self.conv18 = Conv_Bn_Activation(1024, output_ch, 1, 1, 'linear', bn=False, bias=True)

        self.yolo3 = YoloLayer(
            anchor_mask=[6, 7, 8], num_classes=n_classes,
            anchors=[12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401],
            num_anchors=9, stride=32
        )
예제 #3
0
    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
예제 #4
0
    def create_network(self, blocks):
        model = 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 += 1
                batch_normalize = int(block["batch_normalize"])
                filters = int(block["filters"])
                is_pad = int(block["pad"])
                stride = int(block["stride"])
                kernel_size = [
                    int(x) for x in block["size"].strip().split(",")
                ]
                if len(
                        kernel_size
                ) == 2:  # When this happens kernel size must be odd in both dimensions
                    kernel_size = (kernel_size[0], kernel_size[1]
                                   )  # pytorch convention H x W
                    pad = ((kernel_size[0] - 1) // 2,
                           (kernel_size[1] - 1) // 2) if is_pad else 0
                else:
                    kernel_size = (kernel_size[0], kernel_size[0])
                    pad = ((kernel_size[0] - 1) // 2 if is_pad else 0
                           )  # padding is defined as size/2 in yolo wiki
                activation = block["activation"]

                # add convolutional layer
                conv = nn.Sequential()
                if batch_normalize:
                    conv.add_module(
                        "conv{0}".format(conv_id),
                        nn.Conv2d(prev_filters,
                                  filters,
                                  kernel_size,
                                  stride,
                                  pad,
                                  bias=False),
                    )
                    conv.add_module("bn{0}".format(conv_id),
                                    nn.BatchNorm2d(filters))
                else:
                    conv.add_module(
                        "conv{0}".format(conv_id),
                        nn.Conv2d(prev_filters, filters, kernel_size, stride,
                                  pad),
                    )

                # add activation function
                if activation == "leaky":
                    conv.add_module("leaky{0}".format(conv_id),
                                    nn.LeakyReLU(0.1, inplace=True))
                elif activation == "relu":
                    conv.add_module("relu{0}".format(conv_id),
                                    nn.ReLU(inplace=True))
                elif activation == "mish":
                    conv.add_module("mish{0}".format(conv_id), Mish())
                elif activation == "linear":
                    pass
                else:
                    print(
                        f'conv{conv_id} activation "{activation}" not recognized'
                    )

                # update params
                prev_filters = filters
                out_filters.append(prev_filters)
                prev_stride = stride * prev_stride
                out_strides.append(prev_stride)
                model.append(conv)

            elif block["type"] == "maxpool":
                pool_size = int(block["size"])
                stride = int(block["stride"])

                if stride == 1 and pool_size % 2:
                    maxpool = nn.MaxPool2d(kernel_size=pool_size,
                                           stride=stride,
                                           padding=pool_size // 2)
                elif stride == pool_size:
                    maxpool = nn.MaxPool2d(kernel_size=pool_size,
                                           stride=stride,
                                           padding=0)
                else:
                    maxpool = MaxPoolDark(pool_size, stride)

                out_filters.append(prev_filters)
                prev_stride = stride * prev_stride
                out_strides.append(prev_stride)
                model.append(maxpool)

            elif block["type"] == "upsample":
                stride = int(block["stride"])
                out_filters.append(prev_filters)
                prev_stride = prev_stride // stride
                out_strides.append(prev_stride)

                model.append(Upsample_expand(stride))
                # model.append(Upsample_interpolate(stride))

            elif block["type"] == "route":
                layers = block["layers"].split(",")
                ind = len(model)
                layers = [
                    int(i) if int(i) > 0 else int(i) + ind for i in layers
                ]
                if len(layers) == 1:
                    prev_filters = out_filters[layers[0]]
                    prev_stride = out_strides[layers[0]]
                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)
                model.append(EmptyModule())

            elif block["type"] == "shortcut":
                ind = len(model)
                prev_filters = out_filters[ind - 1]
                out_filters.append(prev_filters)
                prev_stride = out_strides[ind - 1]
                out_strides.append(prev_stride)
                model.append(EmptyModule())

            elif block["type"] == "yolo":
                if self.model_type == "BEV_grid":  # BEV grid layer
                    # TODO: go through this code and remove unneccessary parameters
                    yolo_layer = YoloBEVGridLayer()
                    yolo_layer.num_classes = int(block["classes"])
                    self.num_classes = yolo_layer.num_classes
                    yolo_layer.num_anchors = self.num_anchors
                    yolo_layer.stride = prev_stride
                    yolo_layer.scale_x_y = float(block["scale_x_y"])
                    out_filters.append(prev_filters)
                    out_strides.append(prev_stride)
                    model.append(yolo_layer)

                elif self.model_type == "BEV_flat":  # BEV flat layer
                    yolo_layer = YoloBEVFlatLayer()
                    yolo_layer.num_classes = int(block["classes"])
                    self.num_classes = yolo_layer.num_classes
                    yolo_layer.num_predictors = self.num_predictors
                    yolo_layer.num_anchors = self.num_anchors
                    model.append(yolo_layer)

                elif self.model_type == "Yolov4":  # Classic Yolo layer
                    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"])
                    out_filters.append(prev_filters)
                    out_strides.append(prev_stride)
                    model.append(yolo_layer)

                else:
                    print(
                        "model type not recognized while building yolo layer!")

            else:
                print("unknown type %s" % (block["type"]))

        return model
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
    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