Keras常用API及GAN mnist demo

1. 定义模型

Sequential模型是层的线性堆栈
Sequential通过将一系列图层实例传递给构造函数来创建模型:
.add()方法简单地添加图层:

model = Sequential()
model.add(Dense(32, input_dim=784))
model.add(Activation('relu'))

1.1 Dense

keras.layers.Dense(units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

Dense层,即全连接层,实现的运算是output = activation(dot(input, kernel)+bias)。其中activation是逐元素计算的激活函数,kernel是本层的权值矩阵,bias为偏置向量,只有当use_bias=True才会添加。

  • units: 正整数,输出空间维度。
  • activation: 激活函数 (详见 activations)。 若不指定,则不使用激活函数 (即,「线性」激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers).
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向的的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层的输出的正则化函数 (它的 “activation”)。 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸:
nD 张量,尺寸: (batch_size, ..., input_dim)。 最常见的情况是一个尺寸为 (batch_size, input_dim)的 2D 输入。

输出尺寸:
nD 张量,尺寸: (batch_size, ..., units)。 例如,对于尺寸为 (batch_size, input_dim) 的 2D 输入, 输出的尺寸为 (batch_size, units)

1.2 Dropout

keras.layers.Dropout(rate, noise_shape=None, seed=None)

Dropout 包括在训练中每次更新时, 将输入单元的按比率随机设置为 0, 这有助于防止过拟合。

  • rate: 在 0 和 1 之间浮动。需要丢弃的输入比例。
  • noise_shape: 1D 整数张量, 表示将与输入相乘的二进制 dropout 掩层的形状。 例如,如果你的输入尺寸为 (batch_size, timesteps, features),然后 你希望 dropout 掩层在所有时间步都是一样的, 你可以使用 noise_shape=(batch_size, 1, features)
  • seed: 一个作为随机种子的 Python 整数。

1.3 Flatten

keras.layers.Flatten(data_format=None)

将输入展平。不影响批量大小。

1.4 Conv2D

keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

2D 卷积层 (例如对图像的空间卷积)。

该层创建了一个卷积核, 该卷积核对层输入进行卷积, 以生成输出张量。 如果 use_biasTrue, 则会创建一个偏置向量并将其添加到输出中。 最后,如果 activation 不是 None,它也会应用于输出。

当使用该层作为模型第一层时,需要提供 input_shape 参数 (整数元组,不包含样本表示的轴),例如, input_shape=(128, 128, 3) 表示 128x128 RGB 图像, 在 data_format="channels_last"时。
参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者 2 个整数表示的元组或列表, 指明 2D 卷积窗口的宽度和高度。 可以是一个整数,为所有空间维度指定相同的值。
  • strides: 一个整数,或者 2 个整数表示的元组或列表, 指明卷积沿宽度和高度方向的步长。 可以是一个整数,为所有空间维度指定相同的值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: “valid” 或 “same” (大小写敏感)。
  • activation: 要使用的激活函数 (详见 activations)。 如果不指定,则不使用激活函数 (即线性激活: a(x) = x)。

1.5 MaxPooling2D

keras.layers.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)
  • pool_size:2个整数的整数或元组,用于缩减的因子(垂直,水平)。(2,2)将在两个空间维度上将输入减半。如果仅指定一个整数,则两个尺寸将使用相同的窗口长度。
  • 步幅strides:整数,2个整数的元组或无。跨越价值观。如果为None,则默认为pool_size。
  • 填充padding:其中一个"valid"或"same"(不区分大小写)。

2. 指定输入形状

模型需要知道它应该期望什么样的输入形状。因此,Sequential模型中的第一层(并且只有第一层,因为随后的层可以进行自动形状推断)需要接收有关其输入形状的信息。有几种方法可以做到这一点:

将input_shape参数传递给第一层。这是一个形状元组(整数或None条目的元组,其中None表示可以期望任何正整数)。在中input_shape,不包含批次尺寸。

某些2D图层(例如Dense,通过参数支持输入形状的指定)input_dim,而某些3D时间层则支持参数input_diminput_length

