1、一般训练模式:
import tensorflow as tf
import numpy as np
import time
from sklearn import metrics
from keras.callbacks import ModelCheckpoint
# from tensorflow.keras.callbacks import ModelCheckpoint
# 建立model
class MLP(tf.keras.Model):
"""自定义MLP类
"""
def __init__(self):
super().__init__()
# 定义两层神经网络,第一层100个神经元,激活函数relu,第二层10个神经元输出给softmax
self.flatten = tf.keras.layers.Flatten()
self.dense1 = tf.keras.layers.Dense(units=128, activation=tf.nn.relu)
self.dense2 = tf.keras.layers.Dense(units=10)
def call(self, x):
# [batch_size, 28, 28, 1]
x = self.flatten(x)
# [batch_size, 784]
x = self.dense1(x)
# [batch_size, 100]
x = self.dense2(x)
# [batch_size, 10]
return x
# -------------创建虚拟数据----------------
"""
from keras.utils import np_utils
y_train = np_utils.to_categorical(y_train) # 即:one_hot(独热编码)
"""
data = np.random.random((128,28,28,1))
y = np.zeros((128))
y[32:65], y[64:97], y[96:129] = 1, 2, 3
# (data, y), (test, y_test) = tf.keras.datasets.mnist.load_data() # 一般下载在 C:\Users\用户名\.keras
# -------------生成model----------------
model = MLP()
# -------------定义compile----------------
"""
from_logits=False,output 为经过 softmax 输出的概率值
from_logits=True,output 为经过网络直接输出的 logits 张量
"""
# 使用model.compile()方法来配置训练方法
model.compile(
optimizer=tf.keras.optimizers.Adam(lr=0.001), # 使用SGD优化器,学习率为0.001
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), # 配置损失函数
metrics=['accuracy'] # 标注网络评价指标
)
# -------------定义模型保存策略----------------
"""
filename:字符串,保存模型的路径,filepath可以是格式化的字符串,里面的占位符将会被epoch值和传入on_epoch_end的logs关键字所填入。
例如:filepath = “weights_{epoch:03d}-{val_loss:.4f}.h5”
monitor:需要监视的值,通常为:val_accuracy、val_loss、accuracy、loss
verbose:信息展示模式,0或1。为1表示输出epoch模型保存信息,默认为0表示不输出该信息
save_best_only:当设置为True时,将只保存在验证集上性能最好的模型
mode:‘auto’,‘min’,‘max’之一,在save_best_only=True时决定性能最佳模型的评判准则,例如,当监测值为val_acc时,模式应为max,当检测值为val_loss时,模式应为min。在auto模式下,评价准则由被监测值的名字自动推断。
save_weights_only:若设置为True,则只保存模型权重,否则将保存整个模型(包括模型结构,配置信息等)
"""
# filepath = "./weights_{epoch:03d}.h5"
filepath = "./weights.h5"
checkpoint = ModelCheckpoint(filepath=filepath, monitor='val_accuracy', verbose=1,save_best_only=True, mode='auto')
# -------------训练网络----------------
# 使用model.fit()方法来执行训练过程
tic = time.clock()
train_history = model.fit(
x=data, y=y, # 告知训练集的输入以及标签,如果有两个输入,则用[data1, data2]
batch_size=32, # 每一批batch的大小为32
epochs=10, # 迭代次数epochs为10
validation_split=0.2, # 从训练集中划分20%给测试集。可以自己指定测试集:validation_data=(data, y),
validation_freq=2, # 每迭代5次进行一次测试集预测
callbacks=[checkpoint]
)
toc = time.clock()
print('Training Time: ', toc - tic)
scores = model.evaluate(data, y, batch_size=32)
print('Test score:', scores[0])
print('Test accuracy:', scores[1])
# -------------打印模型参数----------------
model.summary() # 查看模型参数
# -------------获取训练中的参数----------------
# 模型训练损失和准确率参数
acc = train_history.history['accuracy']
val_acc = train_history.history['val_accuracy']
loss = train_history.history['loss']
val_loss = train_history.history['val_loss']
# -------------测试模型----------------
model.load_weights("./weights.h5")
tic = time.clock()
pred_test = model.predict(data).argmax(axis=1)
toc = time.clock()
print('Test time:', toc - tic)
# -------------绘制混淆矩阵----------------
confusion_matrix_mss = metrics.confusion_matrix(y,pred_test)
2、自定义训练模式:
import tensorflow as tf
import numpy as np
# 建立model
class MLP(tf.keras.Model):
"""自定义MLP类
"""
def __init__(self):
super().__init__()
# 定义两层神经网络,第一层100个神经元,激活函数relu,第二层10个神经元输出给softmax
self.flatten = tf.keras.layers.Flatten()
self.dense1 = tf.keras.layers.Dense(units=128, activation=tf.nn.relu)
self.dense2 = tf.keras.layers.Dense(units=10)
def call(self, x):
# [batch_size, 28, 28, 1]
x = self.flatten(x)
# [batch_size, 784]
x = self.dense1(x)
# [batch_size, 100]
x = self.dense2(x)
# [batch_size, 10]
return x
# -------------创建虚拟数据----------------
"""
from keras.utils import np_utils
y_train = np_utils.to_categorical(y_train) # 即:one_hot(独热编码)
"""
data = np.random.random((128,28,28,1))
y = np.zeros((128))
y[32:65], y[64:97], y[96:129] = 1, 2, 3
# (data, y), (test, y_test) = tf.keras.datasets.mnist.load_data() # 一般下载在 C:\Users\用户名\.keras
# -------------生成model----------------
model = MLP()
# -------------设置超参数----------------
epochs = 20
batch_size = 16
lr = 0.001
# -------------包装训练、测试数据----------------
train_loader = tf.data.Dataset.from_tensor_slices((data[:100], y[:100]))
train_dataset = train_loader.shuffle(buffer_size=1).batch(batch_size)
test_loader = tf.data.Dataset.from_tensor_slices((data[100:], y[100:]))
test_dataset = test_loader.shuffle(buffer_size=1).batch(batch_size)
# -------------设置损失函数和优化器----------------
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam(learning_rate=lr)
# -------------设置训练、测试准确率函数----------------
train_acc_metric = tf.keras.metrics.SparseCategoricalAccuracy()
val_acc_metric = tf.keras.metrics.SparseCategoricalAccuracy()
# -------------开始训练----------------
for epoch in range(epochs):
for i, (X, y) in enumerate(train_dataset):
with tf.GradientTape() as tape:
y_pred = model(X)
loss = loss_fn(y_true=y, y_pred=y_pred)
grads = tape.gradient(loss, model.variables)
optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
train_acc_metric(y, y_pred)
train_acc = train_acc_metric.result()
print("step: {:3d} train_loss:{:.6f} train_acc:{:.2f}".format(epoch,loss,train_acc))
train_acc_metric.reset_states() # 在每个epoch结束时重置训练指标, 一定要重置!
if (epoch+1) % 5==0:
# 验证集
for i, (X, y) in enumerate(test_dataset):
y_pred = model(X)
val_acc_metric(y, y_pred)
loss = loss_fn(y_true=y, y_pred=y_pred)
val_acc = val_acc_metric.result()
print("step: {:3d} test_loss:{:.6f} test_acc:{:.2f}".format(epoch,loss,val_acc))
val_acc_metric.reset_states() # 和上面一样需要充值
3、Keras model.fit()参数详解
fit( x=None, #输入的x值
y=None, #输入的y标签值
batch_size=None, #整数 ,每次梯度更新的样本数即批量大小。未指定,默认为32。
epochs=1, #迭代次数
verbose=1, #整数,代表以什么形式来展示日志状态
callbacks=None, #回调函数,这个list中的回调函数将会在训练过程中的适当时机被调用,参考回调函数
validation_split=0.0, #浮点数0-1之间,用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。
validation_data=None, #这个参数会覆盖 validation_split,即两个函数只能存在一个,它的输入为元组 (x_val,y_val),这作为验证数据。
shuffle=True, #布尔值。是否在每轮迭代之前混洗数据
class_weight=None,
sample_weight=None,
initial_epoch=0,
steps_per_epoch=None, #一个epoch包含的步数(每一步是一个batch的数据送入),当使用如TensorFlow数据Tensor之类的输入张量进行训练时,默认的None代表自动分割,即数据集样本数/batch样本数。
validation_steps=None, #在验证集上的step总数,仅当steps_per_epoch被指定时有用。
validation_freq=1, #指使用验证集实施验证的频率。当等于1时代表每个epoch结束都验证一次
max_queue_size=10,
workers=1,
use_multiprocessing=False
)
在实际应用中的model.fit()调用。
history = model.fit(train_x,
train_y,
batch_size=batch_size,
epochs=100,
#validation_split=0.125,
validation_data=[val_x,val_y],
shuffle= True,
verbose=1,
callbacks=[checkpoint],
validation_freq=1)