【问题标题】:Runtime Error: Disconnected graph for GANs because input can't be obtained运行时错误:GAN 的图断开连接,因为无法获得输入
【发布时间】:2018-12-15 02:59:27
【问题描述】:

这是我的鉴别器架构:

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)

这里是生成器架构:

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)

这是我制作 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)

判别器有 2 个模型,将得到一个形状为 128x128x3 的图像和一个形状为 1x128x3 的嵌入图像,然后将两个模型合并。生成器模型只是得到噪声并生成128x128x3 图像。所以在combined = Model(z, valid) 行,我收到以下错误:

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']

我认为这是因为鉴别器找不到嵌入输入,但我给它输入了一个形状为 (1,128,3) 的张量,就像将噪声输入到生成器模型一样。谁能帮我看看我哪里做错了?

在这里设置完所有内容后,我将如何从合并在一起的噪声和嵌入向量中生成图像,鉴别器将获取图像和向量来识别假货:

#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)

【问题讨论】:

    标签: python tensorflow keras deep-learning generative-adversarial-network


    【解决方案1】:

    您忘记将temp 添加为 GAN 的输入之一(这就是为什么错误说它无法提供相应的张量,因为它本质上是断开的):

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

    作为旁注,我强烈建议使用Keras Functional API 来构建复杂的多分支模型,例如您的鉴别器。它更易于使用、更灵活且不易出错。

    例如,这是您编写的描述符,但我已使用函数式 API 对其进行了重写。我个人认为它更容易理解:

    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)
    

    【讨论】:

    • 我不敢相信我做了这么愚蠢的事情:/ 非常感谢。
    • 另外,“combined = Model([z, temp], valid)” 似乎有点奇怪,因为我正在添加噪声和嵌入来生成“z”,那么 temp 需要什么? temp 仅在光盘中使用。 “combined = Model(z, valid)”不是更有意义吗?
    • @Asim temp 是一个输入层。所以它必须以某种方式在你的 GAN 中输入。因此,根据您实现架构的方式,您必须明确地将其作为模型的输入,否则它不会连接到任何东西,因此无法输入。
    • 哦,好吧,我的问题已经解决了,但是架构很奇怪,现在会解决这个问题。
    • 我想要“combined = Model(z, valid)”,并将嵌入仅用于鉴别器而不是 gen,并且 gen 将 jyst 具有 484 的 z,即与嵌入连接的噪声。我能以某种方式做到这一点吗?所以 disc 将有一个合并模型,就像你上面描述的那样,GEN 有一个简单的 484 输入传统 GEN 模型,组合的“combined = Model(z, valid)”保持这样。我可以这样做吗?
    猜你喜欢
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 2016-11-07
    • 2021-12-14
    • 2014-05-13
    • 2014-06-06
    相关资源
    最近更新 更多