目录

在上篇博客(AN网络之入门教程(四)之基于DCGAN动漫头像生成)中,介绍了基于DCGAN的动漫头像生成,时隔几月,序属三秋,在这篇博客中,将介绍如何使用条件GAN网络(conditional GAN)生成符合需求的图片。

做成的效果图如下所示,“一键起飞”

项目地址:Github

在阅读这篇博客之前,首先得先对GAN和DCGAN有一部分的了解,如果对GAN不是很了解的话,建议先去了解GAN网络,或者也可以参考一下我之前的博客系列

相比较于普通的GAN网络,cgan在网络结构上发生了一些改变,与GAN网络相比,在Input layer添加了一个\(Y\)的标签,其代表图片的属性标签——在Minst数据集中,标签即代表着手写数字为几(如7,3),而在动漫头像数据集中,标签可以表示为头发的颜色,或者眼睛的颜色(当然为其他的属性特征也是的)。

在\(G\)网络中,Generator可以根据给的\(z\) (latent noise)和 \(y\) 生成相对应的图片,而\(D\)网络可以根据给的\(x\)(比如说图片)和 \(Y\) 进行评判。下图便是一个CGAN网络的简单示意图。

在这篇博客中,使用的框架:

  • Keras version:2.3.1

Prepare

首先的首先,我们需要数据集,里面既需要包括动漫头像的图片,也需要有每一张图片所对应的标签数据。这里我们使用Anime-Face-ACGAN中提供的图片数据集和标签数据集,当然,在我的Github中也提供了数据集的下载(其中,我的数据集对图片进行了清洗,将没有相对应标签的图片进行了删除)。

部分图片数据如下所示:

在tags_clean.csv 中,数据形式如下图所示,每一行代表的是相对应图片的标签数据。第一个数据为ID,同时也是图片的文件名字,后面的数据即为图片的特征数据

这里我们需要标签属性的仅仅为eyes的颜色数据和hair的颜色数据,应注意的是在csv中存在某一些图片没有这些数据(如第0个数据)。

以上便将这次所需要的数据集介绍完了,下面将简单的介绍一下数据集的加载。

加载数据集

首先我们先进行加载数据集,一共需要加载两个数据集,一个是图片数据集合,一个是标签数据集合。在标签数据集中,我们需要的是眼睛的颜色头发的颜色。在数据集中,一共分别有12种头发的颜色和11种眼睛的颜色。

  1. # 头发的种类
  2. HAIRS = ['orange hair', 'white hair', 'aqua hair', 'gray hair', 'green hair', 'red hair', 'purple hair', 'pink hair','blue hair', 'black hair', 'brown hair', 'blonde hair']
  3. # 眼睛的种类
  4. EYES = ['gray eyes', 'black eyes', 'orange eyes', 'pink eyes', 'yellow eyes', 'aqua eyes', 'purple eyes', 'green eyes','brown eyes', 'red eyes', 'blue eyes']

接下来加载数据集,在这个操作中,我们提取出csv中的hair和eye的颜色并得到相对应的id,然后将其保存到numpy数组中。

  1. # 加载标签数据
  2. import numpy as np
  3. import csv
  4. with open('tags_clean.csv', 'r') as file:
  5. lines = csv.reader(file, delimiter=',')
  6. y_hairs = []
  7. y_eyes = []
  8. y_index = []
  9. for i, line in enumerate(lines):
  10. # id 对应的是图片的名字
  11. idx = line[0]
  12. # tags 代表图片的所有特征(有hair,eyes,doll等等,当时我们只关注eye 和 hari)
  13. tags = line[1]
  14. tags = tags.split('\t')[:-1]
  15. y_hair = []
  16. y_eye = []
  17. for tag in tags:
  18. tag = tag[:tag.index(':')]
  19. if (tag in HAIRS):
  20. y_hair.append(HAIRS.index(tag))
  21. if (tag in EYES):
  22. y_eye.append(EYES.index(tag))
  23. # 如果同时存在hair 和 eye标签就代表这个标签是有用标签。
  24. if (len(y_hair) == 1 and len(y_eye) == 1):
  25. y_hairs.append(y_hair)
  26. y_eyes.append(y_eye)
  27. y_index.append(idx)
  28. y_eyes = np.array(y_eyes)
  29. y_hairs = np.array(y_hairs)
  30. y_index = np.array(y_index)
  31. print("一种有{0}个有用的标签".format(len(y_index)))

