Exemple #1
0
def classifier(base_layers, input_rois, num_rois, nb_classes = 21, trainable=False):

    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround

    if K.backend() == 'tensorflow':
        pooling_regions = 14
        input_shape = (num_rois,14,14,1024)
    elif K.backend() == 'theano':
        pooling_regions = 7
        input_shape = (num_rois,1024,7,7)

    out_roi_pool = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])
    out = classifier_layers(out_roi_pool, input_shape=input_shape, trainable=True)

    out = TimeDistributed(Flatten())(out)

    out_class = TimeDistributed(Dense(nb_classes, activation='softmax', kernel_initializer='zero'), name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes-1), activation='linear', kernel_initializer='zero'), name='dense_regress_{}'.format(nb_classes))(out)
    return [out_class, out_regr]
Exemple #2
0
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=21,
               trainable=False):
    #baselayers是vgg网络的输出值featuremap
    #inputrois 是经过ROIpooling 以后的结果
    #numrois是roi预选框的个数
    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround

    if K.backend() == 'tensorflow':
        pooling_regions = 7
        input_shape = (num_rois, 7, 7, 512)
    elif K.backend() == 'theano':
        pooling_regions = 7
        input_shape = (num_rois, 512, 7, 7)
    #RoiPoolingConv:返回的shape为(1, 32, 7, 7, 512)含义是batch_size,预选框的个数,特征图宽,特征图高度,特征图深度
    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])
    # RoiPoolingConv:返回的shape为(1, 32, 7, 7, 512)
    # 含义是batch_size, 预选框的个数,特征图宽,特征图高度,特征图深度
    #TimeDistributed:输入至少为3D张量,下标为1的维度将被认为是时间维。
    # 即对以一个维度下的变量当作一个完整变量来看待本文是32。你要实现的目的就是对32个预选框提出的32个图片做出判断
    out = TimeDistributed(Flatten(name='flatten'))(out_roi_pool)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc1'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc2'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    # TimeDistributed:输入至少为3D张量,下标为1的维度将被认为是时间维。即对以一个维度下的变量当作一个完整变量来看待本文是32。
    # 你要实现的目的就是对32个预选宽提出的32个图片做出判断
    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer='zero'),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     kernel_initializer='zero'),
                               name='dense_regress_{}'.format(nb_classes))(out)
    #背景是不需要回归的,所以outregr少一个
    return [out_class, out_regr]
def classifier(base_layers, input_rois, num_rois, nb_classes, trainable=True):
    """
    The final classifier to match original implementation for VGG-16
    The only difference being the Roipooling layer uses tensorflow's bilinear interpolation
    """

    pooling_regions = 7
    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois,
                                  trainable=trainable)(
                                      [base_layers, input_rois])

    out = TimeDistributed(Flatten(), name="flatten",
                          trainable=trainable)(out_roi_pool)
    out = TimeDistributed(Dense(4096, activation='relu', trainable=trainable),
                          name="fc1",
                          trainable=trainable)(out)
    out = TimeDistributed(Dropout(0.5), name="drop_out1", trainable=trainable)(
        out)  # add dropout to match original implememtation
    out = TimeDistributed(Dense(4096, activation='relu', trainable=trainable),
                          name="fc2",
                          trainable=trainable)(out)
    out = TimeDistributed(Dropout(0.5), name="drop_out2", trainable=trainable)(
        out)  # add dropout to match original implementation

    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer='zero',
                                      trainable=trainable),
                                name='dense_class_{}'.format(nb_classes),
                                trainable=trainable)(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     kernel_initializer='zero',
                                     trainable=trainable),
                               name='dense_regress_{}'.format(nb_classes),
                               trainable=trainable)(out)

    return [out_class, out_regr]
