python - 如何更改 Tensorflow 中预训练 ResNet 的第一个卷积?
问题描述
嗨,我需要将模型的第一个卷积从 rgb/resnet_v1_50/conv1/weights:0 (float32_ref 7x7x3x64) 更改为 rgb/resnet_v1_50/conv1/weights:0 (float32_ref 7x7x4x64),因此基本上将滤波器形式 3 的数量增加到4 接受 4 个通道的图像,但在其他地方保留预训练的权重(只是额外的通道初始化 ramdonly)。
你知道如何在 Tensorflow 1.x 中做到这一点(我更像是一个 PyTorch 人......)?
在 PyTorch 中,我这样做:
net = model.resnet50(num_classes=dataset_train.num_classes(),pretrained=True)
new_conv1 = nn.Conv2d(4, 64, kernel_size=7, stride=2,padding=3,bias=False)
conv1 = net.conv1
with torch.no_grad():
new_conv1.weight[:, :3, :, :]= conv1.weight
new_conv1.bias = conv1.bias
net.conv1 = new_conv1
以下是在 tensorflow 中创建模型的方式:
def single_stream(self, images, modality, is_training, reuse=False):
with tf.variable_scope(modality, reuse=reuse):
with slim.arg_scope(resnet_v1.resnet_arg_scope()):
_, end_points = resnet_v1.resnet_v1_50(
images, self.no_classes, is_training=is_training, reuse=reuse)
# last bottleneck before logits
net = end_points[modality + '/resnet_v1_50/block4']
if 'autoencoder' in self.mode:
return net
with tf.variable_scope(modality + '/resnet_v1_50', reuse=reuse):
bottleneck = slim.conv2d(net, self.hidden_repr_size, [
7, 7], padding='VALID', activation_fn=tf.nn.relu, scope='f_repr')
net = slim.conv2d(bottleneck, self.no_classes, [
1, 1], activation_fn=None, scope='_logits_')
if ('train_hallucination' in self.mode or 'test_disc' in self.mode or 'train_eccv' in self.mode):
return net, bottleneck
return net
我可以使用 build_model 中的命令: self.images = tf.placeholder(tf.float32, [None, 224, 224, 4 ], modality + '_images') 有效地将 3 更改为 4: rgb/resnet_v1_50 /conv1/weights:0 (float32_ref 7x7x4x64) [12544, bytes: 50176] 但问题出在检查点上!
非常感谢你的帮助!
解决方案
正如您使用 Pytorch 所做的那样,您可以在 Keras 中做同样的事情,它现在是 TF2 的一个模块(更多信息)。
我将向您展示一种可能的方法:
net_conv1 = model.layers[2] # first 2D convolutional layer, from model.layers, or model.summary()
# your new set of weights must have same dimensions of the ouput of the layer
print( 'weights shape: ', numpy.shape(net_conv1.weights) )
print( net_conv1.weights[0].shape )
print( net_conv1.weights[1].shape )
# New weights
osh_0 = net_conv1.weights[0].shape.as_list()
osh_1 = net_conv1.weights[1].shape.as_list()
print(osh_0, osh_1)
new_conv1_w_0 = numpy.random.rand( *osh_0 )
new_conv1_w_1 = numpy.random.rand( *osh_1 )
# update the weights
net_conv1.set_weights([new_conv1_w_0, new_conv1_w_1])
# check the result
net_conv1.get_weights()
# update the model
model.layers[2] = net_conv1
检查 Keras 文档的图层部分。
希望它会有所帮助
推荐阅读
- python - 如何检查一个单词是否按字母顺序出现在python中另一个单词之前或之后?
- javascript - 如何在js中找到画布的中心
- floating-point - 32 位浮点数可以精确表示到小数点后的最高值是多少?
- ios - iOS 上的 Firebase 云消息传递
- typescript - 打字稿 - 接口中的默认函数 - > 错误(TS)属性或预期签名
- android - 长 Web API 路由属性除以零错误
- reactjs - 使用 Express + Webpack Dev Middleware + Webpack Hot Middleware 无法重新加载
- javascript - localStorage 响应晚于新页面加载
- javascript - 如何使用 javascript/jquery 将表单信息写入本地 txt 存档?
- r - 如何在泊松回归中组合组来估计对比度?