通过上述的操作,我们就提取出了在csv文件中同时存在eye颜色hair颜色标签的数据了。并保存了所对应图片的id数据

接下来我们就是根据id数据去读取出相对应的图片了,其中,所有的图片均为(64,64,3)的RGB图片,并且图片的保存位置为/faces

  1. import os
  2. import cv2
  3. # 创建数据集images_data
  4. images_data = np.zeros((len(y_index), 64, 64, 3))
  5. # 从本地文件读取图片加载到images_data中。
  6. for index,file_index in enumerate (y_index):
  7. images_data[index] = cv2.cvtColor(
  8. cv2.resize(
  9. cv2.imread(os.path.join("faces", str(file_index) + '.jpg'), cv2.IMREAD_COLOR),
  10. (64, 64)),cv2.COLOR_BGR2RGB
  11. )

接下来将图片进行归一化(一般来说都需要将图片进行归一化提高收敛的速度):

  1. images_data = (images_data / 127.5) - 1

通过以上的操作,我们就将数据导入内存中了,因为这个数据集比较小,因此将其全部导入到内存中是完全的。

构建网络

first of all,我们将我们需要的库导入:

  1. from keras.layers import Input, Dense, Reshape, Flatten, Dropout, multiply, Activation
  2. from keras.layers import BatchNormalization, Activation, Embedding, ZeroPadding2D
  3. from keras.layers import Conv2D, Conv2DTranspose, Dropout, UpSampling2D, MaxPooling2D,Concatenate
  4. from keras.layers.advanced_activations import LeakyReLU
  5. from keras.models import Sequential, Model, load_model
  6. from keras.optimizers import SGD, Adam, RMSprop
  7. from keras.utils import to_categorical,plot_model
  8. import matplotlib.pyplot as plt
  9. import matplotlib.gridspec as gridspec

构建Generator

关于G网络的模型图如下所示,而代码便是按照如下的模型图来构建网络模型:

  • Input:头发的颜色,眼睛的颜色,100维的高斯噪声。
  • Output:(64,64,3)的RGB图片。

构建模型图的代码:


  1. def build_generator_model(noise_dim, hair_num_class, eye_num_class):
  2. """
  3. 定义generator的生成方法
  4. :param noise_dim: 噪声的维度
  5. :param hair_num_class: hair标签的种类个数
  6. :param eye_num_class: eye标签的种类个数
  7. :return: generator
  8. """
  9. # kernel初始化模式
  10. kernel_init = 'glorot_uniform'
  11. model = Sequential(name='generator')
  12. model.add(Reshape((1, 1, -1), input_shape=(noise_dim + 16,)))
  13. model.add(Conv2DTranspose(filters=512, kernel_size=(4, 4), strides=(1, 1), padding="valid",
  14. data_format="channels_last", kernel_initializer=kernel_init, ))
  15. model.add(BatchNormalization(momentum=0.5))
  16. model.add(LeakyReLU(0.2))
  17. model.add(Conv2DTranspose(filters=256, kernel_size=(4, 4), strides=(2, 2), padding="same",
  18. data_format="channels_last", kernel_initializer=kernel_init))
  19. model.add(BatchNormalization(momentum=0.5))
  20. model.add(LeakyReLU(0.2))
  21. model.add(Conv2DTranspose(filters=128, kernel_size=(4, 4), strides=(2, 2), padding="same",
  22. data_format="channels_last", kernel_initializer=kernel_init))
  23. model.add(BatchNormalization(momentum=0.5))
  24. model.add(LeakyReLU(0.2))
  25. model.add(Conv2DTranspose(filters=64, kernel_size=(4, 4), strides=(2, 2), padding="same",
  26. data_format="channels_last", kernel_initializer=kernel_init))
  27. model.add(BatchNormalization(momentum=0.5))
  28. model.add(LeakyReLU(0.2))
  29. model.add(Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding="same", data_format="channels_last",
  30. kernel_initializer=kernel_init))
  31. model.add(BatchNormalization(momentum=0.5))
  32. model.add(LeakyReLU(0.2))
  33. model.add(Conv2DTranspose(filters=3, kernel_size=(4, 4), strides=(2, 2), padding="same",
  34. data_format="channels_last", kernel_initializer=kernel_init))
  35. model.add(Activation('tanh'))
  36. latent = Input(shape=(noise_dim,))
  37. eyes_class = Input(shape=(1,), dtype='int32')
  38. hairs_class = Input(shape=(1,), dtype='int32')
  39. hairs = Flatten()(Embedding(hair_num_class, 8, init='glorot_normal')(hairs_class))
  40. eyes = Flatten()(Embedding(eye_num_class, 8, init='glorot_normal')(eyes_class))
  41. # 连接模型的输入
  42. con = Concatenate()([latent, hairs, eyes])
  43. # 模型的输出
  44. fake_image = model(con)
  45. # 创建模型
  46. m = Model(input=[latent, hairs_class, eyes_class], output=fake_image)
  47. return m

