首页 > 解决方案 > 来自 tf.keras 的 VGG19 不支持索引

问题描述

我正在使用 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

我认为应该更新(重新编写)函数函数以将其与 tensorflow.keras 中的 VGG19 一起使用。我怎么能适应它?

谢谢

标签: tensorflowkerasvgg-net

解决方案


很容易找出问题所在。如果您显示结果,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())

根据他们对过滤器的要求是一个 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执行相同的操作


推荐阅读