Exemple #4
0
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=21,
               trainable=False):

    pooling_regions = 7

    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])

    out = classifier_layers(out_roi_pool, trainable=trainable)
    out = TimeDistributed(Flatten(), name='td_flatten')(out)
    out_class = TimeDistributed(Dense(nb_classes, activation='softmax'),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     init='zero'),
                               name='dense_regr_{}'.format(nb_classes))(out)

    return [out_class, out_regr]
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=21,
               trainable=False):

    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround

    if K.backend() == 'tensorflow':
        pooling_regions = 14
        input_shape = (num_rois, 14, 14, 1024
                       )  # densenet output channels are 1024..
    elif K.backend() == 'theano':
        pooling_regions = 7
        input_shape = (num_rois, 4096, 7, 7)

    # from vgg version..
    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])

    out_roi_pool = TimeDistributed(AveragePooling2D((7, 7)),
                                   name='avg_pool')(out_roi_pool)
    out = TimeDistributed(Flatten(name='flatten'))(out_roi_pool)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc1'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc2'))(out)
    out = TimeDistributed(Dropout(0.5))(out)

    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer='zero'),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     kernel_initializer='zero'),
                               name='dense_regress_{}'.format(nb_classes))(out)

    return [out_class, out_regr]
Exemple #6
0
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=21,
               trainable=False):
    """
    :param base_layers: output of nn_base
    :param input_rois:  Input(shape = (None,4))
    :param num_rois:  4
    :param nb_classes:
    :param trainable: True
    :return:
    """
    pooling_regions = 7
    input_shape = (num_rois, 7, 7, 512)
    ## (1, self.num_rois, self.pool_size, self.pool_size, self.nb_channels )
    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])
    ### Flatten layer
    out = TimeDistributed(Flatten(name='flatten'))(
        out_roi_pool)  ## 1 * num_rois * pool_size^2 * nb_channels
    out = TimeDistributed(Dense(4096, activation='relu',
                                name='fc1'))(out)  ### 4096 output
    out = TimeDistributed(Dropout(0.5))(out)  ##
    out = TimeDistributed(Dense(4096, activation='relu', name='fc2'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    ###
    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer='zero'),
                                name='dense_class_{}'.format(nb_classes))(out)
    print(out_class)
    out_reg = TimeDistributed(Dense(4 * (nb_classes - 1),
                                    activation='linear',
                                    kernel_initializer='zero'),
                              name='dense_regress_{}'.format(nb_classes))(out)
    print(out_reg)

    return [out_class, out_reg]
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=21,
               trainable=False):

    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround

    if K.backend() == 'tensorflow':
        pooling_regions = 7
        input_shape = (num_rois, 7, 7, 1024)
    elif K.backend() == 'theano':
        pooling_regions = 7
        input_shape = (num_rois, 1024, 7, 7)

    x = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])

    # pool inputs to save memory.
    #x = TimeDistributed(Convolution2D(1024, (3, 3), name='lastconv', padding="same"))(out_roi_pool)
    #x = Activation('relu')(x)

    x = TimeDistributed(AveragePooling2D((7, 7)), name='avg_pool')(x)
    out = TimeDistributed(Flatten(name='flatten'))(x)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc1'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc2'))(out)
    out = TimeDistributed(Dropout(0.5))(out)

    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer='zero'),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     kernel_initializer='zero'),
                               name='dense_regress_{}'.format(nb_classes))(out)

    return [out_class, out_regr]
Exemple #8
0
def fine_layer(base_layers,
               input_rois,
               num_rois=7,
               nb_classes=200,
               trainable=False):
    pooling_regions = 7
    input_shape = (num_rois, 7, 7, 512)
    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])

    partout_0 = part_net(out_roi_pool, 0, nb_classes)
    partout_1 = part_net(out_roi_pool, 1, nb_classes)
    partout_2 = part_net(out_roi_pool, 2, nb_classes)
    partout_3 = part_net(out_roi_pool, 3, nb_classes)
    partout_4 = part_net(out_roi_pool, 4, nb_classes)
    partout_5 = part_net(out_roi_pool, 5, nb_classes)
    partout_6 = part_net(out_roi_pool, 6, nb_classes)
    #holy_classout = merge.concatenate([partout_0,partout_1,partout_2,partout_3,partout_4,partout_5,partout_6],mode='concat')
    return [
        partout_0, partout_1, partout_2, partout_3, partout_4, partout_5,
        partout_6
    ]
