zoukankan      html  css  js  c++  java
  • 通过DCGAN进行生成花朵

    环境是你要安装Keras和Tensorflow

    先来个network.py,里面定义了生成器网络和鉴别器网络:

     1 # -*- coding: UTF-8 -*-
     2 
     3 """
     4 DCGAN 深层卷积的生成对抗网络
     5 """
     6 
     7 import tensorflow as tf
     8 
     9 # Hyper parameter(超参数)
    10 EPOCHS = 100
    11 BATCH_SIZE = 128
    12 LEARNING_RATE = 0.0002
    13 BETA_1 = 0.5
    14 
    15 
    16 # 定义判别器模型
    17 def discriminator_model():
    18     model = tf.keras.models.Sequential()
    19 
    20     model.add(tf.keras.layers.Conv2D(
    21         64,  # 64 个过滤器,输出的深度(depth)是 64
    22         (5, 5),  # 过滤器在二维的大小是(5 * 5)
    23         padding='same',  # same 表示输出的大小不变,因此需要在外围补零2圈
    24         input_shape=(64, 64, 3)  # 输入形状 [64, 64, 3]。3 表示 RGB 三原色
    25     ))
    26     model.add(tf.keras.layers.Activation("tanh"))  # 添加 Tanh 激活层
    27     model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))  # 池化层
    28     model.add(tf.keras.layers.Conv2D(128, (5, 5)))
    29     model.add(tf.keras.layers.Activation("tanh"))
    30     model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))
    31     model.add(tf.keras.layers.Conv2D(128, (5, 5)))
    32     model.add(tf.keras.layers.Activation("tanh"))
    33     model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))
    34     model.add(tf.keras.layers.Flatten())  # 扁平化
    35     model.add(tf.keras.layers.Dense(1024))  # 1024 个神经元的全连接层
    36     model.add(tf.keras.layers.Activation("tanh"))
    37     model.add(tf.keras.layers.Dense(1))  # 1 个神经元的全连接层
    38     model.add(tf.keras.layers.Activation("sigmoid"))  # 添加 Sigmoid 激活层
    39 
    40     return model
    41 
    42 
    43 # 定义生成器模型
    44 # 从随机数来生成图片
    45 def generator_model():
    46     model = tf.keras.models.Sequential()
    47     # 输入的维度是 100, 输出维度(神经元个数)是1024 的全连接层
    48     model.add(tf.keras.layers.Dense(input_dim=100, units=1024))
    49     model.add(tf.keras.layers.Activation("tanh"))
    50     model.add(tf.keras.layers.Dense(128 * 8 * 8))  # 8192 个神经元的全连接层
    51     model.add(tf.keras.layers.BatchNormalization())  # 批标准化
    52     model.add(tf.keras.layers.Activation("tanh"))
    53     model.add(tf.keras.layers.Reshape((8, 8, 128), input_shape=(128 * 8 * 8, )))  # 8 x 8 像素
    54     model.add(tf.keras.layers.UpSampling2D(size=(2, 2)))  # 16 x 16像素
    55     model.add(tf.keras.layers.Conv2D(128, (5, 5), padding="same"))
    56     model.add(tf.keras.layers.Activation("tanh"))
    57     model.add(tf.keras.layers.UpSampling2D(size=(2, 2)))  # 32 x 32像素
    58     model.add(tf.keras.layers.Conv2D(128, (5, 5), padding="same"))
    59     model.add(tf.keras.layers.Activation("tanh"))
    60     model.add(tf.keras.layers.UpSampling2D(size=(2, 2)))  # 64 x 64像素
    61     model.add(tf.keras.layers.Conv2D(3, (5, 5), padding="same"))
    62     model.add(tf.keras.layers.Activation("tanh"))
    63 
    64     return model
    65 
    66 
    67 # 构造一个 Sequential 对象,包含一个 生成器 和一个 判别器
    68 # 输入 -> 生成器 -> 判别器 -> 输出
    69 def generator_containing_discriminator(generator, discriminator):
    70     model = tf.keras.models.Sequential()
    71     model.add(generator)
    72     discriminator.trainable = False  # 初始时 判别器 不可被训练
    73     model.add(discriminator)
    74     return model

    接着我们写个训练模型的文件,train..py

     1 # -*- coding: UTF-8 -*-
     2 
     3 """
     4 训练 DCGAN
     5 """
     6 
     7 import os
     8 import glob
     9 import numpy as np
    10 from scipy import misc
    11 import tensorflow as tf
    12 
    13 from network import *
    14 
    15 
    16 def train():
    17     # 确保包含所有图片的 images 文件夹在所有 Python 文件的同级目录下
    18     # 当然了,你也可以自定义文件夹名和路径
    19     if not os.path.exists("images"):
    20         raise Exception("包含所有图片的 images 文件夹不在此目录下,请添加")
    21 
    22     # 获取训练数据
    23     data = []
    24     for image in glob.glob("images/*"):
    25         image_data = misc.imread(image)  # imread 利用 PIL 来读取图片数据
    26         data.append(image_data)
    27     input_data = np.array(data)
    28 
    29     # 将数据标准化成 [-1, 1] 的取值, 这也是 Tanh 激活函数的输出范围
    30     input_data = (input_data.astype(np.float32) - 127.5) / 127.5
    31 
    32     # 构造 生成器 和 判别器
    33     g = generator_model()
    34     d = discriminator_model()
    35 
    36     # 构建 生成器 和 判别器 组成的网络模型
    37     d_on_g = generator_containing_discriminator(g, d)
    38 
    39     # 优化器用 Adam Optimizer
    40     g_optimizer = tf.keras.optimizers.Adam(lr=LEARNING_RATE, beta_1=BETA_1)
    41     d_optimizer = tf.keras.optimizers.Adam(lr=LEARNING_RATE, beta_1=BETA_1)
    42 
    43     # 配置 生成器 和 判别器
    44     g.compile(loss="binary_crossentropy", optimizer=g_optimizer)
    45     d_on_g.compile(loss="binary_crossentropy", optimizer=g_optimizer)
    46     d.trainable = True
    47     d.compile(loss="binary_crossentropy", optimizer=d_optimizer)
    48 
    49     # 开始训练
    50     for epoch in range(EPOCHS):
    51         for index in range(int(input_data.shape[0] / BATCH_SIZE)):
    52             input_batch = input_data[index * BATCH_SIZE : (index + 1) * BATCH_SIZE]
    53 
    54             # 连续型均匀分布的随机数据(噪声)
    55             random_data = np.random.uniform(-1, 1, size=(BATCH_SIZE, 100))
    56             # 生成器 生成的图片数据
    57             generated_images = g.predict(random_data, verbose=0)
    58 
    59             input_batch = np.concatenate((input_batch, generated_images))
    60             output_batch = [1] * BATCH_SIZE + [0] * BATCH_SIZE
    61 
    62             # 训练 判别器,让它具备识别不合格生成图片的能力
    63             d_loss = d.train_on_batch(input_batch, output_batch)
    64 
    65             # 当训练 生成器 时,让 判别器 不可被训练
    66             d.trainable = False
    67 
    68             # 重新生成随机数据。很关键
    69             random_data = np.random.uniform(-1, 1, size=(BATCH_SIZE, 100))
    70 
    71             # 训练 生成器,并通过不可被训练的 判别器 去判别
    72             g_loss = d_on_g.train_on_batch(random_data, [1] * BATCH_SIZE)
    73 
    74             # 恢复 判别器 可被训练
    75             d.trainable = True
    76 
    77             # 打印损失
    78             print("Epoch {}, 第 {} 步, 生成器的损失: {:.3f}, 判别器的损失: {:.3f}".format(epoch, index, g_loss, d_loss))
    79 
    80         # 保存 生成器 和 判别器 的参数
    81         # 大家也可以设置保存时名称不同(比如后接 epoch 的数字),参数文件就不会被覆盖了
    82         if epoch % 1 == 0:
    83             g.save_weights("./generator_weight.h5", True)
    84             d.save_weights("./discriminator_weight", True)
    85 
    86 
    87 if __name__ == "__main__":
    88     train()

    运行这个文件,就可以产生生成器网络的权重文件  generator_weight.h5, 这里我选择每个训练epoch都保存一次权重文件。你可以按你的喜好来。

      训练好了之后,那么我们就可以用generate.py文件,从随机数据生成好看的花朵了。

     1 # -*- coding: UTF-8 -*-
     2 
     3 """
     4 用 DCGAN 的生成器模型 和 训练得到的生成器参数文件 来生成图片
     5 """
     6 
     7 import numpy as np
     8 from PIL import Image
     9 import tensorflow as tf
    10 
    11 from network import *
    12 
    13 
    14 def generate():
    15     # 构造生成器
    16     g = generator_model()
    17 
    18     # 配置 生成器
    19     g.compile(loss="binary_crossentropy", optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE, beta_1=BETA_1))
    20 
    21     # 加载训练好的 生成器 参数
    22     g.load_weights("generator_weight.h5")
    23 
    24     # 连续型均匀分布的随机数据(噪声)
    25     random_data = np.random.uniform(-1, 1, size=(BATCH_SIZE, 100))
    26 
    27     # 用随机数据作为输入,生成器 生成图片数据
    28     images = g.predict(random_data, verbose=1)
    29 
    30     # 用生成的图片数据生成 PNG 图片
    31     for i in range(BATCH_SIZE):
    32         image = images[i] * 127.5 + 127.5
    33         Image.fromarray(image.astype(np.uint8)).save("./generated_image/image-%s.png" % i)
    34 
    35 
    36 if __name__ == "__main__":
    37     generate()

    附注1: 一些训练过程

    C:ProgramDataAnaconda3python.exe D:/threeTFproject/Case2_AI_Photoshop/train.py
    C:ProgramDataAnaconda3libsite-packagesh5py__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
      from ._conv import register_converters as _register_converters
    2018-11-01 09:29:35.205667: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
    Epoch 0, 第 0 步, 生成器的损失: 0.169, 判别器的损失: 0.732
    Epoch 0, 第 1 步, 生成器的损失: 0.258, 判别器的损失: 0.577
    Epoch 0, 第 2 步, 生成器的损失: 0.680, 判别器的损失: 0.534
    Epoch 0, 第 3 步, 生成器的损失: 1.493, 判别器的损失: 0.451
    Epoch 0, 第 4 步, 生成器的损失: 1.484, 判别器的损失: 0.513
    Epoch 0, 第 5 步, 生成器的损失: 2.465, 判别器的损失: 0.350
    Epoch 0, 第 6 步, 生成器的损失: 4.008, 判别器的损失: 0.313
    Epoch 0, 第 7 步, 生成器的损失: 2.139, 判别器的损失: 0.494
    Epoch 0, 第 8 步, 生成器的损失: 2.939, 判别器的损失: 0.501
    Epoch 0, 第 9 步, 生成器的损失: 3.805, 判别器的损失: 0.415
    Epoch 0, 第 10 步, 生成器的损失: 3.413, 判别器的损失: 0.590
    Epoch 0, 第 11 步, 生成器的损失: 2.520, 判别器的损失: 0.486
    Epoch 0, 第 12 步, 生成器的损失: 2.286, 判别器的损失: 0.471
    Epoch 0, 第 13 步, 生成器的损失: 1.228, 判别器的损失: 0.670
    Epoch 0, 第 14 步, 生成器的损失: 0.561, 判别器的损失: 0.655
    Epoch 0, 第 15 步, 生成器的损失: 0.560, 判别器的损失: 0.517
    Epoch 0, 第 16 步, 生成器的损失: 0.643, 判别器的损失: 0.490
    Epoch 0, 第 17 步, 生成器的损失: 0.727, 判别器的损失: 0.488
    Epoch 0, 第 18 步, 生成器的损失: 1.003, 判别器的损失: 0.734
    Epoch 0, 第 19 步, 生成器的损失: 1.235, 判别器的损失: 0.379
    Epoch 0, 第 20 步, 生成器的损失: 1.869, 判别器的损失: 0.377
    Epoch 0, 第 21 步, 生成器的损失: 2.073, 判别器的损失: 0.384
    Epoch 0, 第 22 步, 生成器的损失: 1.185, 判别器的损失: 0.613
    WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x0000019D240A8BA8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.
    
    Consider using a TensorFlow optimizer from `tf.train`.
    Epoch 1, 第 0 步, 生成器的损失: 2.079, 判别器的损失: 0.590
    Epoch 1, 第 1 步, 生成器的损失: 1.161, 判别器的损失: 0.506
    Epoch 1, 第 2 步, 生成器的损失: 1.137, 判别器的损失: 0.451
    Epoch 1, 第 3 步, 生成器的损失: 1.538, 判别器的损失: 0.346
    Epoch 1, 第 4 步, 生成器的损失: 1.733, 判别器的损失: 0.362
    Epoch 1, 第 5 步, 生成器的损失: 2.059, 判别器的损失: 0.275
    Epoch 1, 第 6 步, 生成器的损失: 2.376, 判别器的损失: 0.243
    Epoch 1, 第 7 步, 生成器的损失: 2.260, 判别器的损失: 0.300
    Epoch 1, 第 8 步, 生成器的损失: 3.750, 判别器的损失: 0.240
    Epoch 1, 第 9 步, 生成器的损失: 3.422, 判别器的损失: 0.222
    Epoch 1, 第 10 步, 生成器的损失: 4.694, 判别器的损失: 0.275
    Epoch 1, 第 11 步, 生成器的损失: 2.299, 判别器的损失: 0.411
    Epoch 1, 第 12 步, 生成器的损失: 4.065, 判别器的损失: 0.547
    Epoch 1, 第 13 步, 生成器的损失: 1.834, 判别器的损失: 0.470
    Epoch 1, 第 14 步, 生成器的损失: 0.398, 判别器的损失: 1.344
    Epoch 1, 第 15 步, 生成器的损失: 1.134, 判别器的损失: 0.973
    Epoch 1, 第 16 步, 生成器的损失: 2.866, 判别器的损失: 0.374
    Epoch 1, 第 17 步, 生成器的损失: 1.056, 判别器的损失: 0.767
    Epoch 1, 第 18 步, 生成器的损失: 0.916, 判别器的损失: 0.603
    Epoch 1, 第 19 步, 生成器的损失: 1.151, 判别器的损失: 0.645
    Epoch 1, 第 20 步, 生成器的损失: 1.947, 判别器的损失: 0.411
    Epoch 1, 第 21 步, 生成器的损失: 3.122, 判别器的损失: 0.314
    Epoch 1, 第 22 步, 生成器的损失: 1.805, 判别器的损失: 0.642
    WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x0000019D240A8BA8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.
    
    Consider using a TensorFlow optimizer from `tf.train`.
    Epoch 2, 第 0 步, 生成器的损失: 1.240, 判别器的损失: 0.569
    Epoch 2, 第 1 步, 生成器的损失: 1.151, 判别器的损失: 0.449
    Epoch 2, 第 2 步, 生成器的损失: 1.395, 判别器的损失: 0.332
    Epoch 2, 第 3 步, 生成器的损失: 1.649, 判别器的损失: 0.258
    Epoch 2, 第 4 步, 生成器的损失: 1.777, 判别器的损失: 0.277
    Epoch 2, 第 5 步, 生成器的损失: 1.562, 判别器的损失: 0.268
    Epoch 2, 第 6 步, 生成器的损失: 2.229, 判别器的损失: 0.224
    Epoch 2, 第 7 步, 生成器的损失: 2.432, 判别器的损失: 0.272
    Epoch 2, 第 8 步, 生成器的损失: 4.502, 判别器的损失: 0.229
    Epoch 2, 第 9 步, 生成器的损失: 4.549, 判别器的损失: 0.211
    Epoch 2, 第 10 步, 生成器的损失: 4.481, 判别器的损失: 0.263
    Epoch 2, 第 11 步, 生成器的损失: 3.766, 判别器的损失: 0.423
    Epoch 2, 第 12 步, 生成器的损失: 2.195, 判别器的损失: 0.562
    Epoch 2, 第 13 步, 生成器的损失: 1.682, 判别器的损失: 2.144
    Epoch 2, 第 14 步, 生成器的损失: 0.911, 判别器的损失: 0.543
    Epoch 2, 第 15 步, 生成器的损失: 0.301, 判别器的损失: 0.342
    Epoch 2, 第 16 步, 生成器的损失: 0.159, 判别器的损失: 0.429
    Epoch 2, 第 17 步, 生成器的损失: 0.208, 判别器的损失: 0.392
    Epoch 2, 第 18 步, 生成器的损失: 0.241, 判别器的损失: 0.390
    Epoch 2, 第 19 步, 生成器的损失: 0.826, 判别器的损失: 0.224
    Epoch 2, 第 20 步, 生成器的损失: 1.065, 判别器的损失: 0.204
    Epoch 2, 第 21 步, 生成器的损失: 0.824, 判别器的损失: 0.226
    Epoch 2, 第 22 步, 生成器的损失: 4.178, 判别器的损失: 0.579
    WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x0000019D240A8BA8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.
    
    Consider using a TensorFlow optimizer from `tf.train`.
    Epoch 3, 第 0 步, 生成器的损失: 0.122, 判别器的损失: 0.613
    Epoch 3, 第 1 步, 生成器的损失: 1.310, 判别器的损失: 0.799
    Epoch 3, 第 2 步, 生成器的损失: 1.949, 判别器的损失: 0.168
    Epoch 3, 第 3 步, 生成器的损失: 1.606, 判别器的损失: 0.167
    Epoch 3, 第 4 步, 生成器的损失: 1.433, 判别器的损失: 0.281
    Epoch 3, 第 5 步, 生成器的损失: 1.427, 判别器的损失: 0.323
    Epoch 3, 第 6 步, 生成器的损失: 2.604, 判别器的损失: 0.292
    Epoch 3, 第 7 步, 生成器的损失: 2.925, 判别器的损失: 0.377
    Epoch 3, 第 8 步, 生成器的损失: 4.519, 判别器的损失: 0.292
    Epoch 3, 第 9 步, 生成器的损失: 4.978, 判别器的损失: 0.415
    Epoch 3, 第 10 步, 生成器的损失: 5.062, 判别器的损失: 0.506
    Epoch 3, 第 11 步, 生成器的损失: 2.873, 判别器的损失: 0.648
    Epoch 3, 第 12 步, 生成器的损失: 3.078, 判别器的损失: 0.610
    Epoch 3, 第 13 步, 生成器的损失: 2.059, 判别器的损失: 0.783
    Epoch 3, 第 14 步, 生成器的损失: 0.750, 判别器的损失: 1.088
    Epoch 3, 第 15 步, 生成器的损失: 1.064, 判别器的损失: 0.898
    Epoch 3, 第 16 步, 生成器的损失: 0.329, 判别器的损失: 0.714
    Epoch 3, 第 17 步, 生成器的损失: 0.133, 判别器的损失: 0.446
    Epoch 3, 第 18 步, 生成器的损失: 0.401, 判别器的损失: 0.476
    Epoch 3, 第 19 步, 生成器的损失: 0.419, 判别器的损失: 0.374
    Epoch 3, 第 20 步, 生成器的损失: 0.960, 判别器的损失: 0.225
    Epoch 3, 第 21 步, 生成器的损失: 1.431, 判别器的损失: 0.203
    Epoch 3, 第 22 步, 生成器的损失: 1.061, 判别器的损失: 0.717
    WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x0000019D240A8BA8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.
    
    Consider using a TensorFlow optimizer from `tf.train`.
    Epoch 4, 第 0 步, 生成器的损失: 2.778, 判别器的损失: 0.743
    Epoch 4, 第 1 步, 生成器的损失: 0.179, 判别器的损失: 0.724
    Epoch 4, 第 2 步, 生成器的损失: 2.880, 判别器的损失: 0.836
    Epoch 4, 第 3 步, 生成器的损失: 2.585, 判别器的损失: 0.290
    Epoch 4, 第 4 步, 生成器的损失: 2.781, 判别器的损失: 0.339
    Epoch 4, 第 5 步, 生成器的损失: 2.925, 判别器的损失: 0.517
    Epoch 4, 第 6 步, 生成器的损失: 5.254, 判别器的损失: 0.537

     

     附注2:这是train了一个epoch的generate_weight.ht拿来给generate.py生成花朵用的,效果如下:

    用34 epoch的generate_weight.ht试试,效果如下:

    如果你epoch到200以上,那么就可以看到如下的效果:

  • 相关阅读:
    api接口安全
    php读取大文件
    thinkphp5.0的工作流程
    php扩展包索引
    redis学习之持久化与内存淘汰机制
    mysql优化之分区
    简练软考知识点整理-控制干系人参与
    简练软考知识点整理-控制干系人参与
    简练软考知识点整理-管理干系人参与
    简练软考知识点整理-管理干系人参与
  • 原文地址:https://www.cnblogs.com/www-caiyin-com/p/9889502.html
Copyright © 2011-2022 走看看