构建G网络:

  1. # 生成网络
  2. G = build_generator_model(100,len(HAIRS),len(EYES))
  3. # 调用这个方法可以画出模型图
  4. # plot_model(G, to_file='generator.png', show_shapes=True, expand_nested=True, dpi=500)

构建Discriminator

这里我们的discriminator的网络结构上文中的cgan网络结构稍有不同。在前文中,我们是在Discriminator的输入端的输入是图片标签,而在这里,我们的Discriminator的输入仅仅是图片,输出才是label 和 真假概率。

网络结构如下所示:

然后根据上述的网络结构来构建discriminator,代码如下:

  1. def build_discriminator_model(hair_num_class, eye_num_class):
  2. """
  3. 定义生成 discriminator 的方法
  4. :param hair_num_class: 头发颜色的种类
  5. :param eye_num_class: 眼睛颜色的种类
  6. :return: discriminator
  7. """
  8. kernel_init = 'glorot_uniform'
  9. discriminator_model = Sequential(name="discriminator_model")
  10. discriminator_model.add(Conv2D(filters=64, kernel_size=(4, 4), strides=(2, 2), padding="same",
  11. data_format="channels_last", kernel_initializer=kernel_init,
  12. input_shape=(64, 64, 3)))
  13. discriminator_model.add(LeakyReLU(0.2))
  14. discriminator_model.add(Conv2D(filters=128, kernel_size=(4, 4), strides=(2, 2), padding="same",
  15. data_format="channels_last", kernel_initializer=kernel_init))
  16. discriminator_model.add(BatchNormalization(momentum=0.5))
  17. discriminator_model.add(LeakyReLU(0.2))
  18. discriminator_model.add(Conv2D(filters=256, kernel_size=(4, 4), strides=(2, 2), padding="same",
  19. data_format="channels_last", kernel_initializer=kernel_init))
  20. discriminator_model.add(BatchNormalization(momentum=0.5))
  21. discriminator_model.add(LeakyReLU(0.2))
  22. discriminator_model.add(Conv2D(filters=512, kernel_size=(4, 4), strides=(2, 2), padding="same",
  23. data_format="channels_last", kernel_initializer=kernel_init))
  24. discriminator_model.add(BatchNormalization(momentum=0.5))
  25. discriminator_model.add(LeakyReLU(0.2))
  26. discriminator_model.add(Flatten())
  27. # 网络的输入
  28. dis_input = Input(shape=(64, 64, 3))
  29. features = discriminator_model(dis_input)
  30. # 真/假概率的输出
  31. validity = Dense(1, activation="sigmoid")(features)
  32. # 头发颜色种类的输出
  33. label_hair = Dense(hair_num_class, activation="softmax")(features)
  34. # 眼睛颜色种类的输出
  35. label_eyes = Dense(eye_num_class, activation="softmax")(features)
  36. m = Model(dis_input, [validity, label_hair, label_eyes])
  37. return m

然后调用方法创建discriminator。

  1. D = build_discriminator_model(len(HAIRS),len(EYES))
  2. # 画出模型图
  3. # plot_model(D, to_file='discriminator.png', show_shapes=True, expand_nested=True, dpi=500)

构建cGAN网络

cgan网络的输入是generator的输入,cgan的输出是discriminator的输出,网络模型图如下所示:

