Error de tiempo de ejecución: gráfico desconectado para GAN porque no se puede obtener la entrada

Aquí está mi architecture discriminadora:

def build_discriminator(img_shape,embedding_shape): model1 = Sequential() model1.add(Conv2D(32, kernel_size=5, strides=2, input_shape=img_shape, padding="same")) model1.add(LeakyReLU(alpha=0.2)) model1.add(Dropout(0.25)) model1.add(Conv2D(48, kernel_size=5, strides=2, padding="same")) #model.add(ZeroPadding2D(padding=((0,1),(0,1)))) model1.add(BatchNormalization(momentum=0.8)) model1.add(LeakyReLU(alpha=0.2)) model1.add(Dropout(0.25)) model1.add(Conv2D(64, kernel_size=5, strides=2, padding="same")) model1.add(BatchNormalization(momentum=0.8)) model1.add(LeakyReLU(alpha=0.2)) model1.add(Dropout(0.25)) model1.add(Conv2D(128, kernel_size=5, strides=2, padding="same")) model1.add(BatchNormalization(momentum=0.8)) model1.add(LeakyReLU(alpha=0.2)) model1.add(Dropout(0.25)) model1.add(Conv2D(256, kernel_size=5, strides=2, padding="same")) model1.add(BatchNormalization(momentum=0.8)) model1.add(LeakyReLU(alpha=0.2)) model1.add(Dropout(0.25)) model1.add(Flatten()) model1.add(Dense(200)) model2=Sequential() model2.add(Dense(50, input_shape=embedding_shape)) model2.add(Dense(100)) model2.add(Dense(200)) model2.add(Flatten()) merged_model = Sequential() merged_model.add(Merge([model1, model2], mode='concat')) merged_model.add(Dense(1, activation='sigmoid', name='output_layer')) #merged_model.compile(loss='binary_crossentropy', optimizer='adam', #metrics=['accuracy']) #model1.add(Dense(1, activation='sigmoid')) merged_model.summary() merged_model.input_shape img = Input(shape=img_shape) emb = Input(shape=embedding_shape) validity = merged_model([img,emb]) return Model([img,emb],validity) 

Y aquí está la architecture del generador:

 def build_generator(latent_dim=484): model = Sequential() model.add(Dense(624 * 2 * 2, activation="relu", input_dim=latent_dim)) model.add(Reshape((2, 2, 624))) model.add(UpSampling2D()) model.add(Conv2D(512, kernel_size=5, padding="same")) model.add(BatchNormalization(momentum=0.8)) model.add(Activation("relu")) model.add(UpSampling2D()) #4x4x512 model.add(Conv2D(256, kernel_size=5, padding="same")) model.add(BatchNormalization(momentum=0.8)) model.add(Activation("relu")) model.add(UpSampling2D()) #8x8x256 model.add(Conv2D(128, kernel_size=5, padding="same")) model.add(BatchNormalization(momentum=0.8)) model.add(Activation("relu")) model.add(UpSampling2D()) #16x16x128 model.add(Conv2D(64, kernel_size=5, padding="same")) model.add(BatchNormalization(momentum=0.8)) model.add(Activation("relu")) model.add(UpSampling2D()) #32x32x64 model.add(Conv2D(32, kernel_size=5, padding="same")) model.add(BatchNormalization(momentum=0.8)) model.add(Activation("relu")) model.add(UpSampling2D()) #64x64x32 model.add(Conv2D(3, kernel_size=5, padding="same")) model.add(Activation("tanh")) #128x128x3 noise = Input(shape=(latent_dim,)) img = model(noise) return Model(noise, img) 

Y aquí es cómo estoy haciendo la red GAN:

 optimizer = Adam(0.0004, 0.5) discriminator=build_discriminator((128,128,3),(1,128,3)) discriminator.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']) # Build the generator generator = build_generator() # The generator takes noise as input and generates imgs z = Input(shape=(100+384,)) img = generator(z) # For the combined model we will only train the generator discriminator.trainable = False temp=Input(shape=(1,128,3)) # The discriminator takes generated images as input and determines validity valid = discriminator([img,temp]) # The combined model (stacked generator and discriminator) # Trains the generator to fool the discriminator combined = Model(z, valid) combined.compile(loss='binary_crossentropy', optimizer=optimizer) 