def classifier(base_layers, input_rois, num_rois, nb_classes=21, trainable=False):
    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround

    if K.backend() == 'tensorflow':
        pooling_regions = 14
        input_shape = (num_rois, 14, 14, 512)
    elif K.backend() == 'theano':
        pooling_regions = 7
        input_shape = (num_rois, 512, 7, 7)

    out_roi_pool = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])

    out = TimeDistributed(BatchNormalization(name='final_conv_bn'))(out_roi_pool)
    out = TimeDistributed(Activation('relu', name='final_act'))(out)
    out = TimeDistributed(GlobalAveragePooling2D(name='final_pooling'))(out)

    out_class = TimeDistributed(Dense(nb_classes, activation='softmax', kernel_initializer='zero'),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1), activation='linear', kernel_initializer='zero'),
                               name='dense_regress_{}'.format(nb_classes))(out)

    return [out_class, out_regr]
Exemple #10
0
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=21,
               trainable=True):

    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround

    kernel_init = RandomNormal(mean=0, stddev=0.01)

    if K.backend() == 'tensorflow':
        pooling_regions = 7
        input_shape = (num_rois, 7, 7, 512)
    elif K.backend() == 'theano':
        pooling_regions = 7
        input_shape = (num_rois, 512, 7, 7)

    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])

    out = TimeDistributed(Flatten(name='flatten'))(out_roi_pool)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc1'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc2'))(out)
    out = TimeDistributed(Dropout(0.5))(out)

    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer=kernel_init),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     kernel_initializer=kernel_init),
                               name='dense_regress_{}'.format(nb_classes))(out)

    return [out_class, out_regr]
Exemple #11
0
def classifier(base_layers, input_rois, num_rois, nb_classes = 21, trainable_cls= True ,trainable_view = True):

    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround
    # num_rois = K.shape(input_rois)[1]
    if K.backend() == 'tensorflow':
        pooling_regions = 14
        input_shape = (num_rois,14,14,1024)
    elif K.backend() == 'theano':
        pooling_regions = 7
        input_shape = (num_rois,1024,7,7)

    out_roi_pool = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])

    out1,fc = view_layers(out_roi_pool, input_shape=input_shape, trainable=trainable_view)
    fc = TimeDistributed(Flatten())(fc)
    ##use FC
    out1 = TimeDistributed(Dense(1024, activation='relu', kernel_initializer='glorot_normal',trainable=True), name='dense_fc1024_view_{}'.format(nb_classes))(fc)
    # out1 = TimeDistributed(Dense(1024, activation='relu', kernel_initializer='glorot_normal',trainable=True), name='dense_fc1024_view1_{}'.format(nb_classes))(out1)
    ##dont use FC
    # out1 = TimeDistributed(Flatten())(out1)
    # out1 = TimeDistributed(LeakyReLU())(out1)



    out2 = classifier_layers(out_roi_pool, input_shape=input_shape, trainable=trainable_cls)
    out2 = TimeDistributed(Flatten())(out2)


    # out view is in the size of 360*num_cls
    out_view = TimeDistributed(Dense(360 * nb_classes, activation='linear', kernel_initializer='normal',trainable=True), name='dense_view1024_{}'.format(nb_classes))(out1)

    out_class = TimeDistributed(Dense(nb_classes, activation='softmax', kernel_initializer='zero',trainable=trainable_cls), name='dense_class_{}'.format(nb_classes))(out2)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes-1), activation='linear', kernel_initializer='zero',trainable=trainable_cls), name='dense_regress_{}'.format(nb_classes))(out2)


    return [out_class, out_regr, out_view],out1
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=21,
               trainable=False):

    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround

    if K.backend() == 'tensorflow':
        pooling_regions = 7
        #alpha=5
        input_shape = (num_rois, 7, 7, 512)
    elif K.backend() == 'theano':
        pooling_regions = 7
        #alpha=5
        input_shape = (num_rois, 512, 7, 7)

    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])
    #out_roi_pool = PSRoiAlignPooling(pooling_regions, num_rois, alpha)([base_layers, input_rois])

    # Flatten conv layer and connect to 2 FC 2 Dropout
    out = TimeDistributed(Flatten())(out_roi_pool)
    out = TimeDistributed(Dense(1024, activation='relu', name='fc'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    # outputs
    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer='zero'),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     kernel_initializer='zero'),
                               name='dense_regress_{}'.format(nb_classes))(out)

    return [out_class, out_regr]