模型图看起来很复杂,但是实际上代码却很简单,针对于GAN网络,我们只需要将GAN网络中的D网络进行冻结(将trainable变成False)即可。

  1. def build_ACGAN(gen_lr=0.00015, dis_lr=0.0002, noise_size=100):
  2. """
  3. 生成
  4. :param gen_lr: generator的学习率
  5. :param dis_lr: discriminator的学习率
  6. :param noise_size: 噪声维度size
  7. :return:
  8. """
  9. # D网络优化器
  10. dis_opt = Adam(lr=dis_lr, beta_1=0.5)
  11. # D网络loss
  12. losses = ['binary_crossentropy', 'categorical_crossentropy', 'categorical_crossentropy']
  13. # 配置D网络
  14. D.compile(loss=losses, loss_weights=[1.4, 0.8, 0.8], optimizer=dis_opt, metrics=['accuracy'])
  15. # 在训练的generator时,冻结discriminator的权重
  16. D.trainable = False
  17. opt = Adam(lr=gen_lr, beta_1=0.5)
  18. gen_inp = Input(shape=(noise_size,))
  19. hairs_inp = Input(shape=(1,), dtype='int32')
  20. eyes_inp = Input(shape=(1,), dtype='int32')
  21. GAN_inp = G([gen_inp, hairs_inp, eyes_inp])
  22. GAN_opt = D(GAN_inp)
  23. gan = Model(input=[gen_inp, hairs_inp, eyes_inp], output=GAN_opt)
  24. gan.compile(loss=losses, optimizer=opt, metrics=['accuracy'])
  25. return gan

然后调用方法构建GAN网络即可:

  1. gan = build_ACGAN()
  2. # plot_model(gan, to_file='gan.png', show_shapes=True, expand_nested=True, dpi=500)

工具方法

然后我们定义一些方法,有:

  • 产生噪声:gen_noise
  • G网络产生图片,并将生成的图片进行保存
  • 从数据集中随机获取动漫头像和标签数据

关于这些代码具体的说明,可以看一下注释。

  1. def gen_noise(batch_size, noise_size=100):
  2. """
  3. 生成高斯噪声
  4. :param batch_size: 生成噪声的数量
  5. :param noise_size: 噪声的维度
  6. :return: (batch_size,noise)的高斯噪声
  7. """
  8. return np.random.normal(0, 1, size=(batch_size, noise_size))
  9. def generate_images(generator,img_path):
  10. """
  11. G网络生成图片
  12. :param generator: 生成器
  13. :return: (64,64,3)维度 16张图片
  14. """
  15. noise = gen_noise(16, 100)
  16. hairs = np.zeros(16)
  17. eyes = np.zeros(16)
  18. # 指令生成头发,和眼睛的颜色
  19. for h in range(len(HAIRS)):
  20. hairs[h] = h
  21. for e in range(len(EYES)):
  22. eyes[e] = e
  23. # 生成图片
  24. fake_data_X = generator.predict([noise, hairs, eyes])
  25. plt.figure(figsize=(4, 4))
  26. gs1 = gridspec.GridSpec(4, 4)
  27. gs1.update(wspace=0, hspace=0)
  28. for i in range(16):
  29. ax1 = plt.subplot(gs1[i])
  30. ax1.set_aspect('equal')
  31. image = fake_data_X[i, :, :, :]
  32. fig = plt.imshow(image)
  33. plt.axis('off')
  34. fig.axes.get_xaxis().set_visible(False)
  35. fig.axes.get_yaxis().set_visible(False)
  36. plt.tight_layout()
  37. # 保存图片
  38. plt.savefig(img_path, bbox_inches='tight', pad_inches=0)
  39. def sample_from_dataset(batch_size, images, hair_tags, eye_tags):
  40. """
  41. 从数据集中随机获取图片
  42. :param batch_size: 批处理大小
  43. :param images: 数据集
  44. :param hair_tags: 头发颜色标签数据集
  45. :param eye_tags: 眼睛颜色标签数据集
  46. :return:
  47. """
  48. choice_indices = np.random.choice(len(images), batch_size)
  49. sample = images[choice_indices]
  50. y_hair_label = hair_tags[choice_indices]
  51. y_eyes_label = eye_tags[choice_indices]
  52. return sample, y_hair_label, y_eyes_label

进行训练

然后定义训练方法, 在训练的过程中,我们一般来说会将10进行smooth,让它们在一定的范围内波动。同时我们在训练D网络的过程中,我们会这样做:

  1. 真实的图片,真实的标签进行训练 —— 训练判别器对真实图片的判别能力
  2. G网络产生的图片,虚假的标签进行训练 —— 训练判别器对fake 图片的判别能力