El discriminador tiene 2 modelos, y obtendrá como entrada una imagen de forma 128x128x3 y una incrustación de forma 1x128x3 y ambos modelos se fusionan entonces. El modelo del generador solo genera ruido y genera una imagen de 128x128x3 . Entonces, en la línea combined = Model(z, valid) , obtengo el siguiente error:

 RuntimeError: Graph disconnected: cannot obtain value for tensor Tensor("input_5:0", shape=(?, 1, 128, 3), dtype=float32) at layer "input_5". The following previous layers were accessed without issue: ['input_4', 'model_2'] 

lo cual creo que se debe al hecho de que el discriminador no puede encontrar información de inserción, pero le estoy dando un tensor de forma (1,128,3) , al igual que el ruido se alimenta al modelo del generador. ¿Alguien por favor me puede ayudar donde estoy haciendo mal?

Y después de que todo esté configurado aquí es cómo generaré imágenes a partir del ruido y el vector de integración y el discriminador tomará la imagen y el vector para identificar las falsificaciones:

 #texts has embedding vectors pics=np.array(pics) . #images noise = np.random.normal(0, 1, (batch_size, 100)) j=0 latent_code=[] for j in range(len(texts)): #appending embedding at the end of noise n=np.append(noise[j],texts[j]) n=n.tolist() latent_code.append(n) latent_code=np.array(latent_code) gen_imgs = generator.predict(latent_code) #gen making fakes j=0 vects=[] for im in gen_imgs: t=np.array(texts[j]) t=np.reshape(t,[128,3]) t=np.expand_dims(t, axis=0) vects.append(t) j+=1 vects=np.array(vects) #vector of ?,1,128,3 #disc marking fakes and reals d_loss_real = discriminator.train_on_batch([pics,vects], valid) d_loss_fake = discriminator.train_on_batch([gen_pics,vects], fake) d_loss = 0.5 * np.add(d_loss_real, d_loss_fake) g_loss = combined.train_on_batch(latent_code, valid) 

Se ha olvidado de agregar la temp como una de las entradas de la GAN (por eso el error dice que no puede alimentar el tensor correspondiente, ya que está esencialmente desconectado):

 combined = Model([z, temp], valid) 

Como nota al margen, recomiendo usar la API funcional de Keras para construir modelos de sucursales múltiples y complicados como su discriminador. Es mucho más fácil de usar, es más flexible y menos propenso a errores.

Por ejemplo, este es el descriminador que ha escrito, pero lo he reescrito usando la API funcional. Personalmente creo que es mucho más fácil de seguir:

 def build_discriminator(img_shape,embedding_shape): input_img = Input(shape=img_shape) x = Conv2D(32, kernel_size=5, strides=2, padding="same")(input_img) x = LeakyReLU(alpha=0.2)(x) x = Dropout(0.25)(x) x = Conv2D(48, kernel_size=5, strides=2, padding="same")(x) x = BatchNormalization(momentum=0.8)(x) x = LeakyReLU(alpha=0.2)(x) x = Dropout(0.25)(x) x = Conv2D(64, kernel_size=5, strides=2, padding="same")(x) x = BatchNormalization(momentum=0.8)(x) x = LeakyReLU(alpha=0.2)(x) x = Dropout(0.25)(x) x = Conv2D(128, kernel_size=5, strides=2, padding="same")(x) x = BatchNormalization(momentum=0.8)(x) x = LeakyReLU(alpha=0.2)(x) x = Dropout(0.25)(x) x = Conv2D(256, kernel_size=5, strides=2, padding="same")(x) x = BatchNormalization(momentum=0.8)(x) x = LeakyReLU(alpha=0.2)(x) x = Dropout(0.25)(x) x = Flatten()(x) output_img = Dense(200)(x) input_emb = Input(shape=embedding_shape) y = Dense(50)(input_emb) y = Dense(100)(y) y = Dense(200)(y) output_emb = Flatten()(y) merged = concatenate([output_img, output_emb]) output_merge = Dense(1, activation='sigmoid', name='output_layer')(merged) return Model([input_img, input_emb], output_merge)