Exemple #13
0
def classifier(base_layers,
               input_rois,
               num_rois,
               nb_classes=2,
               trainable=False):

    pooling_regions = 14
    input_shape = (num_rois, 14, 14, 1024)

    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois)([base_layers, input_rois])
    out = classifier_layers(out_roi_pool,
                            input_shape=input_shape,
                            trainable=True)

    out = TimeDistributed(Flatten())(out)

    gaussian_initializer_cls = TruncatedNormal(stddev=0.01)
    gaussian_initializer_regr = TruncatedNormal(stddev=0.001)

    out_class = TimeDistributed(Dense(
        nb_classes,
        activation='softmax',
        kernel_initializer=gaussian_initializer_cls,
        kernel_regularizer=WEIGHT_RGLZ,
        bias_regularizer=BIAS_RGLZ),
                                name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(
        4 * (nb_classes - 1),
        activation='linear',
        kernel_initializer=gaussian_initializer_regr,
        kernel_regularizer=WEIGHT_RGLZ,
        bias_regularizer=BIAS_RGLZ),
                               name='dense_regress_{}'.format(nb_classes))(out)
    return [out_class, out_regr]
Exemple #14
0
def fg_classifier(base_layers,
                  input_rois0,
                  input_rois1,
                  input_rois2,
                  input_rois3,
                  input_rois4,
                  input_rois5,
                  input_rois6,
                  nb_classes=200,
                  trainable=True):
    pooling_regions = 7
    #input_shape = (num_rois, 7, 7, 512)

    # out_roi_pool = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])
    #input_rois = K.expand_dims(input_rois, axis=1)
    #input_rois = K.expand_dims(input_rois, axis=1)
    head = RoiPoolingConv(pooling_regions, 1)([base_layers, input_rois0])
    legs = RoiPoolingConv(pooling_regions, 1)([base_layers, input_rois1])
    wings = RoiPoolingConv(pooling_regions, 1)([base_layers, input_rois2])
    back = RoiPoolingConv(pooling_regions, 1)([base_layers, input_rois3])
    belly = RoiPoolingConv(pooling_regions, 1)([base_layers, input_rois4])
    breast = RoiPoolingConv(pooling_regions, 1)([base_layers, input_rois5])
    tail = RoiPoolingConv(pooling_regions, 1)([base_layers, input_rois6])

    head_out = fg_layer(head, 'head', nb_classes=nb_classes)
    legs_out = fg_layer(legs, 'legs', nb_classes=nb_classes)
    wings_out = fg_layer(wings, 'wings', nb_classes=nb_classes)
    back_out = fg_layer(back, 'back', nb_classes=nb_classes)
    belly_out = fg_layer(belly, 'belly', nb_classes=nb_classes)
    breast_out = fg_layer(breast, 'breast', nb_classes=nb_classes)
    tail_out = fg_layer(tail, 'tail', nb_classes=nb_classes)

    #outlist = [head_out,legs_out,wings_out,back_out,belly_out,breast_out,tail_out]

    return [
        head_out, legs_out, wings_out, back_out, belly_out, breast_out,
        tail_out
    ]
Exemple #15
0
def fine_layer_hole(base_layers, input_rois, num_rois=1, nb_classes = 200):
    pooling_regions = 14
    input_shape = (num_rois, 14, 14, 1024)
    out_roi_pool = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])
    hole_partout = part_net(out_roi_pool, 0, nb_classes)
    return hole_partout
