def build_wBiFPN(features, num_channels, id): if id == 0: #-------------------------------------------# # 获得三个shape的有效特征层 # 分别是C3 64, 64, 40 # C4 32, 32, 112 # C5 16, 16, 320 #-------------------------------------------# _, _, C3, C4, C5 = features #------------------------------------------------------------------------# # 第一次BIFPN需要 下采样 与 调整通道 获得 p3_in p4_in p5_in p6_in p7_in #------------------------------------------------------------------------# #-------------------------------------------# # 首先对通道数进行调整 # C3 64, 64, 40 -> 64, 64, 64 #-------------------------------------------# P3_in = C3 P3_in = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode3/resample_0_0_8/conv2d')(P3_in) P3_in = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode3/resample_0_0_8/bn')(P3_in) #-------------------------------------------# # 首先对通道数进行调整 # C4 32, 32, 112 -> 32, 32, 64 # -> 32, 32, 64 #-------------------------------------------# P4_in = C4 P4_in_1 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode2/resample_0_1_7/conv2d')(P4_in) P4_in_1 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode2/resample_0_1_7/bn')(P4_in_1) P4_in_2 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode4/resample_0_1_9/conv2d')(P4_in) P4_in_2 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode4/resample_0_1_9/bn')(P4_in_2) #-------------------------------------------# # 首先对通道数进行调整 # C5 16, 16, 320 -> 16, 16, 64 # -> 16, 16, 64 #-------------------------------------------# P5_in = C5 P5_in_1 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode1/resample_0_2_6/conv2d')(P5_in) P5_in_1 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode1/resample_0_2_6/bn')(P5_in_1) P5_in_2 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode5/resample_0_2_10/conv2d')(P5_in) P5_in_2 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode5/resample_0_2_10/bn')(P5_in_2) #-------------------------------------------# # 对C5进行下采样,调整通道数与宽高 # C5 16, 16, 320 -> 8, 8, 64 #-------------------------------------------# P6_in = layers.Conv2D(num_channels, kernel_size=1, padding='same', name='resample_p6/conv2d')(C5) P6_in = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name='resample_p6/bn')(P6_in) P6_in = layers.MaxPooling2D(pool_size=3, strides=2, padding='same', name='resample_p6/maxpool')(P6_in) #-------------------------------------------# # 对P6_in进行下采样,调整宽高 # P6_in 8, 8, 64 -> 4, 4, 64 #-------------------------------------------# P7_in = layers.MaxPooling2D(pool_size=3, strides=2, padding='same', name='resample_p7/maxpool')(P6_in) #-------------------------------------------------------------------------# #--------------------------构建BIFPN的上下采样循环-------------------------# P7_U = layers.UpSampling2D()(P7_in) P6_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode0/add')([P6_in, P7_U]) P6_td = layers.Activation(lambda x: tf.nn.swish(x))(P6_td) P6_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode0/op_after_combine5')(P6_td) P6_U = layers.UpSampling2D()(P6_td) P5_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode1/add')([P5_in_1, P6_U]) P5_td = layers.Activation(lambda x: tf.nn.swish(x))(P5_td) P5_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode1/op_after_combine6')(P5_td) P5_U = layers.UpSampling2D()(P5_td) P4_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode2/add')([P4_in_1, P5_U]) P4_td = layers.Activation(lambda x: tf.nn.swish(x))(P4_td) P4_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode2/op_after_combine7')(P4_td) P4_U = layers.UpSampling2D()(P4_td) P3_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode3/add')([P3_in, P4_U]) P3_out = layers.Activation(lambda x: tf.nn.swish(x))(P3_out) P3_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode3/op_after_combine8')(P3_out) P3_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P3_out) P4_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode4/add')([P4_in_2, P4_td, P3_D]) P4_out = layers.Activation(lambda x: tf.nn.swish(x))(P4_out) P4_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode4/op_after_combine9')(P4_out) P4_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P4_out) P5_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode5/add')([P5_in_2, P5_td, P4_D]) P5_out = layers.Activation(lambda x: tf.nn.swish(x))(P5_out) P5_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode5/op_after_combine10')(P5_out) P5_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P5_out) P6_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode6/add')([P6_in, P6_td, P5_D]) P6_out = layers.Activation(lambda x: tf.nn.swish(x))(P6_out) P6_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode6/op_after_combine11')(P6_out) P6_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P6_out) P7_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode7/add')([P7_in, P6_D]) P7_out = layers.Activation(lambda x: tf.nn.swish(x))(P7_out) P7_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode7/op_after_combine12')(P7_out) else: P3_in, P4_in, P5_in, P6_in, P7_in = features P7_U = layers.UpSampling2D()(P7_in) P6_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode0/add')([P6_in, P7_U]) P6_td = layers.Activation(lambda x: tf.nn.swish(x))(P6_td) P6_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode0/op_after_combine5')(P6_td) P6_U = layers.UpSampling2D()(P6_td) P5_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode1/add')([P5_in, P6_U]) P5_td = layers.Activation(lambda x: tf.nn.swish(x))(P5_td) P5_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode1/op_after_combine6')(P5_td) P5_U = layers.UpSampling2D()(P5_td) P4_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode2/add')([P4_in, P5_U]) P4_td = layers.Activation(lambda x: tf.nn.swish(x))(P4_td) P4_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode2/op_after_combine7')(P4_td) P4_U = layers.UpSampling2D()(P4_td) P3_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode3/add')([P3_in, P4_U]) P3_out = layers.Activation(lambda x: tf.nn.swish(x))(P3_out) P3_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode3/op_after_combine8')(P3_out) P3_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P3_out) P4_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode4/add')([P4_in, P4_td, P3_D]) P4_out = layers.Activation(lambda x: tf.nn.swish(x))(P4_out) P4_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode4/op_after_combine9')(P4_out) P4_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P4_out) P5_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode5/add')([P5_in, P5_td, P4_D]) P5_out = layers.Activation(lambda x: tf.nn.swish(x))(P5_out) P5_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode5/op_after_combine10')(P5_out) P5_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P5_out) P6_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode6/add')([P6_in, P6_td, P5_D]) P6_out = layers.Activation(lambda x: tf.nn.swish(x))(P6_out) P6_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode6/op_after_combine11')(P6_out) P6_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P6_out) P7_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode7/add')([P7_in, P6_D]) P7_out = layers.Activation(lambda x: tf.nn.swish(x))(P7_out) P7_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode7/op_after_combine12')(P7_out) return [P3_out, P4_out, P5_out, P6_out, P7_out]
def build_wBiFPN(features, num_channels, id, freeze_bn=False): if id == 0: _, _, C3, C4, C5 = features # 第一次BIFPN需要 下采样 与 降通道 获得 p3_in p4_in p5_in p6_in p7_in #-----------------------------下采样 与 降通道----------------------------# P3_in = C3 P3_in = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode3/resample_0_0_8/conv2d')(P3_in) P3_in = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode3/resample_0_0_8/bn')(P3_in) P4_in = C4 P4_in_1 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode2/resample_0_1_7/conv2d')(P4_in) P4_in_1 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode2/resample_0_1_7/bn')(P4_in_1) P4_in_2 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode4/resample_0_1_9/conv2d')(P4_in) P4_in_2 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode4/resample_0_1_9/bn')(P4_in_2) P5_in = C5 P5_in_1 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode1/resample_0_2_6/conv2d')(P5_in) P5_in_1 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode1/resample_0_2_6/bn')(P5_in_1) P5_in_2 = layers.Conv2D(num_channels, kernel_size=1, padding='same', name=f'fpn_cells/cell_{id}/fnode5/resample_0_2_10/conv2d')(P5_in) P5_in_2 = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name=f'fpn_cells/cell_{id}/fnode5/resample_0_2_10/bn')(P5_in_2) P6_in = layers.Conv2D(num_channels, kernel_size=1, padding='same', name='resample_p6/conv2d')(C5) P6_in = layers.BatchNormalization(momentum=MOMENTUM, epsilon=EPSILON, name='resample_p6/bn')(P6_in) P6_in = layers.MaxPooling2D(pool_size=3, strides=2, padding='same', name='resample_p6/maxpool')(P6_in) P7_in = layers.MaxPooling2D(pool_size=3, strides=2, padding='same', name='resample_p7/maxpool')(P6_in) #-------------------------------------------------------------------------# #--------------------------构建BIFPN的上下采样循环-------------------------# P7_U = layers.UpSampling2D()(P7_in) P6_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode0/add')([P6_in, P7_U]) P6_td = layers.Activation(lambda x: tf.nn.swish(x))(P6_td) P6_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode0/op_after_combine5')(P6_td) P6_U = layers.UpSampling2D()(P6_td) P5_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode1/add')([P5_in_1, P6_U]) P5_td = layers.Activation(lambda x: tf.nn.swish(x))(P5_td) P5_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode1/op_after_combine6')(P5_td) P5_U = layers.UpSampling2D()(P5_td) P4_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode2/add')([P4_in_1, P5_U]) P4_td = layers.Activation(lambda x: tf.nn.swish(x))(P4_td) P4_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode2/op_after_combine7')(P4_td) P4_U = layers.UpSampling2D()(P4_td) P3_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode3/add')([P3_in, P4_U]) P3_out = layers.Activation(lambda x: tf.nn.swish(x))(P3_out) P3_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode3/op_after_combine8')(P3_out) P3_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P3_out) P4_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode4/add')([P4_in_2, P4_td, P3_D]) P4_out = layers.Activation(lambda x: tf.nn.swish(x))(P4_out) P4_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode4/op_after_combine9')(P4_out) P4_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P4_out) P5_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode5/add')([P5_in_2, P5_td, P4_D]) P5_out = layers.Activation(lambda x: tf.nn.swish(x))(P5_out) P5_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode5/op_after_combine10')(P5_out) P5_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P5_out) P6_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode6/add')([P6_in, P6_td, P5_D]) P6_out = layers.Activation(lambda x: tf.nn.swish(x))(P6_out) P6_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode6/op_after_combine11')(P6_out) P6_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P6_out) P7_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode7/add')([P7_in, P6_D]) P7_out = layers.Activation(lambda x: tf.nn.swish(x))(P7_out) P7_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode7/op_after_combine12')(P7_out) else: P3_in, P4_in, P5_in, P6_in, P7_in = features P7_U = layers.UpSampling2D()(P7_in) P6_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode0/add')([P6_in, P7_U]) P6_td = layers.Activation(lambda x: tf.nn.swish(x))(P6_td) P6_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode0/op_after_combine5')(P6_td) P6_U = layers.UpSampling2D()(P6_td) P5_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode1/add')([P5_in, P6_U]) P5_td = layers.Activation(lambda x: tf.nn.swish(x))(P5_td) P5_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode1/op_after_combine6')(P5_td) P5_U = layers.UpSampling2D()(P5_td) P4_td = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode2/add')([P4_in, P5_U]) P4_td = layers.Activation(lambda x: tf.nn.swish(x))(P4_td) P4_td = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode2/op_after_combine7')(P4_td) P4_U = layers.UpSampling2D()(P4_td) P3_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode3/add')([P3_in, P4_U]) P3_out = layers.Activation(lambda x: tf.nn.swish(x))(P3_out) P3_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode3/op_after_combine8')(P3_out) P3_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P3_out) P4_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode4/add')([P4_in, P4_td, P3_D]) P4_out = layers.Activation(lambda x: tf.nn.swish(x))(P4_out) P4_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode4/op_after_combine9')(P4_out) P4_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P4_out) P5_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode5/add')([P5_in, P5_td, P4_D]) P5_out = layers.Activation(lambda x: tf.nn.swish(x))(P5_out) P5_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode5/op_after_combine10')(P5_out) P5_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P5_out) P6_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode6/add')([P6_in, P6_td, P5_D]) P6_out = layers.Activation(lambda x: tf.nn.swish(x))(P6_out) P6_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode6/op_after_combine11')(P6_out) P6_D = layers.MaxPooling2D(pool_size=3, strides=2, padding='same')(P6_out) P7_out = wBiFPNAdd(name=f'fpn_cells/cell_{id}/fnode7/add')([P7_in, P6_D]) P7_out = layers.Activation(lambda x: tf.nn.swish(x))(P7_out) P7_out = SeparableConvBlock(num_channels=num_channels, kernel_size=3, strides=1, name=f'fpn_cells/cell_{id}/fnode7/op_after_combine12')(P7_out) return [P3_out, P4_out, P5_out, P6_out, P7_out]