来自 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

做同样的事情