在训练G网路的时候我们会这样做:

  1. 产生噪声,虚假的标签(代码随机生成头发的颜色和眼睛的颜色),然后输入到GAN网络中
  2. 而针对于GAN网络的输出,我们将其定义为[1(认为其为真实图片)],[输入端的标签]。GAN网络的输出认为是1(实际上是虚假的图片),这样就能够产生一个loss,从而通过反向传播来更新G网络的权值(在这一个步骤中,D网络的权值并不会进行更新。)
  1. def train(epochs, batch_size, noise_size, hair_num_class, eye_num_class):
  2. """
  3. 进行训练
  4. :param epochs: 训练的步数
  5. :param batch_size: 训练的批处理大小
  6. :param noise_size: 噪声维度大小
  7. :param hair_num_class: 头发颜色种类
  8. :param eye_num_class: 眼睛颜色种类
  9. :return:
  10. """
  11. for step in range(0, epochs):
  12. # 每隔100轮保存数据
  13. if (step % 100) == 0:
  14. step_num = str(step).zfill(6)
  15. generate_images(G, os.path.join("./generate_img", step_num + "_img.png"))
  16. # 随机产生数据并进行编码
  17. sampled_label_hairs = np.random.randint(0, hair_num_class, batch_size).reshape(-1, 1)
  18. sampled_label_eyes = np.random.randint(0, eye_num_class, batch_size).reshape(-1, 1)
  19. sampled_label_hairs_cat = to_categorical(sampled_label_hairs, num_classes=hair_num_class)
  20. sampled_label_eyes_cat = to_categorical(sampled_label_eyes, num_classes=eye_num_class)
  21. noise = gen_noise(batch_size, noise_size)
  22. # G网络生成图片
  23. fake_data_X = G.predict([noise, sampled_label_hairs, sampled_label_eyes])
  24. # 随机获得真实数据并进行编码
  25. real_data_X, real_label_hairs, real_label_eyes = sample_from_dataset(
  26. batch_size, images_data, y_hairs, y_eyes)
  27. real_label_hairs_cat = to_categorical(real_label_hairs, num_classes=hair_num_class)
  28. real_label_eyes_cat = to_categorical(real_label_eyes, num_classes=eye_num_class)
  29. # 产生0,1标签并进行smooth
  30. real_data_Y = np.ones(batch_size) - np.random.random_sample(batch_size) * 0.2
  31. fake_data_Y = np.random.random_sample(batch_size) * 0.2
  32. # 训练D网络
  33. dis_metrics_real = D.train_on_batch(real_data_X, [real_data_Y, real_label_hairs_cat,
  34. real_label_eyes_cat])
  35. dis_metrics_fake = D.train_on_batch(fake_data_X, [fake_data_Y, sampled_label_hairs_cat,
  36. sampled_label_eyes_cat])
  37. noise = gen_noise(batch_size, noise_size)
  38. # 产生随机的hair 和 eyes标签
  39. sampled_label_hairs = np.random.randint(0, hair_num_class, batch_size).reshape(-1, 1)
  40. sampled_label_eyes = np.random.randint(0, eye_num_class, batch_size).reshape(-1, 1)
  41. # 将标签变成(,12)或者(,11)类型的
  42. sampled_label_hairs_cat = to_categorical(sampled_label_hairs, num_classes=hair_num_class)
  43. sampled_label_eyes_cat = to_categorical(sampled_label_eyes, num_classes=eye_num_class)
  44. real_data_Y = np.ones(batch_size) - np.random.random_sample(batch_size) * 0.2
  45. # GAN网络的输入
  46. GAN_X = [noise, sampled_label_hairs, sampled_label_eyes]
  47. # GAN网络的输出
  48. GAN_Y = [real_data_Y, sampled_label_hairs_cat, sampled_label_eyes_cat]
  49. # 对GAN网络进行训练
  50. gan_metrics = gan.train_on_batch(GAN_X, GAN_Y)
  51. # 保存生成器
  52. if step % 100 == 0:
  53. print("Step: ", step)
  54. print("Discriminator: real/fake loss %f, %f" % (dis_metrics_real[0], dis_metrics_fake[0]))
  55. print("GAN loss: %f" % (gan_metrics[0]))
  56. G.save(os.path.join('./model', str(step) + "_GENERATOR.hdf5"))

