VGG19 из tf.keras не поддерживает индексацию

#tensorflow #keras #vgg-net

#tensorflow #keras #vgg-net

Вопрос:

Я загружаю автономный VGG19 на виртуальную машину Ubuntu с помощью Tensorflow1.14.0 следующим образом :

 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)
  

однако, когда я хочу использовать VGG19 из tensorflow.keras для подавления двух полностью соединенных слоев 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 должна быть обновлена (переписана), чтобы использовать ее с VGG19 из tensorflow.keras. Как я мог его адаптировать?

Спасибо

Ответ №1:

Легко разобраться в проблеме. Если вы покажете результат 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

Комментарии:

1. Спасибо за ваш ответ. Я понимаю, что я должен заменить «веса = VGG19_layers[n_layer][0][0][2][0][0]» по «весам=VGG19_layers[n_layers].веса[0][0][2][0][0]» и «смещение=VGG19_layers[n_layers].смещение[0][0][2][0][1]» по «смещению=VGG19_layers[n_layers].смещение[0][0][2][0][1]». При этом я получаю сообщение об ошибке «индекс вне диапазона», связанное со смещением.

2. Когда я смотрю на смещение, его ядро представляет собой вектор из 64 элементов, поэтому вы можете индексировать только один раз, чтобы получить к ним доступ: VGG19_layers[1].bias Out: <tf.Variable 'block1_conv1/bias:0' shape=(64,) dtype=float32>

3. VGG19_layers[1].смещение[0]

4. большое вам спасибо. Я постараюсь обновить свой код с учетом ваших рекомендаций. Могу ли я спросить позже, если код все еще не работает?

5. конечно. Нет проблем, приятель