当前位置:   article > 正文

TensorFlow----Keras库_tensorflow.keras

tensorflow.keras

目录

 1.网络层类

2.网络容器

3.模型装配

4.模型训练

5.模型测试

6.模型保存

(1)张量方式

(2)网络方式

(3)SavedModel方式

7.自定义网络

(1)自定义网络层

(2)自定义网络

8.测量工具

(1)构造测量器

(2)写入数据

(3)读取统计信息

(4)清除状态

9.可视化

(1)模型端

(2)浏览器端


参考来源:主页 - Keras 中文文档

Keras 提供了一系列高层的神经网络相关类和函数,如经典数据集加载函数、 网络层
类、 模型容器、 损失函数类、 优化器类、 经典模型类等

 导入keras,只能从tensorflow中导入,否则导入的是标准的Keras库 :

from tensorflow import keras

 1.网络层

        对于常见的网络层,一般直接使用层方式来完成模型的搭建,在 tf.keras.layers 命名空间中提供了大量常见网络层的类,如全连接层、 激活函数层、 池化层、 卷积层、 循环神经网络层

        网络层类,只需要在创建时指定网络层的相关参数, 并调用__call__方法即可完成前向计算。在调用__call__方法时, Keras 会自动调用每个层的前向传播逻辑,这些逻辑一般实现在类的
call 函数中

eg: 通过 layers.Softmax(axis)类搭建 Softmax 网络层

  1. import tensorflow as tf
  2. from tensorflow import keras # 导入keras,只能从tf中导入,否则导入的是标准的Keras库
  3. from tensorflow.keras import layers # 导入网络层类
  4. # 创建 Softmax 层,并调用__call__方法完成前向计算
  5. x = tf.constant([2., 1.0, 0.1]) # 创建张量
  6. layer = layers.Softmax(axis=-1) # 创建Softmax层
  7. out = layer(x) # 向前计算,其实是调用的call
  8. print(out)

直接调用tf.nn.softmax()函数也是一样的效果

out = tf.nn.softmax(x)

2.网络容器

对于常见的网络,需要手动调用每一层的类实例完成前向传播运算,当网络层数变得
较深时, 这一部分代码显得非常臃肿。可以通过 Keras 提供的网络容器 Sequential 将多个
网络层封装成一个大网络模型,只需要调用网络模型的实例一次即可完成数据从第一层到
最末层的顺序传播运算

eg: 2层的全连接层和激活函数层

  1. import tensorflow as tf
  2. from tensorflow import keras # 导入keras,只能从tf中导入,否则导入的是标准的Keras库
  3. from tensorflow.keras import layers, Sequential
  4. # 封装一个大型网络
  5. network = Sequential([
  6. layers.Dense(3, activation=None), # 全连接层,不用激活函数
  7. layers.ReLU(), # 激活函数层
  8. layers.Dense(2, activation=None),
  9. layers.ReLU() # 激活函数层
  10. ])
  11. x = tf.random.normal([4, 3])
  12. out = network(x) # 调用call(),输入从第一层开始, 逐层传播至输出层,并返回输出层的输出
  13. network.build(input_shape=(4, 4)) # 创建网络层参数
  14. network.summary() # 打印出网络结构和参数量

通过 add()方法继续追加新的网络层, 实现动态创建网络的功能

  1. layers_num = 2 # 堆叠 2 次
  2. network = Sequential([]) # 先创建空的网络容器
  3. for _ in range(layers_num):
  4. network.add(layers.Dense(3)) # 添加全连接层
  5. network.add(layers.ReLU()) # 添加激活函数层

注意,在通过Sequential容器创建对应层数的网络结构,在完成网络创建时, 网络层类并没有创建内部权值张量等成员变量此时通过调用类的 build 方法并指定输入大小,即可自动创建所有层的内部张量。

通过 summary()函数可以方便打印出网络结构和参数量

输出结果:


 

Layer 列为每层的名字,这个名字由 TensorFlow 内部维护,与 Python 的对象名并不一样。 Param#列为层的参数个数, Total params 项统计出了总的参数量, Trainable params
为总的待优化参数量, Non-trainable params 为总的不需要优化的参数量

当通过 Sequential 容量封装多个网络层时, 每层的参数列表将会自动并入Sequential 容器的参数列表中。 Sequential 对象的 trainable_variablesvariables 包含了所有层的待优化张量列表
全部张量列表

  1. # 打印网络的待优化参数名与shape
  2. for item in network.trainable_variables:
  3. print(item.name, item.shape)
  4. '''
  5. dense/kernel:0 (3, 3)
  6. dense/bias:0 (3,)
  7. dense_1/kernel:0 (3, 2)
  8. dense_1/bias:0 (2,)
  9. '''

3.模型装配

在训练网络时,一般的流程是通过前向计算获得网络的输出值, 再通过损失函数计算网络误差,然后通过自动求导工具计算梯度并更新,同时间隔性地测试网络的性能

对于这种常用的训练逻辑,可以直接通过 Keras 提供的模型装配与训练等高层接口实现

在 Keras 中,有 2 个比较特殊的类: keras.Model keras.layers.Layer 类其中 Layer类是网络层的母类,定义了网络层的一些常见功能,如添加权值、 管理权值列表等。

Model 类是网络的母类,除了具有 Layer 类的功能,还添加了保存模型、加载模型、 训练
与测试模型等便捷功能

 Sequential 也是 Model 的子类, 因此具有 Model 类的所有功能
 

