Я пытаюсь добиться тонкой настройки на архитектуре Resnet50 (я построил мой на основе реализации keras) с предварительно подготовленными весами, предоставленными Keras.
Недостаток этой предварительно обученной модели заключается в том, что она имеетОбучались на изображениях с древовидных каналов.В моем случае входы имеют более трех каналов.Это может быть 5, 6, ...
Это изменение канала подразумевает, что первый уровень conv1 зависит от количества каналов.Таким образом, для использования предварительно обученных весов у меня есть две возможности:
Загружать веса после слоя conv1, а для слоев до conv1 они устанавливаются как случайные.
Вторая возможность - установить 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))