下面是详细讲解“keras模型保存为tensorflow的二进制模型方式”的完整攻略。
1. 模型训练
首先,我们需要使用Keras框架进行模型的训练。这里我们以一个简单的手写体数字识别模型为例:
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras import backend as K
batch_size = 128
num_classes = 10
epochs = 12
# input image dimensions
img_rows, img_cols = 28, 28
# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()
if K.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
# convert class vectors to binary class matrices
y_train = tf.keras.utils.to_categorical(y_train, num_classes)
y_test = tf.keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.Adadelta(),
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
这里我们使用了两层卷积神经网络,Dropout和全连接层。我们训练好了模型后,需要将其保存为 TensorFlow 的二进制模型。
2. 保存模型
TensorFlow提供了两个API来保存模型:SavedModel和tf.train.Checkpoint。这里我们主要介绍SavedModel。
SavedModel是序列化模型的格式,可以将模型的结构、权重和训练配置保存为文件夹。使用SavedModel格式保存模型有以下几个步骤:
2.1 路径设置
创建一个用于保存模型的文件夹路径:
import os
# 创建文件夹
export_path = './saved_model'
if os.path.isdir(export_path):
print('已经存在')
else:
os.mkdir(export_path) # 如果文件夹不存在,则创建
2.2 保存模型
使用 tf.keras.models.save_model()
函数将模型保存到文件夹路径中,并设置 save_format='tf'
参数。
tf.keras.models.save_model(
model,
export_path,
save_format='tf'
)
这会将模型及其所有权重和配置保存到文件夹路径中。
2.3 恢复模型
要使用保存的模型,可以使用 tf.keras.models.load_model() 函数,其参数是保存的文件夹路径:
loaded_model = tf.keras.models.load_model(export_path)
这将返回一个与保存模型相同的模型对象。可以使用该模型对象完成推断或微调等后续操作。
3. 示例说明
下面给出两个示例说明:
3.1 保存和恢复MNIST模型
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras import backend as K
import os
batch_size = 128
num_classes = 10
epochs = 12
# input image dimensions
img_rows, img_cols = 28, 28
# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()
if K.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
# convert class vectors to binary class matrices
y_train = tf.keras.utils.to_categorical(y_train, num_classes)
y_test = tf.keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.Adadelta(),
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
# 保存模型
export_path = './saved_model/mnist'
if not os.path.exists(export_path):
os.makedirs(export_path)
tf.keras.models.save_model(model, export_path, save_format='tf')
# 加载模型
loaded_model = tf.keras.models.load_model(export_path)
# 用测试数据进行推断
score = loaded_model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
3.2 保存和恢复CIFAR10模型
import tensorflow as tf
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Conv2D, Dense, Flatten, MaxPooling2D
from tensorflow.keras.models import Sequential
import os
# 加载 CIFAR-10 数据集
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# 数据预处理,将像素值缩放到 [0, 1] 区间
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
# 将类别标签转换为 one-hot 向量
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
# 构建模型
model = Sequential([
Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
Conv2D(32, (3, 3), activation='relu'),
MaxPooling2D(pool_size=(2, 2)),
Dropout(0.25),
Conv2D(64, (3, 3), activation='relu'),
Conv2D(64, (3, 3), activation='relu'),
MaxPooling2D(pool_size=(2, 2)),
Dropout(0.25),
Flatten(),
Dense(512, activation='relu'),
Dropout(0.5),
Dense(10, activation='softmax'),
])
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=64,
epochs=10,
validation_data=(x_test, y_test))
# 保存模型
export_path = './saved_model/cifar10'
if not os.path.exists(export_path):
os.makedirs(export_path)
tf.keras.models.save_model(model, export_path, save_format='tf')
# 加载模型
loaded_model = tf.keras.models.load_model(export_path)
# 用测试数据进行推断
score = loaded_model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
以上两个示例代码中,我们都先用Keras训练了一个模型,然后将模型保存为 TensorFlow 的二进制模型格式。再用 tf.keras.models.load_model()
加载保存的模型,并用测试数据进行推断。这里的方法可以适用于大多数Keras模型。