如果需要为输入指定固定的批处理大小(这对于有状态循环网络很有用),则可以将batch_size参数传递给图层。如果同时传递batch_size=32和传递input_shape=(6, 8)到图层,则它将期望每一批输入都具有批处理形状(32, 6, 8)

3. compile 编译模型

compile(self, optimizer, loss, metrics=None)

在训练模型之前,通过compile方法完成配置学习过程。它接收三个参数:

  1. 优化器optimizer。这可以是现有优化器(例如rmspropadagrad)的字符串标识符,也可以是Optimizer该类的实例。请参阅:优化程序。
  2. 损失函数loss。这是模型将尝试最小化的目标。它可以是现有损失函数(例如categorical_crossentropymse)的字符串标识符,也可以是目标函数。请参阅:损失。
  3. 指标列表metrics。对于任何分类问题,您都需要将此设置为metrics=['accuracy']。指标可以是现有指标或自定义指标函数的字符串标识符。请参阅:指标。
# For a multi-class classification problem
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# For a binary classification problem
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# For a mean squared error regression problem
model.compile(optimizer='rmsprop',
              loss='mse')

# For custom metrics
import keras.backend as K

def mean_pred(y_true, y_pred):
    return K.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])

4.fit 训练模型

it(self, X=None, y=None, batch_size=None, epochs=1, verbose=1, validation_data=None)
  • X:输入数据。
  • y:输入数据集的标签。
  • batch_size:整数,指定进行梯度下降时每个batch包含的样本数。训练时一个batch的样本会被计算一次梯度下降,使目标函数优化一步。
  • epochs:整数,训练终止时的epoch值,训练将在达到该epoch值时停止,如果未指定,默认为 32。
  • verbose:0 为不在标准输出流输出日志信息,1 为输出进度条记录,2 为每个epoch输出一行记录。
  • validation_data:验证数据集,用于在每个 epoch 验证 model 的效果。

5. evaluate 评估模型

evaluate(self, x=None, y=None, batch_size=None, verbose=1)

在测试模式,返回误差值和评估标准值。计算逐批次进行。


Keras 手写数字识别

import keras
from keras import layers
import matplotlib.pyplot as plt
%matplotlib inline
import keras.datasets.mnist as mnist
# 1.输入数据
(train_image, train_label),(test_image,test_label) = mnist.load_data()

# 2.构建模型
model = keras.Sequential()
# (60000,28,28)--> (60000, 28*28)
model.add(layers.Flatten())
# 全连接层
model.add(layers.Dense(64,activation = 'relu'))
model.add(layers.Dense(10,activation = 'softmax'))

# 3.编译模型
model.compile(optimizer = 'adam',
             loss = 'sparse_categorical_crossentropy',
             metrics=['acc'])

# 4.模型训练
model.fit(train_image, train_label, epochs = 50, batch_size = 512)

5.模型评估:

model.evaluate(test_image, test_label)

输出:

10000/10000 [==============================] - 1s 88us/step
[0.5225099971218286, 0.9659]
model.evaluate(train_image, train_label)

输出:

60000/60000 [==============================] - 4s 63us/step
[0.3641383859386498, 0.9760166666666666]

6.模型优化

model = keras.Sequential()
# (60000,28,28)--> (60000, 28*28)
model.add(layers.Flatten())
# 全连接层
model.add(layers.Dense(64,activation = 'relu'))
model.add(layers.Dense(64,activation = 'relu'))
model.add(layers.Dense(10,activation = 'softmax'))

model.compile(optimizer = 'adam',
             loss = 'sparse_categorical_crossentropy',
             metrics=['acc'])
             
model.fit(train_image, train_label, epochs = 50, batch_size = 512,validation_data = (test_image,test_label))

Keras GAN mnist

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
import numpy as np
import glob
import os

# 1.导入数据
(train_images, train_label), (_,_) = tf.keras.datasets.mnist.load_data()
# 转换数据类型,并reshape为四维变量
train_images = train_images.reshape(train_images.shape[0],28,28,1).astype('float32')
# 归一化数据
train_images = (train_images - 127.5)/127.5
# 批训练大小
BATCH_SIZE = 256
# 取多少张图片用来操作,比如shuffle操作
BUFFER_SIZE = 60000
datasets = tf.data.Dataset.from_tensor_slices(train_images)
datasets = datasets.shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

