Как вывести второй слой сети?

9

Моя модель обучена на цифровых изображениях (MNIST dataset ). Я пытаюсь распечатать вывод второго слоя моей сети - массив из 128 чисел.

После прочтения много примеров - например, это , и это , или это .

Мне не удалось сделать это в моей собственной сети. Ни одно из решений не работает по моему собственному алгоритму.

Ссылка на Colab: https://colab.research.google.com/drive/1MLbpWJmq8JZB4_zKongaHP2o3M1FpvAv?fbclid=IwAR20xRz2i6sFS-Nm6Xwfk5hztdXOuxY4tZaDRXxAHa9B9

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

Что мне не хватает? Как вывести Второй слой? Если моя форма (28,28)- какой должен быть тип и значение input_shape?


Неудачные испытания и ошибки, например:

(1)

for layer in model.layers:

    get_2nd_layer_output = K.function([model.layers[0].input],[model.layers[2].output])
    layer_output = get_2nd_layer_output(layer)[0]
    print('\nlayer output: get_2nd_layer_output=, layer=', layer, '\nlayer output: get_2nd_layer_output=', get_2nd_layer_output)

Ошибка типа: входные данные должны быть списком или кортежем.

(2)

input_shape=(28, 28)
inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers]          # all layer outputs
functor = K.function([inp, K.learning_phase()], outputs )   # evaluation function

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = functor([test, 0.])
print('layer_outs',layer_outs)

tenorflow.python.framework.errors_impl.FailedPreconditionError: Ошибка при чтении переменной ресурса dens_1 / bias из Container: localhost. Это может означать, что переменная была неинициализирована. Не найдено: Контейнер localhost не существует. (Не удалось найти ресурс: localhost / плотность_1 / смещение) [[{{узел плотность_1 / BiasAdd / ReadVariableOp}}]]

Шир К
источник
1
Ссылки в вашем вопросе не работают, пожалуйста, добавьте их, чтобы иметь представление о том, что вы пытались
Тео Рубенах
@ ThéoRubenach Готово
Шир К

Ответы:

3

Похоже, вы смешиваете старые keras (до tenorflow 2.0:) import kerasи новые keras ( from tensorflow import keras).

Старайтесь не использовать старые keras вместе с tenorflow> = 2.0 (и не ссылаться на старую документацию, как в первой ссылке), так как ее легко спутать с новой (хотя ничего строго нелогичного):

from tensorflow import keras
from keras.models import Model
print(Model.__module__) #outputs 'keras.engine.training'

from tensorflow.keras.models import Model
print(Model.__module__) #outputs 'tensorflow.python.keras.engine.training'

Поведение будет очень нестабильным, смешивая эти две библиотеки.

Как только это будет сделано, используя ответ из того, что вы пытались, m - это ваша модель, и my_input_shape- это форма ваших моделей, то есть форма одного изображения (здесь (28, 28) или (1, 28, 28), если у вас есть партии):

from tensorflow import keras as K
my_input_data = np.random.rand(*my_input_shape) 
new_temp_model = K.Model(m.input, m.layers[3].output) #replace 3 with index of desired layer
output_of_3rd_layer = new_temp_model.predict(my_input_data) #this is what you want

Если у вас есть одно изображение, imgвы можете написать прямоnew_temp_model.predict(img)

Тео Рубенах
источник
Рубенах, что ты имеешь в виду под my_input_shape? какой должна быть ценность этого вар?
Шир К
1
в соответствии с формой ввода вашей модели, вы даже определяете ее в своем коде:input_shape=(28, 28)
Тео Рубенах
1
здесь я использую случайные данные, но в вашем случае вы, my_input_dataконечно, должны заменить свои собственные данные
Тео Рубенах
Что вы подразумеваете под «вашими собственными данными»? Какими должны быть значения внутри - тренировочные данные? тестовые данные? это должен быть только 1 объект (изображение) или список / массив / кортеж объектов (изображений)? Я попробовал много разных комбинаций этого, и ничего из этого не сработало. Когда я установил 'input_shape', как вы упомянули, я получил ошибку '' AttributeError: у объекта 'tuple' нет атрибута 'shape' '
Шир К
1
Я обновил свой ответ соответственно. Изображение, которое вы хотите использовать, зависит от вашего варианта использования, оно не имеет ничего общего с кодом. Если вы все еще не уверены, возможно, задайте новый вопрос на другом сайте stackexchange?
Тео Рубенах
3

(Предполагая TF2)

Я думаю, что самым простым подходом было бы назвать ваши слои, а затем вызывать их со стандартным вводом, чтобы ваша модель могла выглядеть так

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28), name='flatten'),
    keras.layers.Dense(128, activation='relu', name='hidden'),
    keras.layers.Dense(10, activation='softmax')
])

Затем просто создайте вход и

my_input = tf.random.normal((1, 28, 28)) # Should be like the standard input to your network
output_of_flatten = model.get_layer('flatten')(my_input)
output_of_hidden = model.get_layer('hidden')(output_of_flatten)

output_of_hidden это то, что вы ищете

Альтернативный подход

Если вы ищете более общее решение, предполагая, что ваша модель является последовательной, вы можете использовать indexключевое слово get_layerвроде этого

my_input = tf.random.normal((1, 28, 28)) # Should be like the standard input to your network
desired_index = 1  # 1 == second layer

for i in range(desired_index):
    my_input = model.get_layer(index=i)(my_input)

В конце этого цикла my_inputдолжно быть то, что вы ищете

bluesummers
источник
что вы подразумеваете под "my_input = ... # должно быть похоже на стандартный ввод вашей сети"? какой должна быть ценность этого вар?
Шир К
1
Любой стандартный ввод, например, что ожидает последовательная модель - если ваш ввод 28x28, вы должны передать массив 1x28x28 для одного примера
bluesummers
1
Отредактировал мой ответ
bluesummers
Как напечатать значения внутри 'output_of_hidden'? Текущий результат - 'Tensor output_of_hidden ("hidden_1 / Relu: 0", shape = (1, 128), dtype = float32)'. Я пытался использовать сеанс & Eval, но я получаю ошибки.
Шир К
1
Если в TF2 вы обычно звоните, output_of_hidden.numpy()и он преобразует его в массив numpy
bluesummers