Tensorflow2.0 Keras之模型装配

Tensorflow2.0 Keras之模型装配

模型装配

在 Keras 中,有2 个比较特殊的类:keras.Model 和keras.layers.Layer 类。其中Layer类是网络层的母类,定义了网络层的一些常见功能,如添加权值、管理权值列表等。Model 类是网络的母类,除了具有Layer 类的功能,还添加了保存模型、加载模型、训练与测试模型等便捷功能。Sequential 也是Model 的子类,因此具有Model 类的所有功能。

创建网络层

接下来介绍Model 及其子类的模型装配与训练功能。我们以Sequential 容器封装的网络为例,首先创建5 层的全连接网络,用于MNIST 手写数字图片识别,代码如下:

network = Sequential([layers.Dense(256, activation='relu'),
layers.Dense(128, activation='relu'),
layers.Dense(64, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(10)])
network.build(input_shape=(4, 28*28))

模型装配

创建网络后,正常的流程是循环迭代数据集多个Epoch,每次按批产生训练数据、前向计算,然后通过损失函数计算误差值,并反向传播自动计算梯度、更新网络参数。这一部分逻辑由于非常通用,在Keras 中提供了compile()和fit()函数方便实现上述逻辑。首先通过compile 函数指定网络使用的优化器对象、损失函数类型,评价指标等设定,这一步称为装配。例如:

# 导入优化器,损失函数模块
from tensorflow.keras import optimizers,losses
# 模型装配
# 采用Adam 优化器,学习率为0.01;采用交叉熵损失函数,包含Softmax
network.compile(optimizer=optimizers.Adam(lr=0.01),
loss=losses.CategoricalCrossentropy(from_logits=True),
metrics=['accuracy'] # 设置测量指标为准确率
)

在compile()函数中指定的优化器、损失函数等参数也是我们自行训练时需要设置的参数,并没有什么特别之处,只不过Keras 将这部分常用逻辑内部实现了,提高开发效率。

模型训练

模型装配完成后,即可通过fit()函数送入待训练的数据集和验证用的数据集,这一步称为模型训练。例如:

# 指定训练集为train_db,验证集为val_db,训练5 个epochs,每2 个epoch 验证一次
# 返回训练轨迹信息保存在history 对象中
history = network.fit(train_db, epochs=5, validation_data=test_db,
validation_freq=2)

注:这里是train_db和test_db 是通过mnist手写数据集加载过来的下面是加载的代码

from tensorflow.keras import datasets
def preprocess(x, y):
    """
    预处理函数
    """
    # [b, 28, 28], [b]
    print(x.shape, y.shape)
    x = tf.cast(x, dtype=tf.float32) / 255.
    x = tf.reshape(x, [-1, 28 * 28])  # 将图片打平
    y = tf.cast(y, dtype=tf.int32)
    y = tf.one_hot(y, depth=10)
    return x, y


(x, y), (x_test, y_test) = datasets.mnist.load_data()  # 加载手写数据集数据
print('x:', x.shape, 'y:', y.shape, 'x test:', x_test.shape, 'y test:', y_test)

batchsz = 512
train_db = tf.data.Dataset.from_tensor_slices((x, y))  # 转化为Dataset对象
train_db = train_db.shuffle(1000)  # 随机打散
train_db = train_db.batch(batchsz)  # 批训练
train_db = train_db.map(preprocess)  # 数据预处理
train_db = train_db.repeat(20)  # 复制20份数据
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_db = test_db.shuffle(1000).batch(batchsz).map(preprocess)

fit()函数的运行代表了网络的训练过程,因此会消耗相当的训练时间,并在训练结束后才返回,训练中产生的历史数据可以通过返回值对象取得。可以看到通过compile&fit 方式实现的代码非常简洁和高效,大大缩减了开发时间。但是因为接口非常高层,灵活性也降低了,是否使用需要用户自行判断。

模型测试

Model 基类除了可以便捷地完成网络的装配与训练、验证,还可以非常方便的预测和测试。关于验证和测试的区别,我们会在过拟合一章详细阐述,此处可以将验证和测试理解为模型评估的一种方式。
通过 Model.predict(x)方法即可完成模型的预测,例如:

# 加载一个batch 的测试数据
x,y = next(iter(db_test))
print('predict x:', x.shape) # 打印当前batch 的形状
out = network.predict(x) # 模型预测,预测结果保存在out 中

其中out 即为网络的输出。通过上述代码即可使用训练好的模型去预测新样本的标签信息。

如果只是简单的测试模型的性能,可以通过Model.evaluate(db)循环测试完db 数据集上所有样本,并打印出性能指标,例如:

network.evaluate(db_test) # 模型测试,测试在db_test 上的性能表现

注:db_test 并不是之前加载的测试集,而是一组新的数据,也可以理解为实际运用的数据集

发布了62 篇原创文章 · 获赞 33 · 访问量 3475

猜你喜欢

转载自blog.csdn.net/python_LC_nohtyp/article/details/104272862