2.定义生成器

def generator_model():
    model = keras.Sequential()
    model.add(layers.Dense(256, input_shape=(100,), use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    
    model.add(layers.Dense(512, use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    
    model.add(layers.Dense(28*28*1, use_bias=False, activation='tanh'))
    model.add(layers.BatchNormalization())
    
    # Reshape() 接收元组参数
    model.add(layers.Reshape((28,28,1)))
    
    return model

3.定义鉴别器

def discriminator_model():
    model =keras.Sequential()
    model.add(layers.Flatten())
    
    model.add(layers.Dense(512, use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    
    model.add(layers.Dense(256, use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())    
    
    model.add(layers.Dense(1))
    
    return model
# 因为在上一步的输出没有激活,所以要设置from_logits = True
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

3.定义鉴别器的损失

def discriminator_loss(real_out, fake_out):
    # 希望真实的图片被判别为1
    real_loss = cross_entropy(tf.ones_like(real_out), real_out)
    # 生成的图片被判别为0
    fake_loss = cross_entropy(tf.zeros_like(fake_out), fake_out)
    return real_loss + fake_loss

4.定义生成器的损失

def generator_loss(fake_out):
    # 期望生成的图片被鉴别器判定为真
    return cross_entropy(tf.ones_like(fake_out), fake_out)

5.定义优化器

generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)

6.设置训练参数

EPOCHS = 100
# 长度为100的随机向量
noise_dim = 100
# 生成16个随机向量,观察生成的手写数字情况
num_example_to_generator = 16
seed = tf.random.normal([num_example_to_generator,noise_dim])

7.初始化

generator = generator_model()
discriminator = discriminator_model()

def train_step(images):
    # 生成长度为100的随机数
    noise = tf.random.normal([BATCH_SIZE,noise_dim])
    
    # 自定义训练过程
    # 因为要追踪两个model,所以定义两个梯度
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        # 真实图片的输出,
        real_out = discriminator(images, training=True)
        # 生成图片的输出
        gen_image = generator(noise, training=True)
        # 假图片的输出
        fake_out = discriminator(gen_image, training=True)
        
        gen_loss = generator_loss(fake_out)
        disc_loss = discriminator_loss(real_out, fake_out)
    
    # 生成器损失和随机变量之间的梯度。取出可训练参数:trainable_variables
    gradient_gen = gen_tape.gradient(gen_loss, generator.trainable_variables)
    # 鉴别器的损失函数和鉴别器的可训练参数之间的梯度
    gradient_disc = disc_tape.gradient(disc_loss, discriminator.trainable_variables)
    
    # 优化
    generator_optimizer.apply_gradients(zip(gradient_gen, generator.trainable_variables))
    discriminator_optimizer.apply_gradients(zip(gradient_disc, discriminator.trainable_variables))
    

显示每个epoch生成的图片

def generator_plot_image(gen_model, test_noise):
    pre_images = gen_model(test_noise, training=False)
    fig = plt.figure(figsize=(4,4))
    for i in range(pre_images.shape[0]):
        plt.subplot(4,4,i+1)
        plt.imshow((pre_images[i,:,:,0] + 1)/2, cmap='gray')
        plt.axis('off')
        
    plt.show()

训练

def train(dataset, epochs):
    for epoch in range(epochs):
        for image_batch in dataset:
            train_step(image_batch)
            print('.',end='')
        generator_plot_image(generator, seed)
train(datasets, EPOCHS)

训练最后一轮生成结果:
在这里插入图片描述
可以看出,效果并不是很好,要优化的话可以使用DCGAN。

参考:
https://keras.io/zh/layers/convolutional/#conv2d
https://keras.io/layers/core/
https://www.bilibili.com/video/av89610076/?p=7&t=857

发布了122 篇原创文章 · 获赞 94 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_39653948/article/details/104851925