在创建网络后,正常的流程是循环迭代数据集多个 Epoch,每次按批产生训练数据、 前向计
算,然后通过损失函数计算误差值,并反向传播自动计算梯度、 更新网络参数

在 Keras 中提供了 compile()和 fit()函数方便实现上述逻辑。 首先通过compile 函数指定网络使用的优化器对象 损失函数类型 评价指标等设定,这一步称为装配
 

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

4.模型训练

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

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

其中 train_db 为 tf.data.Dataset 对象;epochs 参数指定训练迭代的 Epoch 数量;validation_data 参数指定用于验证(测试)的数据集验证的频率validation_freq
 

上述代码即可实现网络的训练与验证的功能, fit 函数会返回训练过程的数据记录history, 其中 history.history 为字典对象,包含了训练过程中的 loss、 测量指标等记录项,可以直接查看这些训练数据:history.history

fit()函数的运行代表了网络的训练过程,因此会消耗相当的训练时间,并在训练结束后才返回,训练中产生的历史数据可以通过返回值对象取得

可以看到通过 compile&fit 方式实现的代码非常简洁和高效,大大缩减了开发时间
 

5.模型测试

Model 基类除了可以便捷地完成网络的装配与训练、验证,还可以预测和测试。通过 Model.predict(x)方法即可完成模型的预测

  1. x,y = next(iter(db_train))
  2. print('predict x:', x.shape) # 打印当前 batch 的形状
  3. out = network.predict(x) # 模型预测,预测结果保存在 out 中
  4. print(out)

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

可以通过 Model.evaluate()测试模型的性能指标

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


 

6.模型保存

模型训练完成后,需要将模型保存到文件系统上,从而方便后续的模型测试与部署工作。 如果能够间断地保存模型状态到文件系统,即使发生宕机等意外,也可以从最近一次的网络状态文件中恢复,从而避免浪费大量的训练时间和计算资源

(1)张量方式

网络的状态主要体现在网络的结构以及网络层内部张量数据上,因此在拥有网络结构源文件的条件下,直接保存网络张量参数到文件系统上是最轻量级的一种方式
 

通过调用 Model.save_weights(path)方法即可将当前的网络参数保存到 path 文件
 

  1. # 保存模型参数到文件上
  2. network.save_weights('weights.ckpt')
  3. ....
  4. # 重新搭建相同的网络结构
  5. ...
  6. # 从参数文件中读取数据并写入当前网络
  7. network.load_weights('weights.ckpt')

这种保存与加载网络的方式最为轻量级, 文件中保存的仅仅是张量参数的数值,并没有其它额外的结构参数。 但是它需要使用相同的网络结构才能够正确恢复网络状态,因此一般在拥有网络源文件的情况下使用

(2)网络方式

通过 Model.save(path)函数可以将模型的结构以及模型的参数保存到 path 文件上在需要网络源文件的条件下,通过 keras.models.load_model(path)即可恢复网络结构和网络参数

  1. # 保存模型结构与模型参数到文件
  2. network.save('model.h5')
  3. del network # 删除网络对象
  4. # 从文件恢复网络结构与网络参数
  5. network = keras.models.load_model('model.h5')

model.h5 文件除了保存了模型参数外还应保存了网络结构信息,不需要提前创建模型即可直接从文件中恢复出网络 network 对象

(3)SavedModel方式

通过 tf.saved_model.save (network, path)即可将模型以 SavedModel 方式保存到 path 目录中
 

  1. # 保存模型结构与模型参数到文件
  2. tf.saved_model.save(network, 'model-savedmodel')
  3. del network # 删除网络对象
  4. network = tf.saved_model.load('model-savedmodel')

用户无需关心文件的保存格式,只需要通过 tf.saved_model.load 函数即可恢复出模型对象
 

7.自定义网络

对于需要创建自定义逻辑的网络层,可以通过自定义类来实现。在创建自定义网络层类时,需要继承自 layers.Layer 基类; 创建自定义的网络类时,需要继承自 keras.Model 基类, 这样建立的自定义类才能够方便的利用 Layer/Model 基类提供的参数管理等功能,同时也能够与其他的标准网络层类交互使用
 

(1)自定义网络层

对于自定义的网络层, 至少需要实现初始化__init__方法前向传播逻辑 call 方法

假设需要一个没有偏置向量的全连接层,即 bias 为0, 同时固定激活函数为 ReLU 函数
 

  1. # 自定义网络层
  2. class MyDence(layers.Layer):
  3. # 自定义类的初始化
  4. def __init__(self, inp_dim, outp_dim):
  5. # 继承父类,并定义新功能 super
  6. super(MyDence, self).__init__()
  7. # 创建权值张量并添加到类管理列表中,设置为需要优化
  8. self.kernel = self.add_variable('w', [inp_dim, outp_dim], trainable=True)
  9. # self.bias = self.add_variable('b', [outp_dim])
  10. # 自定义类的向前计算逻辑
  11. def call(self, inputs, training=None):
  12. # X@W
  13. out = inputs @ self.kernel
  14. # 添加激活函数relu
  15. out = tf.nn.relu(out)
  16. return out
  17. # 创建自定义层类的实例化
  18. net = MyDence(4, 3) # 输入为4,输出为3个节点

首先创建类,并继承自 Layer 基类。 创建初始化方法,并调用母类的初始化函数, 由于是全连接层, 因此需要设置两个参数:输入特征的长度 inp_dim 输出特征的长度outp_dim,并通过 self.add_variable(name, shape)创建 shape 大小,名字为 name 的张量

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/47331
推荐阅读
相关标签