MacBook 上生成对抗网络 (GAN) 的 python/keras 实现存在问题

问题描述 投票:0回答:1

我对 keras 和生成对抗网络(GAN)非常陌生。当我尝试在 MacBook 上运行这个脚本来构建一个简单的 GAN 时,我得到了:

Traceback (most recent call last):
  File "~/Library/CloudStorage/Dropbox/programming/python_image_learning/./248-cifar_GAN.py", line 240, in <module>
    train(generator, discriminator, gan_model, dataset, latent_dim, n_epochs=2)
  File "~/Library/CloudStorage/Dropbox/programming/python_image_learning/./248-cifar_GAN.py", line 195, in train
    d_loss_real, _ = d_model.train_on_batch(X_real, y_real) 
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/miniconda3/envs/pyimage/lib/python3.12/site-packages/keras/src/backend/tensorflow/trainer.py", line 549, in train_on_batch
    logs = self.train_function(data())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/miniconda3/envs/pyimage/lib/python3.12/site-packages/tensorflow/python/util/traceback_utils.py", line 153, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "~/miniconda3/envs/pyimage/lib/python3.12/site-packages/keras/src/backend/tensorflow/trainer.py", line 121, in one_step_on_iterator
    outputs = self.distribute_strategy.run(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/miniconda3/envs/pyimage/lib/python3.12/site-packages/keras/src/backend/tensorflow/trainer.py", line 108, in one_step_on_data
    return self.train_step(data)
           ^^^^^^^^^^^^^^^^^^^^^
  File "~/miniconda3/envs/pyimage/lib/python3.12/site-packages/keras/src/backend/tensorflow/trainer.py", line 61, in train_step
    self._loss_tracker.update_state(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'update_state'

当我尝试其他脚本时,我遇到了同样的错误。 然而,这些脚本在 Google Colab 上运行良好,让我推测我本地的编码环境出了问题:

MacBook Pro 16-in, 2019
Bash shell
conda 24.9.2
Python 3.12.7
tensorflow 2.16.2
keras 3.6.0

尽管如此,我也知道简单的 CNN 或 Unet(例如 this)在我的笔记本电脑上运行良好,因此问题似乎是在这种环境中生成器和判别器之间的连接。我尝试连接生成器和鉴别器,但解决这个问题的唯一方法是将鉴别器的输入层设置为生成器输出的克隆,如下所示:

generator_inputs = Input(shape = (100, ))
G1d1, G1l1, G1n1 = dense_leak_norm(parents = generator_inputs, input_shape = (100, ))
G2d1, G2l1, G2n1 = dense_leak_norm(parents = G1n1, units = 512)
G3d1, G3l1, G3n1 = dense_leak_norm(parents = G2n1, units = 1024)
G4d1 = Dense(np.prod(img_shape), activation = "tanh")(G3n1)
generator_outputs = Reshape(img_shape)(G4d1)
generator = Model(inputs = generator_inputs, outputs = generator_outputs)

# This line is required to evade the error
discriminator_inputs = generator_outputs
# If discriminator_inputs is defined using the line below, same error is reproduced
#discriminator_inputs = Input(shape = img_shape)
D1f1 = Flatten(input_shape = img_shape)(discriminator_inputs)
D1d1, D1l1 = dense_leak_norm(parents = D1f1, units = 512, bool_norm = False)
D2d1, D2l1 = dense_leak_norm(parents = D1l1, units = 256, bool_norm = False)
discriminator_outputs = Dense(units = 1, activation = "sigmoid")(D2l1)
discriminator = Model(inputs = discriminator_inputs, outputs = discriminator_outputs)
discriminator.compile(loss = "binary_crossentropy", optimizer = optimizer, metrics = ["accuracy"])

combined = Model(generator_inputs, discriminator_outputs)

正如我们在

discriminator.summary()
中看到的,InputLayer 是生成器输出的克隆:

Layer (type)                         ┃ Output Shape                ┃         Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ keras_tensor_11CLONE (InputLayer)    │ (None, 28, 28, 1)           │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ flatten (Flatten)                    │ (None, 784)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_4 (Dense)                      │ (None, 512)                 │         401,920 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ leaky_re_lu_3 (LeakyReLU)            │ (None, 512)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_5 (Dense)                      │ (None, 256)                 │         131,328 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ leaky_re_lu_4 (LeakyReLU)            │ (None, 256)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_6 (Dense)                      │ (None, 1)                   │             257 │

但显然,GAN 模型不会以这种方式训练。

知道发生了什么事吗?

python tensorflow keras conda generative-adversarial-network
1个回答
0
投票

在Image.sc论坛上询问了我的问题后,我发现如果我将keras从3.6.0降级到3.4.1(Google Colab版本),问题就可以解决。

然而,坏消息是出现了新的bug。当我设定

discriminator.compile(loss = "binary_crossentropy", optimizer = Adam(learning_rate = 0.0002, beta_1 = 0.5), metrics = ["accuracy"])
# Set non-trainable after compiling discriminator
discriminator.trainable = False
即使在关闭

trainable 标签之前已进行

 编译,并且之后不再重新编译判别器 
判别器仍然不可训练。关闭可训练标志前后请参考 discriminator.summary()

discriminator.summary before freezing
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type)                         ┃ Output Shape                ┃         Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ input_layer_1 (InputLayer)           │ (None, 28, 28, 1)           │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ flatten (Flatten)                    │ (None, 784)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_4 (Dense)                      │ (None, 512)                 │         401,920 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ leaky_re_lu_3 (LeakyReLU)            │ (None, 512)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_5 (Dense)                      │ (None, 256)                 │         131,328 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ leaky_re_lu_4 (LeakyReLU)            │ (None, 256)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_6 (Dense)                      │ (None, 1)                   │             257 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
 Total params: 533,505 (2.04 MB)
 Trainable params: 533,505 (2.04 MB)
 Non-trainable params: 0 (0.00 B)
discriminator.summary after freezing but no recompile
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type)                         ┃ Output Shape                ┃         Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ input_layer_1 (InputLayer)           │ (None, 28, 28, 1)           │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ flatten (Flatten)                    │ (None, 784)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_4 (Dense)                      │ (None, 512)                 │         401,920 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ leaky_re_lu_3 (LeakyReLU)            │ (None, 512)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_5 (Dense)                      │ (None, 256)                 │         131,328 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ leaky_re_lu_4 (LeakyReLU)            │ (None, 256)                 │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_6 (Dense)                      │ (None, 1)                   │             257 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
 Total params: 533,505 (2.04 MB)
 Trainable params: 0 (0.00 B)
 Non-trainable params: 533,505 (2.04 MB)

有很多关于此标签工作异常的报告 GitHub 讨论 另一个 GitHub 讨论 为了避免这个问题,我必须在训练判别器之前将其设置为可训练,然后在每个纪元周期中训练整个 GAN 之前将其关闭

discriminator.trainable = True
discriminator.train_on_batch(x = realhalf, y = np.ones((half_size, 1)))
discriminator.trainable = False
combined.train_on_batch(np.random.normal(0, 1, (batch_size, 100)), np.array([1] * batch_size))

但老实说,我觉得使用这些软件包有点不安全,因为这个错误从大约十年前就已经存在了。我做了一个简短的搜索,有些人推荐使用 PyTorch(Rededit 讨论)?如果有人知道这些软件包,请随时告诉我。预先感谢!

© www.soinside.com 2019 - 2024. All rights reserved.