看了一上午简直要头疼死。GAN之前没接触过,学习的时候产生了很多乱七八糟的联想。从上篇文章开始,很多内容都是自己的理解,估计有很多错误,以后学习中发现了可能会回来修改的。
找的是机器之心i的代码:https://gitahub.com/jiqizhixin/ML-Tutorial-Experiment/blob/master/Experiments/Keras_GAN.ipynb,用Keras实现的,不然更看不懂了。笔记本上没安Tensorflow,打算晚上回去用实验室电脑跑一跑,如果顺利的话。
1. 导入部分:
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Reshape
from keras.layers.core import Activation
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import UpSampling2D
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Flatten
from keras.optimizers import SGD
from keras.datasets import mnist
import numpy as np
from PIL import Image
import argparse
import math
关于网络模型:
生成器和判别器都是很简单的网络模型,因此只需要从导入序贯(Sequential)模型,网络层线性堆叠。
关于网络结构:
从keras.layers导入Dense(就是全连接层,是dense connect),导入Reshape(不过看Keras文档Reshape是在keras.layers.core目录下的);从keras.layers.core(常用层)导入Activation(激活层),Flatten(平铺);从keras.layers.normalization导入BatchNormalization(BN层);从keras.layers.convolutional导入UpSampling2D, Conv2D, MaxPooling2D(都是二维的)。
关于网络训练:
从keras.optimizers中导入SGD,算法中使用梯度下降法求解;从keras.datasets中导入mnist(手写数字的数据集,是灰度图像)。
其他:
PIL:Python Imaging Library,python中的图像处理库,看介绍就是有很强的图像处理能力,隐约中记得安装过;
argparse:还不太懂,貌似是能在命令行中提供更加用户友好的参数选择接口。
2. 生成器网络结构:
def generator_model():
#下面搭建生成器的架构,首先导入序贯模型(sequential),即多个网络层的线性堆叠
model = Sequential()
#添加一个全连接层,输入为100维向量,输出为1024维
model.add(Dense(input_dim=100, output_dim=1024))
#添加一个激活函数tanh
model.add(Activation('tanh'))
#添加一个全连接层,输出为128×7×7维度
model.add(Dense(128*7*7))
#添加一个批量归一化层,该层在每个batch上将前一层的激活值重新规范化,即使得其输出数据的均值接近0,其标准差接近1
model.add(BatchNormalization())
model.add(Activation('tanh'))
#Reshape层用来将输入shape转换为特定的shape,将含有128*7*7个元素的向量转化为7×7×128张量
model.add(Reshape((7, 7, 128), input_shape=(128*7*7,)))
#2维上采样层,即将数据的行和列分别重复2次
model.add(UpSampling2D(size=(2, 2)))
#添加一个2维卷积层,卷积核大小为5×5,激活函数为tanh,共64个卷积核,并采用padding以保持图像尺寸不变
model.add(Conv2D(64, (5, 5), padding='same'))
model.add(Activation('tanh'))
model.add(UpSampling2D(size=(2, 2)))
#卷积核设为1即输出图像的维度
model.add(Conv2D(1, (5, 5), padding='same'))
model.add(Activation('tanh'))
return model
代码中的标注都是原作者的。生成器网络的输入是100维的向量,也就是生成器是要从100维的向量(相对于图像的向量应该算是低维向量了,它的分布肯定比图像向量所服从的分布简单多了)生成图像的向量(生成器网络实现的就是从低维向量到高维向量的映射)。至于它输出的图像向量的维度,通过网络具体结构计算&