一般来说,训练1w轮就可以得到一个比较好的结果了(博客的开头的那两张图片就是训练1w轮的模型生成的),不过值得注意的是,在训练轮数过多的情况下产生了过拟合(产生的图片逐渐一毛一样)。

  1. train(1000000,64,100,len(HAIRS),len(EYES))

可视化界面

可视化界面的代码如下所示,也是我从Anime-Face-ACGAN里面copy的,没什么好说的,就是直接使用tk框架搭建了一个界面,一个按钮。

  1. import tkinter as tk
  2. from tkinter import ttk
  3. import imageio
  4. import numpy as np
  5. from PIL import Image, ImageTk
  6. from keras.models import load_model
  7. num_class_hairs = 12
  8. num_class_eyes = 11
  9. def load_model():
  10. # 这里使用的是1w轮的训练模型
  11. g = load_model(str(10000) + '_GENERATOR.hdf5')
  12. return g
  13. # 加载模型
  14. G = load_model()
  15. # 创建窗体
  16. win = tk.Tk()
  17. win.title('可视化GUI')
  18. win.geometry('400x200')
  19. def gen_noise(batch_size, latent_size):
  20. return np.random.normal(0, 1, size=(batch_size, latent_size))
  21. def generate_images(generator, latent_size, hair_color, eyes_color):
  22. noise = gen_noise(1, latent_size)
  23. return generator.predict([noise, hair_color, eyes_color])
  24. def create():
  25. hair_color = np.array(comboxlist1.current()).reshape(1, 1)
  26. eye_color = np.array(comboxlist2.current()).reshape(1, 1)
  27. image = generate_images(G, 100, hair_color, eye_color)[0]
  28. imageio.imwrite('anime.png', image)
  29. img_open = Image.open('anime.png')
  30. img = ImageTk.PhotoImage(img_open)
  31. label.configure(image=img)
  32. label.image = img
  33. comvalue1 = tk.StringVar() # 窗体自带的文本,新建一个值
  34. comboxlist1 = ttk.Combobox(win, textvariable=comvalue1)
  35. comboxlist1["values"] = (
  36. 'orange hair', 'white hair', 'aqua hair', 'gray hair', 'green hair', 'red hair', 'purple hair', 'pink hair',
  37. 'blue hair', 'black hair', 'brown hair', 'blonde hair')
  38. # 默认选择第一个
  39. comboxlist1.current(0)
  40. comboxlist1.pack()
  41. comvalue2 = tk.StringVar()
  42. comboxlist2 = ttk.Combobox(win, textvariable=comvalue2)
  43. comboxlist2["values"] = (
  44. 'gray eyes', 'black eyes', 'orange eyes', 'pink eyes', 'yellow eyes', 'aqua eyes', 'purple eyes', 'green eyes',
  45. 'brown eyes', 'red eyes', 'blue eyes')
  46. # 默认选择第一个
  47. comboxlist2.current(0)
  48. comboxlist2.pack()
  49. bm = tk.PhotoImage(file='anime.png')
  50. label = tk.Label(win, image=bm)
  51. label.pack()
  52. b = tk.Button(win,
  53. text='一键起飞', # 显示在按钮上的文字
  54. width=15, height=2,
  55. command=create) # 点击按钮式执行的命令
  56. b.pack()
  57. win.mainloop()

界面如下所示

总结

cgan网相比较dcgan而言,差别不是很大,只不过是加了一个标签label而已。不过该篇博客的代码还是大量的借鉴了Anime-Face-ACGAN的代码,因为我也是一个新手,Just Study Together.

参考

Anime-Face-ACGAN

GAN — CGAN & InfoGAN (using labels to improve GAN)

A tutorial on Conditional Generative Adversarial Nets + Keras implementation

How to Develop a Conditional GAN (cGAN) From Scratch

