def DarknetConv2D_BN_Leaky(*args, **kwargs): no_bias_kwargs = {'use_bias': False} no_bias_kwargs.update(kwargs) return compose( DarknetConv2D(*args, **no_bias_kwargs), BatchNormalization(), LeakyReLU(alpha=0.1))
def yolo_body(inputs, num_anchors, num_classes): # ---------------------------------------------------# # 生成darknet53的主干模型 # 获得三个有效特征层,他们的shape分别是: # 52,52,256 # 26,26,512 # 13,13,1024 # ---------------------------------------------------# feat1, feat2, feat3 = darknet_body(inputs) darknet = Model(inputs, feat3) # ---------------------------------------------------# # 第一个特征层 # y1=(batch_size,13,13,3,85) # ---------------------------------------------------# # 13,13,1024 -> 13,13,512 -> 13,13,1024 -> 13,13,512 -> 13,13,1024 -> 13,13,512 x, y1 = make_last_layers(darknet.output, 512, num_anchors * (num_classes + 5)) # 13,13,512 -> 13,13,256 -> 26,26,256 x = compose( DarknetConv2D_BN_Leaky(256, (1, 1)), UpSampling2D(2))(x) # 26,26,256 + 26,26,512 -> 26,26,768 x = Concatenate()([x, feat2]) # ---------------------------------------------------# # 第二个特征层 # y2=(batch_size,26,26,3,85) # ---------------------------------------------------# # 26,26,768 -> 26,26,256 -> 26,26,512 -> 26,26,256 -> 26,26,512 -> 26,26,256 x, y2 = make_last_layers(x, 256, num_anchors * (num_classes + 5)) # 26,26,256 -> 26,26,128 -> 52,52,128 x = compose( DarknetConv2D_BN_Leaky(128, (1, 1)), UpSampling2D(2))(x) # 52,52,128 + 52,52,256 -> 52,52,384 x = Concatenate()([x, feat1]) # ---------------------------------------------------# # 第三个特征层 # y3=(batch_size,52,52,3,85) # ---------------------------------------------------# # 52,52,384 -> 52,52,128 -> 52,52,256 -> 52,52,128 -> 52,52,256 -> 52,52,128 x, y3 = make_last_layers(x, 128, num_anchors * (num_classes + 5)) return Model(inputs, [y1, y2, y3])
def test_empty_compose__ok(mocker): f = mocker.MagicMock() f.return_value = 42 def func(*args, **kwargs): """some doc""" result = f(*args, **kwargs) return result final_func = compose()(func) res = final_func(13, key=24) assert final_func.__doc__ == "some doc" assert res == 42 f.assert_called_once_with(13, key=24)
def test_compose__right_order(mocker): order = [] f = mocker.MagicMock() f.return_value = 42 def wrapper1(func): def inner(*args, **kwargs): order.append("A") result = func(*args, **kwargs) order.append("B") return result return inner def wrapper2(func): def inner(*args, **kwargs): order.append("C") result = func(*args, **kwargs) order.append("D") return result return inner def func(*args, **kwargs): """some doc""" order.append("E") result = f(*args, **kwargs) return result final_func = compose(wrapper1, wrapper2)(func) res = final_func(13, key=24) assert final_func.__doc__ == "some doc" assert res == 42 f.assert_called_once_with(13, key=24) assert order == ["A", "C", "E", "D", "B"]
def resblock_body(x, num_filters, num_blocks, all_narrow=True): #----------------------------------------------------------------# # 利用ZeroPadding2D和一个步长为2x2的卷积块进行高和宽的压缩 #----------------------------------------------------------------# preconv1 = ZeroPadding2D(((1, 0), (1, 0)))(x) preconv1 = DarknetConv2D_BN_Mish(num_filters, (3, 3), strides=(2, 2))(preconv1) #--------------------------------------------------------------------# # 然后建立一个大的残差边shortconv、这个大残差边绕过了很多的残差结构 #--------------------------------------------------------------------# shortconv = DarknetConv2D_BN_Mish( num_filters // 2 if all_narrow else num_filters, (1, 1))(preconv1) #----------------------------------------------------------------# # 主干部分会对num_blocks进行循环,循环内部是残差结构。 #----------------------------------------------------------------# mainconv = DarknetConv2D_BN_Mish( num_filters // 2 if all_narrow else num_filters, (1, 1))(preconv1) for i in range(num_blocks): y = compose( DarknetConv2D_BN_Mish(num_filters // 2, (1, 1)), DarknetConv2D_BN_Mish( num_filters // 2 if all_narrow else num_filters, (3, 3)))(mainconv) mainconv = Add()([mainconv, y]) postconv = DarknetConv2D_BN_Mish( num_filters // 2 if all_narrow else num_filters, (1, 1))(mainconv) #----------------------------------------------------------------# # 将大残差边再堆叠回来 #----------------------------------------------------------------# route = Concatenate()([postconv, shortconv]) # 最后对通道数进行整合 return DarknetConv2D_BN_Mish(num_filters, (1, 1))(route)
def DarknetConv2D_BN_Mish(*args, **kwargs): no_bias_kwargs = {'use_bias': False} no_bias_kwargs.update(kwargs) return compose(DarknetConv2D(*args, **no_bias_kwargs), BatchNormalization(), Mish())
def yolo_body(inputs, num_anchors, num_classes): # ---------------------------------------------------# # 生成CSPdarknet53的主干模型 # 获得三个有效特征层,他们的shape分别是: # 52,52,256 # 26,26,512 # 13,13,1024 # ---------------------------------------------------# feat1, feat2, feat3 = darknet_body(inputs) # 13,13,1024 -> 13,13,512 -> 13,13,1024 -> 13,13,512 -> 13,13,2048 -> 13,13,512 -> 13,13,1024 -> 13,13,512 P5 = DarknetConv2D_BN_Leaky(512, (1, 1))(feat3) P5 = DarknetConv2D_BN_Leaky(1024, (3, 3))(P5) P5 = DarknetConv2D_BN_Leaky(512, (1, 1))(P5) # 使用了SPP结构,即不同尺度的最大池化后堆叠。 maxpool1 = MaxPooling2D(pool_size=(13, 13), strides=(1, 1), padding='same')(P5) maxpool2 = MaxPooling2D(pool_size=(9, 9), strides=(1, 1), padding='same')(P5) maxpool3 = MaxPooling2D(pool_size=(5, 5), strides=(1, 1), padding='same')(P5) P5 = Concatenate()([maxpool1, maxpool2, maxpool3, P5]) P5 = DarknetConv2D_BN_Leaky(512, (1, 1))(P5) P5 = DarknetConv2D_BN_Leaky(1024, (3, 3))(P5) P5 = DarknetConv2D_BN_Leaky(512, (1, 1))(P5) # 13,13,512 -> 13,13,256 -> 26,26,256 P5_upsample = compose(DarknetConv2D_BN_Leaky(256, (1, 1)), UpSampling2D(2))(P5) # 26,26,512 -> 26,26,256 P4 = DarknetConv2D_BN_Leaky(256, (1, 1))(feat2) # 26,26,256 + 26,26,256 -> 26,26,512 P4 = Concatenate()([P4, P5_upsample]) # 26,26,512 -> 26,26,256 -> 26,26,512 -> 26,26,256 -> 26,26,512 -> 26,26,256 P4 = make_five_convs(P4, 256) # 26,26,256 -> 26,26,128 -> 52,52,128 P4_upsample = compose(DarknetConv2D_BN_Leaky(128, (1, 1)), UpSampling2D(2))(P4) # 52,52,256 -> 52,52,128 P3 = DarknetConv2D_BN_Leaky(128, (1, 1))(feat1) # 52,52,128 + 52,52,128 -> 52,52,256 P3 = Concatenate()([P3, P4_upsample]) # 52,52,256 -> 52,52,128 -> 52,52,256 -> 52,52,128 -> 52,52,256 -> 52,52,128 P3 = make_five_convs(P3, 128) # ---------------------------------------------------# # 第三个特征层 # y3=(batch_size,52,52,3,85) # ---------------------------------------------------# P3_output = DarknetConv2D_BN_Leaky(256, (3, 3))(P3) P3_output = DarknetConv2D(num_anchors * (num_classes + 5), (1, 1))(P3_output) # 52,52,128 -> 26,26,256 P3_downsample = ZeroPadding2D(((1, 0), (1, 0)))(P3) P3_downsample = DarknetConv2D_BN_Leaky(256, (3, 3), strides=(2, 2))(P3_downsample) # 26,26,256 + 26,26,256 -> 26,26,512 P4 = Concatenate()([P3_downsample, P4]) # 26,26,512 -> 26,26,256 -> 26,26,512 -> 26,26,256 -> 26,26,512 -> 26,26,256 P4 = make_five_convs(P4, 256) # ---------------------------------------------------# # 第二个特征层 # y2=(batch_size,26,26,3,85) # ---------------------------------------------------# P4_output = DarknetConv2D_BN_Leaky(512, (3, 3))(P4) P4_output = DarknetConv2D(num_anchors * (num_classes + 5), (1, 1))(P4_output) # 26,26,256 -> 13,13,512 P4_downsample = ZeroPadding2D(((1, 0), (1, 0)))(P4) P4_downsample = DarknetConv2D_BN_Leaky(512, (3, 3), strides=(2, 2))(P4_downsample) # 13,13,512 + 13,13,512 -> 13,13,1024 P5 = Concatenate()([P4_downsample, P5]) # 13,13,1024 -> 13,13,512 -> 13,13,1024 -> 13,13,512 -> 13,13,1024 -> 13,13,512 P5 = make_five_convs(P5, 512) # ---------------------------------------------------# # 第一个特征层 # y1=(batch_size,13,13,3,85) # ---------------------------------------------------# P5_output = DarknetConv2D_BN_Leaky(1024, (3, 3))(P5) P5_output = DarknetConv2D(num_anchors * (num_classes + 5), (1, 1))(P5_output) return Model(inputs, [P5_output, P4_output, P3_output])