Exemple #16
0
def classifier(base_layers, input_rois, num_rois, nb_classes, trainable=True):
    """
    The final classifier
    NOTE:
    The Roipooling layer uses tensorflow's bilinear interpolation
    """
    channel_axis = 4  # additional TD layer
    pooling_regions = 17  # tensorflow implementation
    out_roi_pool = RoiPoolingConv(pooling_regions,
                                  num_rois,
                                  trainable=trainable)(
                                      [base_layers, input_rois])

    # mixed 8: 8 x 8 x 1280
    branch3x3 = conv2d_bn_td(out_roi_pool, 192, 1, 1, trainable=trainable)
    branch3x3 = conv2d_bn_td(branch3x3,
                             320,
                             3,
                             3,
                             strides=(2, 2),
                             padding='valid',
                             trainable=trainable)

    branch7x7x3 = conv2d_bn_td(out_roi_pool, 192, 1, 1, trainable=trainable)
    branch7x7x3 = conv2d_bn_td(branch7x7x3, 192, 1, 7, trainable=trainable)
    branch7x7x3 = conv2d_bn_td(branch7x7x3, 192, 7, 1, trainable=trainable)
    branch7x7x3 = conv2d_bn_td(branch7x7x3,
                               192,
                               3,
                               3,
                               strides=(2, 2),
                               padding='valid',
                               trainable=trainable)

    branch_pool = TimeDistributed(MaxPooling2D((3, 3),
                                               strides=(2, 2),
                                               trainable=trainable),
                                  trainable=trainable)(out_roi_pool)
    x = layers.concatenate([branch3x3, branch7x7x3, branch_pool],
                           axis=channel_axis,
                           name='mixed8')

    # mixed 9,10: 8 x 8 x 2048
    for i in range(2):
        branch1x1 = conv2d_bn_td(x, 320, 1, 1, trainable=trainable)

        branch3x3 = conv2d_bn_td(x, 384, 1, 1, trainable=trainable)
        branch3x3_1 = conv2d_bn_td(branch3x3, 384, 1, 3, trainable=trainable)
        branch3x3_2 = conv2d_bn_td(branch3x3, 384, 3, 1, trainable=trainable)
        branch3x3 = layers.concatenate([branch3x3_1, branch3x3_2],
                                       axis=channel_axis,
                                       name='mixed9_' + str(i))

        branch3x3dbl = conv2d_bn_td(x, 448, 1, 1, trainable=trainable)
        branch3x3dbl = conv2d_bn_td(branch3x3dbl,
                                    384,
                                    3,
                                    3,
                                    trainable=trainable)
        branch3x3dbl_1 = conv2d_bn_td(branch3x3dbl,
                                      384,
                                      1,
                                      3,
                                      trainable=trainable)
        branch3x3dbl_2 = conv2d_bn_td(branch3x3dbl,
                                      384,
                                      3,
                                      1,
                                      trainable=trainable)
        branch3x3dbl = layers.concatenate([branch3x3dbl_1, branch3x3dbl_2],
                                          axis=channel_axis)

        branch_pool = TimeDistributed(AveragePooling2D((3, 3),
                                                       strides=(1, 1),
                                                       padding='same',
                                                       trainable=trainable),
                                      trainable=trainable)(x)
        branch_pool = conv2d_bn_td(branch_pool, 192, 1, 1, trainable=trainable)
        x = layers.concatenate(
            [branch1x1, branch3x3, branch3x3dbl, branch_pool],
            axis=channel_axis,
            name='mixed' + str(9 + i))

    out = TimeDistributed(GlobalAveragePooling2D(trainable=trainable),
                          name='global_avg_pooling',
                          trainable=trainable)(x)
    out_class = TimeDistributed(Dense(nb_classes,
                                      activation='softmax',
                                      kernel_initializer='zero',
                                      trainable=trainable),
                                name='dense_class_{}'.format(nb_classes),
                                trainable=trainable)(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes - 1),
                                     activation='linear',
                                     kernel_initializer='zero',
                                     trainable=trainable),
                               name='dense_regress_{}'.format(nb_classes),
                               trainable=trainable)(out)

    return [out_class, out_regr]