为什么在 Keras 中实施 Resnet50 禁止小于 32x32x3 的图像?
Why implementation of Resnet50 in Keras forbids images smaller than 32x32x3?
我想了解为什么 ResNet50 在 Keras 中的实现禁止小于 32x32x3 的图像。
基于他们的实施:https://github.com/keras-team/keras-applications/blob/master/keras_applications/resnet50.py
那就是捕捉函数_obtain_input_shape
为了克服这个问题,我根据他们的代码做了自己的实现,并删除了禁止最小尺寸的代码。在我的实现中,我还通过复制第一个 conv1 层的 RGB 权重,增加了使用具有三个以上通道的预训练模型的可能性。
def ResNet50(load_weights=True,
input_shape=None,
pooling=None,
classes=1000):
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)
# Condition on the last layer
if pooling == 'avg':
x = layers.GlobalAveragePooling2D()(x)
elif pooling == 'max':
x = layers.GlobalMaxPooling2D()(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)
f = h5py.File(weights_path, 'r')
d = f['conv1']
# Used to work with more than 3 channels with pre-trained model
if input_shape[2] % 3 == 0:
model.get_layer('tuned_conv1').set_weights([d['conv1_W_1:0'][:].repeat(input_shape[2] / 3, axis=2),
d['conv1_b_1:0']])
else:
m = (3 * int(input_shape[2] / 3)) + 3
model.get_layer('tuned_conv1').set_weights(
[d['conv1_W_1:0'][:].repeat(m, axis=2)[:, :, 0:input_shape[2], :],
d['conv1_b_1:0']])
return model
我 运行 我用 10x10x3 图像实现的,它似乎可以工作。因此我不明白为什么他们设置这个最小界限。
他们没有提供有关此选择的任何信息。我还检查了原始论文,但没有发现任何关于最小输入形状的限制。我想这是有原因的,但我不知道这个。
所以我想知道为什么对Resnet的实现做了这样的限制。
ResNet50 有 5 个下采样阶段,介于 2x2 的 MaxPooling 和 Strided Convolution 之间,每个方向的步幅为 2 px。这意味着最小输入大小为2^5 = 32,这个值也是感受野的大小
使用小于 32x32 的图像没有多大意义,因为那时下采样没有做任何事情,这将改变网络的行为。对于如此小的图像,最好使用另一个下采样较少(如 DenseNet)或深度较小的网络。
我想了解为什么 ResNet50 在 Keras 中的实现禁止小于 32x32x3 的图像。
基于他们的实施:https://github.com/keras-team/keras-applications/blob/master/keras_applications/resnet50.py
那就是捕捉函数_obtain_input_shape
为了克服这个问题,我根据他们的代码做了自己的实现,并删除了禁止最小尺寸的代码。在我的实现中,我还通过复制第一个 conv1 层的 RGB 权重,增加了使用具有三个以上通道的预训练模型的可能性。
def ResNet50(load_weights=True,
input_shape=None,
pooling=None,
classes=1000):
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)
# Condition on the last layer
if pooling == 'avg':
x = layers.GlobalAveragePooling2D()(x)
elif pooling == 'max':
x = layers.GlobalMaxPooling2D()(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)
f = h5py.File(weights_path, 'r')
d = f['conv1']
# Used to work with more than 3 channels with pre-trained model
if input_shape[2] % 3 == 0:
model.get_layer('tuned_conv1').set_weights([d['conv1_W_1:0'][:].repeat(input_shape[2] / 3, axis=2),
d['conv1_b_1:0']])
else:
m = (3 * int(input_shape[2] / 3)) + 3
model.get_layer('tuned_conv1').set_weights(
[d['conv1_W_1:0'][:].repeat(m, axis=2)[:, :, 0:input_shape[2], :],
d['conv1_b_1:0']])
return model
我 运行 我用 10x10x3 图像实现的,它似乎可以工作。因此我不明白为什么他们设置这个最小界限。
他们没有提供有关此选择的任何信息。我还检查了原始论文,但没有发现任何关于最小输入形状的限制。我想这是有原因的,但我不知道这个。
所以我想知道为什么对Resnet的实现做了这样的限制。
ResNet50 有 5 个下采样阶段,介于 2x2 的 MaxPooling 和 Strided Convolution 之间,每个方向的步幅为 2 px。这意味着最小输入大小为2^5 = 32,这个值也是感受野的大小
使用小于 32x32 的图像没有多大意义,因为那时下采样没有做任何事情,这将改变网络的行为。对于如此小的图像,最好使用另一个下采样较少(如 DenseNet)或深度较小的网络。