GAN网络之入门教程(五)之基于条件cGAN动漫头像生成的更多相关文章

  1. GAN网络从入门教程(一)之GAN网络介绍

    GAN网络从入门教程(一)之GAN网络介绍 稍微的开一个新坑,同样也是入门教程(因此教程的内容不会是从入门到精通,而是从入门到入土).主要是为了完成数据挖掘的课程设计,然后就把挖掘榔头挖到了GAN网络 ...

  2. GAN网络从入门教程(二)之GAN原理

    在一篇博客GAN网络从入门教程(一)之GAN网络介绍中,简单的对GAN网络进行了一些介绍,介绍了其是什么,然后大概的流程是什么. 在这篇博客中,主要是介绍其数学公式,以及其算法流程.当然数学公式只是简 ...

  3. GAN网络从入门教程(三)之DCGAN原理

    目录 DCGAN简介 DCGAN的特点 几个重要概念 下采样(subsampled) 上采样(upsampling) 反卷积(Deconvolution) 批标准化(Batch Normalizati ...

  4. GAN网络之入门教程(四)之基于DCGAN动漫头像生成

    目录 使用前准备 数据集 定义参数 构建网络 构建G网络 构建D网络 构建GAN网络 关于GAN的小trick 训练 总结 参考 这一篇博客以代码为主,主要是来介绍如果使用keras构建一个DCGAN ...

  5. SpringBoot入门教程(五)Java基于MySQL实现附近的人

    “附近的人”这个功能估计都不陌生,与之类似的功能最开始是在各大地图应用上接触过,比如搜附近的电影院,附近的超市等等.然而真正让附近的人火遍大江南北的应该是微信"附近的人"这个功能, ...

  6. 【Zigbee技术入门教程-号外】基于Z-Stack协议栈的抢答系统

    [Zigbee技术入门教程-号外]基于Z-Stack协议栈的抢答系统 广东职业技术学院  欧浩源 一.引言    2017年全国职业院校技能大赛"物联网技术应用"赛项中任务三题2的 ...

  7. PySide——Python图形化界面入门教程(五)

    PySide——Python图形化界面入门教程(五) ——QListWidget 翻译自:http://pythoncentral.io/pyside-pyqt-tutorial-the-qlistw ...

  8. Elasticsearch入门教程(五):Elasticsearch查询(一)

    原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  9. 无废话ExtJs 入门教程五[文本框:TextField]

    无废话ExtJs 入门教程五[文本框:TextField] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个文本框.如下所示代码区的第42行位置,items: ...

随机推荐

  1. 入门的艰难——关于LR的使用

    这年头做一件事真是TM不容易啊.做测试也很纠结,不是都说商业工具很强大么,我去,这个不支持那个不支持的,这还有什么搞头,还非要按照你说的这个版本的才行,高一点的就crash了,结果连最初级的录制脚本都 ...

  2. [BUUOJ记录] [ACTF2020 新生赛]BackupFile、Exec

    两道题都比较简单,所以放到一块记下来吧,不是水博客,师傅们轻点打 BackupFile 题目提示“Try to find out source file!”,访问备份文件/index.php.bak获 ...

  3. 三层架构的一点理解以及Dapper一对多查询

    1.首先说一下自己对三层架构的一点理解 论坛里经常说会出现喜欢面相对象的写法,所以使用EF的,我个人觉得他俩没啥关系,先别反对,先听听我怎么说吧. 三层架构,基本都快说烂了,但今天还是说三层架构:UI ...

  4. C001:打印勾

    程序: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { printf(" *\n"); p ...

  5. ByteCTF2019

    VIP 第一阶段: 先检查一下程序开的保护: 程序只开了canary和nx保护.接下来用IDA分析反编译出的伪代码 如上图,载edit函数中我们可以控制size的大小,并且程序没有做任何检查,我们再跟 ...

  6. 腾讯云 云开发 部署 Blazor网站

    Blazor 应用程序除了在 Github Pages/Gitee Pages等静态资源部署以外,现在你有了一个新的选择,那就是使用云开发静态网站功能来部署啦! 系统依赖 在进行后续的内容前,请先确保 ...

  7. opentracting+jager分布式链路追踪探索实践

    一.Opentracing opentracing通过提供平台无关.厂商无关的API,使得开发人员可以方便地实现追踪系统.opentracing提供了用于运营支撑系统和针对特定平台的辅助程序库,被跟踪 ...

  8. 关于input框仿百度/google自动提示的方法

    引入jquery-autocomplete文件 链接:https://pan.baidu.com/s/1hW0XBYH8ZgJgMSY1Ce6Pig 密码:tv5b $(function() { $( ...

  9. JS -- JavaScript简介

    JavaScript是一种属于网络的高级脚本语言(解释性脚本语言),已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果. 一.如何插入JS代码? 使用&l ...

  10. js中的鼠标滚轮事件

    ## 事件对象 event 1 event事件对象,表示用来获取事件的详细信息,比如得到鼠标的横坐标:事件对象.clientX(clientX是可视区坐标) window.onclick = func ...