Keras, непоследовательное поведение при использовании model.predict для доступа к выходным промежуточным слоям с помощью spektral GCN

#python #tensorflow #keras

#python #тензорный поток #keras

Вопрос:

Я пытаюсь получить доступ к выводам промежуточных слоев графовых сверточных сетей (GCN) и model.predict выдает ошибку InvalidArgument для входного значения, где в качестве модели.подгонка работает нормально с тем же вводом.

Вот мой код, и он использует набор данных цитирования ‘CORA’ из OGB, предоставленный библиотекой spektral, которые предоставляют алгоритмы и примеры для сверточной сети графов. Мой код основан на одном из примеров из той же библиотеки, здесь

 from spektral.datasets import citation
from spektral.layers import GraphConv
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dropout, Dense
import numpy as np

A, X, y, train_mask, val_mask, test_mask = citation.load_data('cora')

At = A.transpose()

N = A.shape[0]
F = X.shape[-1]
n_classes = y.shape[-1]

X_in = Input(shape=(F, ))
A_in = Input((N, ), sparse=True)
X_1 = GraphConv(16, 'relu', name="layer1")([X_in, A_in])
X_1 = Dropout(0.5, name="layer2")(X_1)
X_2 = GraphConv(n_classes, 'softmax', name="output")([X_1, A_in])
model = Model(inputs=[X_in, A_in], outputs=X_2)

A = GraphConv.preprocess(A).astype('f4')
At = GraphConv.preprocess(At).astype('f4')

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              weighted_metrics=['acc'])
model.summary()

# Prepare data
X = X.toarray()
A = A.astype('f4')
At = At.astype('f4')
validation_data = ([X, A], y, val_mask)

# Train model
model.fit([X, A], 
          y,
          sample_weight=train_mask,
          validation_data=validation_data,
          epochs=1,
          batch_size=N,
          shuffle=False
)

# Access intemediate layers of model
layer_name = 'layer2'
intermediate_layer_model = Model(inputs=model.input,
                                 outputs=model.get_layer(layer_name).output)

model_input = [X,A]
intermediate_output = intermediate_layer_model.predict(model_input)
print("nnIntermediate_output=",intermediate_output,"nn")
  

Вот сообщение об ошибке:

 Traceback (most recent call last):
  File "PLGcn_example4_stackflow_debug.py", line 53, in <module>
    intermediate_output = intermediate_layer_model.predict(model_input)
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 130, in _method_wrapper
    return method(self, *args, **kwargs)
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 1599, in predict
    tmp_batch_outputs = predict_function(iterator)
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 780, in __call__
    result = self._call(*args, **kwds)
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 846, in _call
    return self._concrete_stateful_fn._filtered_call(canon_args, canon_kwds)  # pylint: disable=protected-access
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 1848, in _filtered_call
    cancellation_manager=cancellation_manager)
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 1924, in _call_flat
    ctx, args, cancellation_manager=cancellation_manager))
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 550, in call
    ctx=ctx)
  File "/home/mansoor4/.local/lib/python3.7/site-packages/tensorflow/python/eager/execute.py", line 60, in quick_execute
    inputs, attrs, num_outputs)
tensorflow.python.framework.errors_impl.InvalidArgumentError:  Cannot multiply A and B because inner dimension does not match: 2708 vs. 32.  Did you forget a transpose?  Dimensions of A: [32, 2708).  Dimensions of B: [32,16]
         [[node functional_3/layer1/SparseTensorDenseMatMul/SparseTensorDenseMatMul (defined at /home/mansoor4/.local/lib/python3.7/site-packages/spektral/layers/ops/matmul.py:33) ]] [Op:__inference_predict_function_22928]

Errors may have originated from an input operation.
Input Source operations connected to node functional_3/layer1/SparseTensorDenseMatMul/SparseTensorDenseMatMul:
 stack (defined at PLGcn_example4_stackflow_debug.py:53)
 functional_3/layer1/MatMul (defined at /home/mansoor4/.local/lib/python3.7/site-packages/spektral/layers/ops/matmul.py:45)

Function call stack:
predict_function
  

Сообщение об ошибке связано с несоответствием внутренних измерений для умножения. Я попытался использовать ответ для ввода, например model_input = [X, At], чтобы устранить проблему, но все еще сталкиваюсь с той же ошибкой.

Я новичок в Keras и Spektral. Я искал связанные сообщения в stackflow и перепробовал множество возможностей, но не смог получить вывод промежуточных значений из сети.

Ответ №1:

Решение

predict Функция Keras Model имеет аргумент по умолчанию batch_size=32 . Вы можете решить это двумя способами.

 intermediate_output = intermediate_layer_model.predict(model_input, batch_size=N)
  

или

 intermediate_output = intermediate_layer_model.predict_on_batch(model_input)
  

В вашем коде первое измерение вашей матрицы смежности и матрицы характеристик узлов будет разделено на пакеты по 32. Однако модель ожидает, что у вас всегда будет полный график, поэтому вам следует установить размер пакета на N (что вы и делаете при вызове model.fit ).

Объяснение

Чтобы понять, почему это необходимо, подумайте об операциях, которые выполняет слой GCN под капотом: A @ X @ W . Это умножение матрицы на фигуры (N, N) x (N, F) x (F, F’). Обратите внимание, что внутренние размеры умножений всегда одинаковы: N с N и F с F.

Теперь, если вы выполняете пакетную обработку, вы устанавливаете для первых измерений A и X значение B = 32. Это дает вам умножение (B, N) x (B, F) x (F, F’). Видите, как внутренние размеры первого умножения больше не совпадают? Это ошибка, которую вызывает TF. Это говорит тебе:

 Cannot multiply A and B because inner dimension does not match: 2708 vs. 32
  

В этом случае N=2708 и B=32.

Ваше здоровье

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

1. Спасибо за четкое объяснение проблемы. Это решается после предложенных вами методов.