0

Keras によって提供される事前トレーニング済みの重みを使用して、Resnet50 アーキテクチャ (keras の実装に基づいてビルドしました) で微調整を達成しようとしています。

この事前トレーニング済みモデルの欠点は、ツリー チャネルを使用して画像でトレーニングされていることです。私の場合、入力には 3 つ以上のチャネルがあります。5、6、...

そのチャネルの変動は、最初の conv1 レイヤーがチャネルの数に依存していることを意味します。したがって、事前にトレーニングされた重みを使用するには、2 つの可能性があります。

  1. conv1 レイヤーの後に重みをロードし、conv1 の前のレイヤーではランダムに設定されます。

  2. 2 番目の可能性は、conv1 に RGB の重みを設定し、残りのチャネルを RGB の重みの複製で満たすことです。

2 番目の可能性を試しましたが、3 の倍数でしか機能しません。さらに、glorot_uniformバンドを複製する代わりに特定のイニシャライザ (たとえば) が必要な場合は、不可能のようです。

だから私は知りたいのですが、特に3の倍数ではなく任意の数のチャネルで動作するために、そのようなことを達成するための機能や他のアプローチがあるかどうかを知りたいですか?

注: 2 番目の可能性を適用する前に、それを実現する関数を見つけようとしましたが、何も見つかりませんでした。

def ResNet50(load_weights=True,
             input_shape=None,
             include_top=False,
             classes=100):
    img_input = Input(shape=input_shape, name='tuned_input')
    x = ZeroPadding2D(padding=(3, 3), name='conv1_pad')(img_input)

    # Stage 1 (conv1_x)
    x = Conv2D(64, (7, 7),
               strides=(2, 2),
               padding='valid',
               kernel_initializer=KERNEL_INIT,
               name='tuned_conv1')(x)

    x = BatchNormalization(axis=CHANNEL_AXIS, name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = ZeroPadding2D(padding=(1, 1), name='pool1_pad')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2))(x)

    # Stage 2 (conv2_x)
    x = _convolution_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
    for block in ['b', 'c']:
        x = _identity_block(x, 3, [64, 64, 256], stage=2, block=block)

    # Stage 3 (conv3_x)
    x = _convolution_block(x, 3, [128, 128, 512], stage=3, block='a')
    for block in ['b', 'c', 'd']:
        x = _identity_block(x, 3, [128, 128, 512], stage=3, block=block)

    # Stage 4 (conv4_x)
    x = _convolution_block(x, 3, [256, 256, 1024], stage=4, block='a')
    for block in ['b', 'c', 'd', 'e', 'f']:
        x = _identity_block(x, 3, [256, 256, 1024], stage=4, block=block)

    # Stage 5 (conv5_x)
    x = _convolution_block(x, 3, [512, 512, 2048], stage=5, block='a')
    for block in ['b', 'c']:
        x = _identity_block(x, 3, [512, 512, 2048], stage=5, block=block)

    # AVGPOOL
    x = AveragePooling2D((2, 2), name="avg_pool")(x)
    if include_top:
        # output layer
        x = Flatten()(x)
        x = Dense(classes, activation='softmax', name='fc' + str(classes), kernel_initializer=KERNEL_INIT)(x)

    inputs = img_input
    # Create model.
    model = models.Model(inputs, x, name='resnet50')

    if load_weights:
        weights_path = get_file(
            'resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',
            WEIGHTS_PATH_NO_TOP,
            cache_subdir='models',
            md5_hash='a268eb855778b3df3c7506639542a6af')
        model.load_weights(weights_path, by_name=True)
        # Set weights for conv1 for 6 channels
        f = h5py.File(weights_path, 'r')
        d = f['conv1']
        model.get_layer('tuned_conv1').set_weights([d['conv1_W_1:0'][:].repeat(2, axis=2), d['conv1_b_1:0']])

    return model

# example image 50x50 with 6 channels
ResNet50(input_shape=(50,50,6))
4

2 に答える 2