【问题标题】:KERAS: How to set weights of Conv2D Layer explicitly using a tensor of same shape as required by weights?KERAS:如何使用与权重要求相同形状的张量显式设置 Conv2D 层的权重?
【发布时间】:2019-06-18 04:27:43
【问题描述】:

我想通过显式定义层的权重矩阵来创建一个 conv2d 层(Conv2D 的 use_bias 参数设置为 False)。我一直在尝试使用 layer.set_weights([K]) 来做到这一点,其中 K 是 (?, 7, 7, 512, 512) 张量。

在简单的 Tensorflow API 中,可以通过将张量传递给 tf.nn.conv2d(input, filter,..) 中的 filter 参数来完成

此外,我还有更多问题,我应该展示我是否应该解决 K 张量中的批处理维度,因为它是由网络生成的

基本上,我想实现一个超网络,在该超网络中,我从 Tensor K 中的另一个网络生成了上面指定的 Conv2D 层的权重。权重 Tensor K 的形状为 [height, width, Filters, Channels]

template= Input(shape=(448,684,3))
hyper_net= VGG16(weights='imagenet', include_top=False, 
input_tensor=None, input_shape=(448,684, 3))

k1= hyper_net(template)

kconv1= hyper_net.get_layer(name='block5_conv1')
config_conv1= kconv1.get_config()
k1conv1 = Conv2D.from_config(config_conv1)(k1)

kconv2= hyper_net.get_layer(name='block5_conv2')
config_conv2= kconv2.get_config()
k1conv2 = Conv2D.from_config(config_conv2)(k1conv1)

k1pool1= MaxPooling2D(pool_size=(2,3))(k1conv2)

k1pool1= Reshape((7,7,512,1))(k1pool1)
print(k1pool1.shape)

K= Conv3D(512, (1,1,1), strides=(1, 1, 1), padding='valid', 
activation=None, use_bias=True, kernel_initializer='he_normal', bias_initializer='zeros', kernel_regularizer=l2(0.01), bias_regularizer=l2(0.01))(k1pool1)


ortho= Input(tensor=tf.convert_to_tensor(O))
base_model = VGG16(weights='imagenet', include_top=False, 
input_tensor=None, input_shape=(1760, 1760, 3))

o1= base_model(ortho)

Oconv1= Conv2D(512, (7, 7), activation='relu', padding='valid',use_bias=False)
Oconv1.set_weights([K])

它给出的错误是:

ValueError: You called `set_weights(weights)` on layer "conv2d_4" with a  weight list of length 1, but the layer was expecting 0 weights. Provided weights: [<tf.Tensor 'conv3d_9/add:0' shape=(?, 7, 7, 512, ...

【问题讨论】:

  • K 中的? 是什么。应该是4 dims。
  • ?表示批次维度,因为 K 张量是网络的输出
  • 在定义权重时不需要 batch_size。它是以下暗淡(kernel, Kernel, input_channels, output_channels)。
  • 是的。这就是我尝试处理批处理维度的原因。这样可以将单独的网络(具有batch维度)生成的权重更改为(kernel, Kernel, input_channels, output_channels)

标签: tensorflow machine-learning keras conv-neural-network convolution


【解决方案1】:

我不知道如何直接从张量中执行此操作,但您可以使用 numpy 数组在 Keras 中设置权重。因此,您可以将张量转换为 numpy 数组,然后对其进行设置:

sess = tf.InteractiveSession()
weights = K.eval() # Convert tensor to numpy
Oconv1.set_weights(weights) # Set weights of layer

显然,张量/numpy-array 和 keras 层的维度必须相同。

【讨论】:

  • 按照你说的做,它要求一个 tf.placeholder 对象来运行 eval()。我无法提供占位符张量,因为它是我的模型的输入,它将成为训练数据
  • 这是错误:InvalidArgumentError: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,448,684,3]
  • 所以你不想根据一些张量来初始化权重,你想在线更新它们?基于一些外部模型?我认为您需要添加更多代码来澄清...
  • 嘿,马克,首先我要感谢你。我添加了更多代码。其次是的,我想通过另一个模型生成权重,然后将输出重塑为 Oconv1 层的权重
【解决方案2】:

在带有急切执行的 TensorFlow 2.0 中,您可能可以执行以下操作之一:

1) 在使用set_weights 方法之前,您可以在Oconv1 上调用build 方法。您将获得ValueError,因为该层中的权重变量尚未初始化,因此该层在构建之前无法通过set_weights 获取任何权重。

Oconv1= Conv2D(512, (7, 7), activation='relu', padding='valid',use_bias=False)
input_shape = tf.TensorShape([None, h, w, c])  # to define h, w, c based on shape of layer input
Oconv1.build(input_shape)
Oconv1.set_weights([K])

2) 你也可以将weights kwarg 传入Conv2D 构造函数。

Oconv1= Conv2D(512, (7, 7), activation='relu', padding='valid',use_bias=False,weights=[K])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2016-07-13
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 2019-02-01
    • 1970-01-01
    相关资源
    最近更新 更多