Отключенный график при объединении двух моделей - PullRequest
0 голосов
/ 09 марта 2019

Попытка построить новую модель на основе части предварительно обученной модели,

Вот немного очищенного кода.

Давайте представим, что мы прошли обучение по модели1 и хотим добавить несколько слоев, определенных в модели2:

import tensorflow.keras as keras
import tensorflow as tf
from tensorflow.keras.layers import Input, Conv2D, Activation
from tensorflow.keras.models import Model, Sequential

model1 = Sequential([
    Conv2D(2, (3,3), padding='same', input_shape=(6,6,1)),
    Activation('relu')
])
model2 = Sequential([
    Conv2D(3, (3,3), padding='same', input_shape=(6,6,2)),
    Activation('softmax')
])

model_merge = Model(inputs=model1.input, 
                    outputs=Activation('softmax')(model2(model1.get_layer('conv2d').output)))

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

Сводка модели1:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 6, 6, 2)           20        
_________________________________________________________________
activation (Activation)      (None, 6, 6, 2)           0         
=================================================================
Total params: 20
Trainable params: 20
Non-trainable params: 0
_________________________________________________________________

Краткое изложение модели2:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 6, 6, 3)           57        
_________________________________________________________________
activation_4 (Activation)    (None, 6, 6, 3)           0         
=================================================================
Total params: 57
Trainable params: 57
Non-trainable params: 0
_________________________ 

И резюме model_merge:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_input (InputLayer)    (None, 6, 6, 1)           0         
_________________________________________________________________
conv2d (Conv2D)              (None, 6, 6, 2)           20        
_________________________________________________________________
sequential_2 (Sequential)    (None, 6, 6, 3)           57        
_________________________________________________________________
activation_4 (Activation)    (None, 6, 6, 3)           0         
=================================================================
Total params: 77
Trainable params: 77
Non-trainable params: 0
_________________________________________________________________

Давайте докажем, что эта объединенная модель не отключена:

layers = [layer.output for layer in model_merge.layers]
test1 = Model(inputs=model_merge.input, outputs=layers[-1])

Все работает просто отлично.

Резюме test1:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_input (InputLayer)    (None, 6, 6, 1)           0         
_________________________________________________________________
conv2d (Conv2D)              (None, 6, 6, 2)           20        
_________________________________________________________________
sequential_2 (Sequential)    (None, 6, 6, 3)           57        
_________________________________________________________________
activation_4 (Activation)    (None, 6, 6, 3)           0         
=================================================================
Total params: 77
Trainable params: 77
Non-trainable params: 0
_________________________________________________________________

Вот трагедия:

test2 = Model(inputs=model_merge.input, outputs=layers[-2])

Самая важная обратная связь:

ValueError: Graph disconnected: cannot obtain value for tensor Tensor("conv2d_2_input:0", shape=(?, 6, 6, 2), dtype=float32) at layer "conv2d_2_input". The following previous layers were accessed without issue: []

полная обратная связь:

ValueErrorTraceback (most recent call last)
<ipython-input-18-946b325081c1> in <module>
----> 1 test = Model(inputs=model_merge.input, outputs=layers[-2])

/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/engine/training.py in __init__(self, *args, **kwargs)
    119 
    120   def __init__(self, *args, **kwargs):
--> 121     super(Model, self).__init__(*args, **kwargs)
    122     # Create a cache for iterator get_next op.
    123     self._iterator_get_next = weakref.WeakKeyDictionary()

/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/engine/network.py in __init__(self, *args, **kwargs)
     79         'inputs' in kwargs and 'outputs' in kwargs):
     80       # Graph network
---> 81       self._init_graph_network(*args, **kwargs)
     82     else:
     83       # Subclassed network

/usr/local/lib/python3.5/dist-packages/tensorflow/python/training/checkpointable/base.py in _method_wrapper(self, *args, **kwargs)
    440     self._setattr_tracking = False  # pylint: disable=protected-access
    441     try:
--> 442       method(self, *args, **kwargs)
    443     finally:
    444       self._setattr_tracking = previous_value  # pylint: disable=protected-access

/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/engine/network.py in _init_graph_network(self, inputs, outputs, name)
    219     # Keep track of the network's nodes and layers.
    220     nodes, nodes_by_depth, layers, layers_by_depth = _map_graph_network(
--> 221         self.inputs, self.outputs)
    222     self._network_nodes = nodes
    223     self._nodes_by_depth = nodes_by_depth

/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/engine/network.py in _map_graph_network(inputs, outputs)
   1850                              'The following previous layers '
   1851                              'were accessed without issue: ' +
-> 1852                              str(layers_with_complete_input))
   1853         for x in node.output_tensors:
   1854           computable_tensors.append(x)

ValueError: Graph disconnected: cannot obtain value for tensor Tensor("conv2d_2_input:0", shape=(?, 6, 6, 2), dtype=float32) at layer "conv2d_2_input". The following previous layers were accessed without issue: []

Это действительно сводит меня с ума,

Есть идеи?

1 Ответ

0 голосов
/ 09 марта 2019

Слой, который вы пытаетесь использовать в качестве вывода, имеет два выходных узла. Первый соединяет вход model2 с выходом model2. Второй выходной узел соединяет выход model1 и первый слой model2. По умолчанию вывод слоя возвращает только первый выходной узел. Таким образом, вы пытаетесь соединить вход model_merge (вход model1) с первым узлом вывода.

Чтобы следующий код показывает это. К отдельным выходным узлам слоя можно получить доступ, используя метод слоя get_output_at().

layer_output = model_merge.layers[-2].output # The first output node
layer_output_1 = model_merge.layers[-2].get_output_at(0) # The first output node
layer_output_2 = model_merge.layers[-2].get_output_at(1) # The second output node

Теперь следующие два кода выдают ошибку, потому что график отключен.

test2 = Model(inputs=model_merge.input, outputs=layer_output)

и

test2 = Model(inputs=model_merge.input, outputs=layer_output_1)

Но код ниже не выдает ошибку, потому что граф подключен.

test2 = Model(inputs=model_merge.input, outputs=layer_output_2)
...