保存整个模型
此方法保存以下所有内容:
1.权重值 2.模型配置(架构) 3.优化器配置
整个模型可以保存到一个文件中,其中包含权重值、模型配置乃至优化器配置。这样,您就可以为模型设置检查点,并稍后从完全相同的状态继续训练,而无需访问原始代码。在 Keras 中保存完全可正常使用的模型非常有用,您可以在 TensorFlow.js 中加载它们,然后在网络浏览器中训练和运行它们。Keras 使用 HDF5 标准提供基本的保存格式。
模型保存
model.save('less_model.h5')
模型加载
new_model = tf.keras.models.load_model('less_model.h5')
实例
import numpy as np
import tensorflow as tf
import gzip
import gzip
import numpy as np
import tensorflow as tf
def get_data():
# 文件获取
train_image = r"../../dataset/fashion-mnist/train-images-idx3-ubyte.gz"
test_image = r"../../dataset/fashion-mnist/t10k-images-idx3-ubyte.gz"
train_label = r"../../dataset/fashion-mnist/train-labels-idx1-ubyte.gz"
test_label = r"../../dataset/fashion-mnist/t10k-labels-idx1-ubyte.gz" # 文件路径
paths = [train_label, train_image, test_label, test_image]
with gzip.open(paths[0], 'rb') as lbpath:
y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[1], 'rb') as imgpath:
x_train = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
with gzip.open(paths[2], 'rb') as lbpath:
y_test = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[3], 'rb') as imgpath:
x_test = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
return (x_train, y_train), (x_test, y_test)
(train_image, train_label), (test_image, test_label) = get_data()
train_image = train_image / 255
test_image = test_image / 255
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28, 28))) # 28*28
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
print(model.summary())
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['acc']
)
model.fit(train_image, train_label, epochs=3)
print(model.evaluate(test_image, test_label, verbose=0))
model.save('less_model.h5')
new_model = tf.keras.models.load_model('less_model.h5')
print(new_model.summary())
new_model.fit(train_image, train_label, epochs=3)
print(new_model.evaluate(test_image, test_label, verbose=0))
仅保存架构
有时我们只对模型的架构感兴趣,而无需保存权重值或优化器。在这种情况下,可以仅保存模型的“配置” 。
获取权重
json_config = model.to_json()
加载权重
reinitialized_model = tf.keras.models.model_from_json(json_config)
实例
import gzip
import numpy as np
import tensorflow as tf
def get_data():
# 文件获取
train_image = r"../../dataset/fashion-mnist/train-images-idx3-ubyte.gz"
test_image = r"../../dataset/fashion-mnist/t10k-images-idx3-ubyte.gz"
train_label = r"../../dataset/fashion-mnist/train-labels-idx1-ubyte.gz"
test_label = r"../../dataset/fashion-mnist/t10k-labels-idx1-ubyte.gz" # 文件路径
paths = [train_label, train_image, test_label, test_image]
with gzip.open(paths[0], 'rb') as lbpath:
y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[1], 'rb') as imgpath:
x_train = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
with gzip.open(paths[2], 'rb') as lbpath:
y_test = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[3], 'rb') as imgpath:
x_test = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
return (x_train, y_train), (x_test, y_test)
(train_image, train_label), (test_image, test_label) = get_data()
train_image = train_image / 255
test_image = test_image / 255
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28, 28))) # 28*28
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
print(model.summary())
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['acc']
)
model.fit(train_image, train_label, epochs=3)
print(model.evaluate(test_image, test_label, verbose=0))
model_json = model.to_json()
with open('model.json', 'w') as file:
file.write(model_json)
with open('model.json', 'r') as file:
json_config = file.read()
reinitialized_model = tf.keras.models.model_from_json(json_config)
reinitialized_model.summary()
reinitialized_model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['acc']
)
print(reinitialized_model.evaluate(test_image, test_label, verbose=0))
仅保存权重
有时我们只需要保存模型的状态(其权重值),而对模型架构不感兴趣。在这种情况下,可以通过get_weights()获取权重值,并通过set_weights()设置权重值
保存权重
model.save_weights('less_weights.h5')
读取权重
reinitialized_model.load_weights('less_weights.h5')
实例
import numpy as np
import tensorflow as tf
import gzip
import gzip
import numpy as np
import tensorflow as tf
def get_data():
# 文件获取
train_image = r"../../dataset/fashion-mnist/train-images-idx3-ubyte.gz"
test_image = r"../../dataset/fashion-mnist/t10k-images-idx3-ubyte.gz"
train_label = r"../../dataset/fashion-mnist/train-labels-idx1-ubyte.gz"
test_label = r"../../dataset/fashion-mnist/t10k-labels-idx1-ubyte.gz" # 文件路径
paths = [train_label, train_image, test_label, test_image]
with gzip.open(paths[0], 'rb') as lbpath:
y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[1], 'rb') as imgpath:
x_train = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
with gzip.open(paths[2], 'rb') as lbpath:
y_test = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[3], 'rb') as imgpath:
x_test = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
return (x_train, y_train), (x_test, y_test)
(train_image, train_label), (test_image, test_label) = get_data()
train_image = train_image / 255
test_image = test_image / 255
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28, 28))) # 28*28
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
print(model.summary())
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['acc']
)
model.fit(train_image, train_label, epochs=3)
print(model.evaluate(test_image, test_label, verbose=0))
model.save_weights('less_weights.h5')
with open('model.json', 'r') as file:
json_config = file.read()
reinitialized_model = tf.keras.models.model_from_json(json_config)
reinitialized_model.summary()
reinitialized_model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['acc']
)
reinitialized_model.load_weights('less_weights.h5')
print(reinitialized_model.evaluate(test_image, test_label, verbose=0))
保存检查点
在训练期间或训练结束时自动保存检查点。这样一来,您便可以使用经过训练的模型,而无需重新训练该模型,或从上次暂停的地方继续训练,以防训练过程中断。
保存检查点
checkpoint_path = 'training_cp/cp.ckpt'
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path,
save_weights_only=True)
# 在训练时使用回调函数指定
model.fit(train_image, train_label, epochs=3, callbacks=[cp_callback])
读取检查点
model.load_weights(checkpoint_path)
实例
import numpy as np
import tensorflow as tf
import gzip
import gzip
import numpy as np
import tensorflow as tf
def get_data():
# 文件获取
train_image = r"../../dataset/fashion-mnist/train-images-idx3-ubyte.gz"
test_image = r"../../dataset/fashion-mnist/t10k-images-idx3-ubyte.gz"
train_label = r"../../dataset/fashion-mnist/train-labels-idx1-ubyte.gz"
test_label = r"../../dataset/fashion-mnist/t10k-labels-idx1-ubyte.gz" # 文件路径
paths = [train_label, train_image, test_label, test_image]
with gzip.open(paths[0], 'rb') as lbpath:
y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[1], 'rb') as imgpath:
x_train = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
with gzip.open(paths[2], 'rb') as lbpath:
y_test = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[3], 'rb') as imgpath:
x_test = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
return (x_train, y_train), (x_test, y_test)
(train_image, train_label), (test_image, test_label) = get_data()
train_image = train_image / 255
test_image = test_image / 255
checkpoint_path = 'training_cp/cp.ckpt'
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path,
save_weights_only=True)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28))) # 28*28
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['acc']
)
# model.fit(train_image, train_label, epochs=3, callbacks=[cp_callback])
# print(model.evaluate(test_image, test_label, verbose=0))
model.load_weights(checkpoint_path)
print(model.evaluate(test_image, test_label, verbose=0))
自定义训练中保存检查点
import datetime
import gzip
import os
import numpy as np
import tensorflow as tf
# 创建常量
v = tf.Variable(0.0)
# 通过assign改变常量的值
v.assign(5)
# 通过assign_add将变量+1
v.assign_add(1)
# print(v)
# print(v.read_value().numpy())
# w = tf.Variable([[1.0]])
# with tf.GradientTape() as t:
# loss = w * w
# grad = t.gradient(loss, w)
# print(grad)
# 常量需要添加监听
# ww = tf.constant(3.0)
# with tf.GradientTape() as t:
# t.watch(ww)
# loss = ww * ww
# grad = t.gradient(loss, ww)
# print(grad)
# 通过persistent=Ture永久的记录计算
# w = tf.constant(3.0)
# with tf.GradientTape(persistent=True) as t:
# t.watch(w)
# y = w * w
# z = y * y
# dy_dw = t.gradient(y, w)
# print(dy_dw)
# dz_dw = t.gradient(z, w)
# print(dz_dw)
def get_data():
# 文件获取
train_image = r"../../dataset/fashion-mnist/train-images-idx3-ubyte.gz"
test_image = r"../../dataset/fashion-mnist/t10k-images-idx3-ubyte.gz"
train_label = r"../../dataset/fashion-mnist/train-labels-idx1-ubyte.gz"
test_label = r"../../dataset/fashion-mnist/t10k-labels-idx1-ubyte.gz" # 文件路径
paths = [train_label, train_image, test_label, test_image]
with gzip.open(paths[0], 'rb') as lbpath:
y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[1], 'rb') as imgpath:
x_train = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
with gzip.open(paths[2], 'rb') as lbpath:
y_test = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(paths[3], 'rb') as imgpath:
x_test = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
return (x_train, y_train), (x_test, y_test)
(train_image, train_label), (test_image, test_label) = get_data()
train_image = tf.expand_dims(train_image, -1)
test_image = tf.expand_dims(test_image, -1)
print(train_image.shape)
train_image = tf.cast(train_image / 255, tf.float32)
test_image = tf.cast(test_image / 255, tf.float32)
train_label = tf.cast(train_label, tf.int64)
test_label = tf.cast(test_label, tf.int64)
dataset = tf.data.Dataset.from_tensor_slices((train_image, train_label))
test_dataset = tf.data.Dataset.from_tensor_slices((test_image, test_label))
dataset = dataset.shuffle(10000).batch(32)
test_dataset = test_dataset.batch(32)
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(16, [3, 3], activation='relu', input_shape=(None, None, 1)),
tf.keras.layers.Conv2D(32, [3, 3], activation='relu'),
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.Dense(10)
])
optimizer = tf.keras.optimizers.Adam()
# 顺序编码使用SparseCategoricalCrossentropy,最后一层没有激活使用from_logits=True
loss_func = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
# 取出一个批次
fratures, labels = next(iter(dataset))
predictions = model(fratures)
# 在第一个维度查看predictions最大值
print(tf.argmax(predictions, axis=1))
train_loss = tf.keras.metrics.Mean('train_loss')
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('train_accuracy')
test_loss = tf.keras.metrics.Mean('test_loss')
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('test_accuracy')
# -----------------第一步-----------------------------
# 创建文件编写器
current_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
train_log_dir = 'tensorboard/logs/' + current_time + '/train'
test_log_dir = 'tensorboard/logs/' + current_time + '/test'
train_summary_writer = tf.summary.create_file_writer(train_log_dir)
test_summary_writer = tf.summary.create_file_writer(test_log_dir)
cp_dir = './customtrain_cp'
cp_prefix = os.path.join(cp_dir, 'ckpt')
checkpoint = tf.train.Checkpoint(optimizer=optimizer,
model=model
)
def loss(model, x, y):
y_ = model(x)
return loss_func(y, y_)
# 对一个batchsh数据进行优化
def train_step(model, images, labels):
# 计算损失值
with tf.GradientTape() as t:
pred = model(images)
loss_step = loss_func(labels, pred)
# 计算梯度
grads = t.gradient(loss_step, model.trainable_variables)
# 优化
optimizer.apply_gradients(zip(grads, model.trainable_variables))
train_loss(loss_step)
# 第一个参数为正确结果,第二个参数为预测结果
train_accuracy(labels, pred)
# 对一个batchsh数据进行优化
def test_step(model, images, labels):
# 计算损失值
pred = model(images)
loss_step = loss_func(labels, pred)
test_loss(loss_step)
# 第一个参数为正确结果,第二个参数为预测结果
test_accuracy(labels, pred)
# 对每一个循环进行训练
def train():
for epoch in range(3):
for (batch, (images, labels)) in enumerate(dataset):
train_step(model, images, labels)
# -----------------第二步-----------------------------
# 保存训练的loss和acc
train_summary_writer.set_as_default()
tf.summary.scalar('loss', train_loss.result(), step=epoch)
tf.summary.scalar('acc', train_accuracy.result(), step=epoch)
for (batch, (images, labels)) in enumerate(test_dataset):
test_step(model, images, labels)
# -----------------第三步-----------------------------
# 保存测试的loss和acc
test_summary_writer.set_as_default()
tf.summary.scalar('loss', test_loss.result(), step=epoch)
tf.summary.scalar('acc', test_accuracy.result(), step=epoch)
print('Epoch{} loss is {},accuracy is {},test_loss is {},test_accuracy is {}'.format(epoch, train_loss.result(),
train_accuracy.result(),
test_loss.result(),
test_accuracy.result()))
# 重置状态
train_loss.reset_states()
train_accuracy.reset_states()
test_loss.reset_states()
test_accuracy.reset_states()
if (epoch + 1) % 2 == 0:
checkpoint.save(file_prefix=cp_prefix)
# train()
# 汇总计算模块
m = tf.keras.metrics.Mean('acc')
m(10)
m([10, 2, 34, 34])
m.result().numpy()
# 重置指标计算模块状态
m.reset_states()
a = tf.keras.metrics.SparseCategoricalAccuracy('acc')
a(labels, model(fratures))
# 恢复检查点
checkpoint.restore(tf.train.latest_checkpoint(cp_dir))
# 查看准确率
print((tf.argmax(model(train_image, training=False), axis=-1).numpy() == train_label).sum()/len(train_label))