我正在尝试使用 Keras 提供的预训练权重对 Resnet50 架构(我基于 keras 实现构建我的架构)进行微调。
这种预训练模型的缺点是它已经在具有树通道的图像上进行了训练。在我的情况下,输入有三个以上的通道。它可以是 5、6、...
该通道变化意味着第一个 conv1 层取决于通道数。因此,要使用预训练的权重,我有两种可能性。
在 conv1 层之后加载权重,对于 conv1 之前的层,它们被设置为随机的。
第二种可能性是使用 RGB 权重设置 conv1,并使用 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))