Как установить веса для определенных каналов в кератах с предварительно обученными весами? - PullRequest
0 голосов
/ 18 марта 2019

Я пытаюсь добиться тонкой настройки на архитектуре Resnet50 (я построил мой на основе реализации keras) с предварительно подготовленными весами, предоставленными Keras.

Недостаток этой предварительно обученной модели заключается в том, что она имеетОбучались на изображениях с древовидных каналов.В моем случае входы имеют более трех каналов.Это может быть 5, 6, ...

Это изменение канала подразумевает, что первый уровень conv1 зависит от количества каналов.Таким образом, для использования предварительно обученных весов у меня есть две возможности:

  1. Загружать веса после слоя conv1, а для слоев до conv1 они устанавливаются как случайные.

  2. Вторая возможность - установить conv1 с весами RGB и заполнить оставшиеся каналы репликацией весов RGB.

Я попробовал вторую возможность, но она работает только с несколькимииз 3. Более того, если мне нужны конкретные инициализаторы (например, glorot_uniform) вместо дублирования полос, это кажется невозможным.

Поэтому я хотел бы знать, есть ли какие-то функции или другие подходы, отличные от моейчтобы достичь такой цели, особенно для работы с любым количеством каналов вместо нескольких 3?

Примечание: перед применением второй возможности я пытался найти функции для достижения этой цели, но ничего не нашел.

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))

1 Ответ

1 голос
/ 19 марта 2019

Ваша модель ResNet может обрабатывать входные изображения с 3 каналами (например, изображения RGB).Теперь у вас есть изображение, которое может иметь любое количество каналов.Один из способов преодоления этого состоит в том, чтобы повторить каждый канал вашего входного изображения 3 раза, независимо обработать каждый из реплицированных каналов с помощью модели, а затем объединить результаты (которые фактически являются картами характеристик конечного слоя в модели).Вот эскиз этого подхода:

from keras import backend as K
from keras.layers import Input, Lambda, concatenate

inp = Input(shape=(w, h, num_channels))
rep_c = Lambda(lambda x: K.repeat_elements(K.expand_dims(x, axis=-1), 3, -1))

out_maps = []
for i in range(num_channels):
    out_maps.append(resnet_model(rep_c[:,:,:,i]))

concat = concatenate(out_maps)

# the rest of the model goes here...

Но учтите, что в зависимости от имеющихся у вас данных и проблемы, над которой вы работаете, этот подход может работать или не работать с хорошей точностью, т.е. если выне уверен, что вам нужно поэкспериментировать, чтобы выяснить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...