keras模型保存为tensorflow的二进制模型方式

  • Post category:Python

下面是详细讲解“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模型。