来自 tf.keras 的 VGG19 不支持索引
VGG19 from tf.keras does not support indexing
我正在使用 Tensorflow1.14.0 在 Ubuntu 虚拟机中加载独立的 VGG19,如下所示:
VGG19 = scipy.io.loadmat(path_VGG19) #stored in my disc
VGG19_layers = VGG19['layers'][0]
然后我将它传递给函数 _conv2dWithRelu():
def _conv2dWithRelu(prev_layer, n_layer, layer_name,VGG19_layers):
# get weights for this layer:
weights = VGG19_layers[n_layer][0][0][2][0][0]
W = tf.constant(weights)
bias = VGG19_layers[n_layer][0][0][2][0][1]
b = tf.constant(np.reshape(bias, (bias.size)))
# create a conv2d layer
conv2d = tf.nn.conv2d(prev_layer, filter=W, strides=[1, 1, 1, 1], padding='SAME') + b
# add a ReLU function and return
return tf.nn.relu(conv2d)
然而,当我想使用 tensorflow.keras 中的 VGG19 来抑制两个完全连接的层 FC 以管理图像输入大小时,我这样加载它:
from tensorflow.keras.applications.vgg19 import VGG19
from tensorflow.keras.layers import Input
model = VGG19(weights="imagenet", include_top=False, input_tensor=Input(shape=(1200, 1600,
3))) #my target input shape
VGG19_layers = model.layers
问题是当我调用上面定义的函数 _conv2dWithRelu() 时,出现以下错误:
TypeError: 'InputLayer' object does not support indexing
我认为 function 函数应该更新(重新编写)以与来自 tensorflow.keras 的 VGG19 一起使用。我该如何调整它?
谢谢
很容易找出问题所在。如果您显示 model.layers
的结果,您将看到每一层都是一个对象类型
[<tensorflow.python.keras.engine.input_layer.InputLayer object at 0x7f550fc09510>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550f0c8ed0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ed32fd0>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550eca3b10>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ecb5c10>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ecc3ad0>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550ecd6910>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec5d190>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec69850>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec7a6d0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec7a850>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550ec1aed0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec220d0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec2cbd0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ed5b110>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f5516559210>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f5516558810>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec54b90>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ebdbe10>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ebedf90>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ebfe7d0>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550ec11790>]
当您通过 VGG19_layers[n_layer][0]0[0][0] 索引它们时,您无法获取它。您应该用 VGG19_layers[n_layer].weights()
代替权重,用 VGG19_layers[n_layer].bias()
代替。
详情,VGG19_layers[1].weights[0]
[0]为权重索引。你可以自己动手来解决你的问题。
<tf.Variable 'block1_conv1/kernel:0' shape=(3, 3, 3, 64) dtype=float32>
此外,VGG19_layers[0] 将是没有权重和偏差的输入层。因此,你应该从 [1]
开始你的图层,而不是 [0]
VGG19_layers[0].weights "results": []
当我检查你的代码时,看起来你正试图保持卷积层的权重并通过 relu 传递它。然后,您应该将整个权重复制到您创建的新卷积中的过滤器,而不是像您所做的那样分割权重。为此,我建议您使用 tf2.x。当您在 tf2.x 中检查权重层的值时,它们会为您提供该过滤器的矩阵,您可以通过
调用它
weights = tf.constant(VGG19_layers[1].weights[0].numpy())
根据 their requirement 过滤器是一个 4d 张量
然后你只需要传递给卷积
conv2d = tf.nn.conv2d(x, filters=weights, strides=[1, 1, 1, 1], padding='SAME')
The output is ok: `<tf.Tensor: shape=(1, 5, 5, 64), dtype=float32, numpy=
array([[[[-4.9203668e+00, 3.2815304e-01, 1.2678468e-01, ...,
-1.8555930e+00, 1.6412614e-01, -7.1041006e-01],
[-5.3053970e+00, 6.5529823e-01, 8.3891630e-01, ...,
-3.1440034e+00, 2.6984088e+00, 1.3087101e+00],
[-3.3932714e+00, 8.7002671e-01, 1.2363169e+00, ...,
-2.6702189e+00, 4.4932485e+00, 2.9435217e+00],
[-5.1859131e+00, 3.8122973e-01, 2.3676270e-01, ...,
....`
您将对 tf.nn.bias_add
做同样的事情
我正在使用 Tensorflow1.14.0 在 Ubuntu 虚拟机中加载独立的 VGG19,如下所示:
VGG19 = scipy.io.loadmat(path_VGG19) #stored in my disc
VGG19_layers = VGG19['layers'][0]
然后我将它传递给函数 _conv2dWithRelu():
def _conv2dWithRelu(prev_layer, n_layer, layer_name,VGG19_layers):
# get weights for this layer:
weights = VGG19_layers[n_layer][0][0][2][0][0]
W = tf.constant(weights)
bias = VGG19_layers[n_layer][0][0][2][0][1]
b = tf.constant(np.reshape(bias, (bias.size)))
# create a conv2d layer
conv2d = tf.nn.conv2d(prev_layer, filter=W, strides=[1, 1, 1, 1], padding='SAME') + b
# add a ReLU function and return
return tf.nn.relu(conv2d)
然而,当我想使用 tensorflow.keras 中的 VGG19 来抑制两个完全连接的层 FC 以管理图像输入大小时,我这样加载它:
from tensorflow.keras.applications.vgg19 import VGG19
from tensorflow.keras.layers import Input
model = VGG19(weights="imagenet", include_top=False, input_tensor=Input(shape=(1200, 1600,
3))) #my target input shape
VGG19_layers = model.layers
问题是当我调用上面定义的函数 _conv2dWithRelu() 时,出现以下错误:
TypeError: 'InputLayer' object does not support indexing
我认为 function 函数应该更新(重新编写)以与来自 tensorflow.keras 的 VGG19 一起使用。我该如何调整它?
谢谢
很容易找出问题所在。如果您显示 model.layers
的结果,您将看到每一层都是一个对象类型
[<tensorflow.python.keras.engine.input_layer.InputLayer object at 0x7f550fc09510>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550f0c8ed0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ed32fd0>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550eca3b10>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ecb5c10>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ecc3ad0>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550ecd6910>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec5d190>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec69850>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec7a6d0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec7a850>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550ec1aed0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec220d0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec2cbd0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ed5b110>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f5516559210>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f5516558810>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ec54b90>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ebdbe10>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ebedf90>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f550ebfe7d0>, <tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f550ec11790>]
当您通过 VGG19_layers[n_layer][0]0[0][0] 索引它们时,您无法获取它。您应该用 VGG19_layers[n_layer].weights()
代替权重,用 VGG19_layers[n_layer].bias()
代替。
详情,VGG19_layers[1].weights[0]
[0]为权重索引。你可以自己动手来解决你的问题。
<tf.Variable 'block1_conv1/kernel:0' shape=(3, 3, 3, 64) dtype=float32>
此外,VGG19_layers[0] 将是没有权重和偏差的输入层。因此,你应该从 [1]
开始你的图层,而不是 [0]
VGG19_layers[0].weights "results": []
当我检查你的代码时,看起来你正试图保持卷积层的权重并通过 relu 传递它。然后,您应该将整个权重复制到您创建的新卷积中的过滤器,而不是像您所做的那样分割权重。为此,我建议您使用 tf2.x。当您在 tf2.x 中检查权重层的值时,它们会为您提供该过滤器的矩阵,您可以通过
调用它weights = tf.constant(VGG19_layers[1].weights[0].numpy())
根据 their requirement 过滤器是一个 4d 张量
然后你只需要传递给卷积
conv2d = tf.nn.conv2d(x, filters=weights, strides=[1, 1, 1, 1], padding='SAME')
The output is ok: `<tf.Tensor: shape=(1, 5, 5, 64), dtype=float32, numpy=
array([[[[-4.9203668e+00, 3.2815304e-01, 1.2678468e-01, ...,
-1.8555930e+00, 1.6412614e-01, -7.1041006e-01],
[-5.3053970e+00, 6.5529823e-01, 8.3891630e-01, ...,
-3.1440034e+00, 2.6984088e+00, 1.3087101e+00],
[-3.3932714e+00, 8.7002671e-01, 1.2363169e+00, ...,
-2.6702189e+00, 4.4932485e+00, 2.9435217e+00],
[-5.1859131e+00, 3.8122973e-01, 2.3676270e-01, ...,
....`
您将对 tf.nn.bias_add
做同样的事情