Функциональные модели суммирования с функциями питона вызывают разъединение графа в Керасе - PullRequest
1 голос
/ 13 марта 2019

Я хочу подключить model_1:

x_a = Input((5,))
hidden_a = Dense(2)(x_a)
hidden_b = Dense(2)(x_a)
model_1 = Model(x_a, [hidden_a, hidden_b])

и model_2:

x_b = Input((2,))
output = Dense(1)(x_b)
model_2 = Model(x_b, output)

Я могу сделать это с помощью следующей строки:

model_3 = Model(x_a, model_2(model_1.outputs[0]))

Однако я хотел бы определить произвольное количество моделей, и поэтому я хотел бы использовать функции для этого.

Интересно, что когда я пытаюсь встроить каждую модель в функцию, выполните следующие действия:

def model1():
  x_a = Input((5,))
  hidden_a = Dense(2)(x_a)
  hidden_b = Dense(2)(x_a)
  model_1 = Model(x_a, [hidden_a, hidden_b])
  return model_1

def model2():    
  x_b = Input((2,))
  output = Dense(1)(x_b)
  model_2 = Model(x_b, output)
  return model_2

input_a = Input((5,))
m1 = model1()
m2 = model2()
m3 = Model(input_a, m2(m1.outputs[0]))

Я получаю сообщение об ошибке:

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

В основном я хочу сделать то же самое, что и в этом посте: Почему при использовании этой простой модели с несколькими выходами Keras жалуется на отсутствие градиентов?

Но с функциями.

Есть ли способ использовать функцию, чтобы делать то, что я хочу, или вы думаете, что вместо этого лучше использовать пользовательские слои? Спасибо.

Ответы [ 2 ]

1 голос
/ 14 марта 2019

Если вы проектируете функции вашей модели с помощью входов «model_inputs» и «sub_model_inputs», вы можете выполнить эту работу.Полностью рабочий код (без ошибок градиента) можно увидеть ниже:

from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.models import Model
import numpy as np

def model1(model_inputs, sub_model_inputs):
  #x_a = Input((5,))
  hidden_a = Dense(2)(sub_model_inputs)
  hidden_b = Dense(2)(sub_model_inputs)
  model_1 = Model(model_inputs, [hidden_a, hidden_b])
  return model_1

def model2(model_inputs, sub_model_inputs):    
  #x_b = Input((2,))
  output = Dense(1)(sub_model_inputs)
  model_2 = Model(model_inputs, output)
  return model_2

input_a = Input((5,))
m1 = model1(input_a, input_a)
m2 = model2(input_a, m1.outputs[0])
m3 = Model(input_a, m2.outputs)

m3.compile(optimizer='adam', loss='mse')

x= np.ones((10,5))
y = np.ones((10,1))
m3.train_on_batch(x,y)

model_inputs - это вход полной модели (в сочетании с более мелкими моделями), в то время как sub_model_inputs соответствуют входу конкретной модели.подмодель (например, модель1 и модель2 в данном случае).

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

Я думаю, что изменение м3 на это должно работать:

m3 = Model(input_a, m2(m1(input_a)[0]))

Проблема вашего метода в том, что в вашем графе модели нет связи между input_a и выходом m2, поэтому модель не знает, что делать с input_a

...