生成对抗网络应用DCGAN,使用DCGAN完成动漫头像的生成,并保存每一轮的生成结果图像
时间: 2023-12-25 11:05:26 浏览: 34
好的,下面是使用DCGAN完成动漫头像生成的步骤:
1. 数据集准备
首先需要准备一些动漫头像的数据集,可以从网上下载或者自己收集,这里推荐使用著名的动漫头像数据集Anime Face Dataset。
2. 网络架构设计
DCGAN 是一种生成对抗网络,包含生成器和判别器两个部分。生成器通过输入噪声向量生成一张图像,判别器则从真实数据集和生成器产生的数据中判断哪些是真实的图像,哪些是生成的图像。
生成器的架构一般采用反卷积层,以将噪声向量转化为一张图像。具体来说,生成器一般采用以下架构:
```
generator = Sequential([
Dense(4*4*256, input_shape=(latent_dim,)),
Reshape((4, 4, 256)),
Conv2DTranspose(128, (4,4), strides=(2,2), padding='same', activation='relu'),
Conv2DTranspose(64, (4,4), strides=(2,2), padding='same', activation='relu'),
Conv2DTranspose(3, (4,4), strides=(2,2), padding='same', activation='tanh')
])
```
判别器的架构一般采用卷积层,以将输入的图像转化为一个概率值。具体来说,判别器一般采用以下架构:
```
discriminator = Sequential([
Conv2D(64, (4,4), strides=(2,2), padding='same', input_shape=(64,64,3)),
LeakyReLU(alpha=0.2),
Conv2D(128, (4,4), strides=(2,2), padding='same'),
BatchNormalization(),
LeakyReLU(alpha=0.2),
Conv2D(256, (4,4), strides=(2,2), padding='same'),
BatchNormalization(),
LeakyReLU(alpha=0.2),
Flatten(),
Dense(1, activation='sigmoid')
])
```
3. 训练模型
训练模型的过程可以分为以下几步:
- 将原始图像缩放到相同大小,以便于输入到网络中。
- 将噪声向量输入到生成器中,生成一张图像。
- 将真实数据和生成的数据输入到判别器中,计算损失函数。
- 使用反向传播算法更新生成器和判别器的权重。
训练代码如下所示:
```
from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Input, Dense, Reshape, Flatten, Dropout, Conv2D, Conv2DTranspose, LeakyReLU, BatchNormalization
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.optimizers import Adam
import numpy as np
import matplotlib.pyplot as plt
import os
# 定义超参数
img_rows = 64
img_cols = 64
channels = 3
latent_dim = 100
batch_size = 32
epochs = 20000
sample_interval = 100
# 加载数据集
dataset_path = 'anime_faces'
data = []
for img in os.listdir(dataset_path):
img_path = os.path.join(dataset_path, img)
img = plt.imread(img_path)
data.append(img)
X_train = np.array(data)
X_train = (X_train.astype(np.float32) - 127.5) / 127.5
# 定义生成器模型
generator = Sequential([
Dense(4*4*256, input_shape=(latent_dim,)),
Reshape((4, 4, 256)),
Conv2DTranspose(128, (4,4), strides=(2,2), padding='same', activation='relu'),
Conv2DTranspose(64, (4,4), strides=(2,2), padding='same', activation='relu'),
Conv2DTranspose(3, (4,4), strides=(2,2), padding='same', activation='tanh')
])
# 定义判别器模型
discriminator = Sequential([
Conv2D(64, (4,4), strides=(2,2), padding='same', input_shape=(64,64,3)),
LeakyReLU(alpha=0.2),
Conv2D(128, (4,4), strides=(2,2), padding='same'),
BatchNormalization(),
LeakyReLU(alpha=0.2),
Conv2D(256, (4,4), strides=(2,2), padding='same'),
BatchNormalization(),
LeakyReLU(alpha=0.2),
Flatten(),
Dense(1, activation='sigmoid')
])
# 编译判别器模型
discriminator.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5), metrics=['accuracy'])
# 冻结判别器的权重
discriminator.trainable = False
# 定义组合模型
gan_input = Input(shape=(latent_dim,))
gan_output = discriminator(generator(gan_input))
gan = Model(gan_input, gan_output)
gan.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5))
# 训练模型
real = np.ones((batch_size, 1))
fake = np.zeros((batch_size, 1))
for epoch in range(epochs):
# 随机选择一个批次的真实数据
idx = np.random.randint(0, X_train.shape[0], batch_size)
real_imgs = X_train[idx]
# 生成噪声向量
noise = np.random.normal(0, 1, (batch_size, latent_dim))
# 使用生成器生成一批假图像
fake_imgs = generator.predict(noise)
# 训练判别器
d_loss_real = discriminator.train_on_batch(real_imgs, real)
d_loss_fake = discriminator.train_on_batch(fake_imgs, fake)
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# 训练生成器
g_loss = gan.train_on_batch(noise, real)
# 每隔一定轮次保存一下生成的图像
if epoch % sample_interval == 0:
print("Epoch %d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100*d_loss[1], g_loss))
sample_images(epoch, generator)
def sample_images(epoch, generator):
r, c = 5, 5
noise = np.random.normal(0, 1, (r * c, latent_dim))
gen_imgs = generator.predict(noise)
# 将生成的图像保存到本地
gen_imgs = 0.5 * gen_imgs + 0.5
fig, axs = plt.subplots(r, c)
cnt = 0
for i in range(r):
for j in range(c):
axs[i,j].imshow(gen_imgs[cnt, :,:,:])
axs[i,j].axis('off')
cnt += 1
fig.savefig("images/anime_%d.png" % epoch)
plt.close()
```
在训练过程中,我们使用了一个 sample_images 函数来保存每一轮生成的图像,方便我们观察模型的训练效果。
4. 结果展示
训练完成后,我们可以使用以下代码来生成一些新的动漫头像:
```
# 加载训练好的生成器模型
generator = tf.keras.models.load_model('generator.h5')
# 生成新的动漫头像
r, c = 5, 5
noise = np.random.normal(0, 1, (r * c, latent_dim))
gen_imgs = generator.predict(noise)
# 可视化生成的图像
gen_imgs = 0.5 * gen_imgs + 0.5
fig, axs = plt.subplots(r, c)
cnt = 0
for i in range(r):
for j in range(c):
axs[i,j].imshow(gen_imgs[cnt, :,:,:])
axs[i,j].axis('off')
cnt += 1
plt.show()
```
运行以上代码即可生成新的动漫头像。