本主题主要阐述下Keras框架中的模型Model的使用,主要包含的内容:
  1.模型的两种使用方式;
  2.经典模型的实现(定制模型);
  3.模型的定制训练;

一. 模型使用的两种方式

  • Keras通过两个API提供两种计算模型:

    • 函数式模型:通过Model类API;
    • 顺序式模型:通过Sequential类API;
  • 本文的业务背景还是是深度全链接网络;
    实现4 -> 8 -> 4 -> 1网络。

1. 函数式模型

  • 函数式模型的编程特点是:

    1. 程序员构建层,通过Layer对象的可调用特性,或者使用apply与call实现链式函数调用;
    2. Model只需要通过inputs与outputs;
  • 这种模式之所以称为函数式模型,是因为Layer提供了几种函数式调用方式,通过这种调用建立层之间的网络模型。
    1. Layer是可调用对象,提供__call__可调用运算符(...)
    2. apply函数;
  1. 函数式模型的示意图

  2. 函数式模型的示例代码 - 使用Layer的可调用运算
    # Author:Louis Young
    # Note:使用Iris数据集,构建的4-8-4-1的全链接神经网络
    import tensorflow as tf
    import tensorflow.keras as keras
    import tensorflow.keras.layers as layers
    import sklearn.datasets as datasets# 1. 定义Layer层;
    #   1.1. 输入层:必须是InputLayer或者Input创建的Tensor;
    input_layer = keras.Input(shape=(4,))   # 4是Iris的特征维数(4个特征:可以参考sklearn中关于iris数据集的特征说明)
    #   1.2. 隐藏层:8-4
    hide1_layer = layers.Dense(units=8, activation='relu')
    hide2_layer = layers.Dense(units=4, activation='relu')
    #   1.3. 输出层:1
    output_layer = layers.Dense(units=1, activation='sigmoid')#  2. 构建Layer之间的函数链式关系
    hide1_layer_tensor = hide1_layer(input_layer)      # <----------------------使用可调用特性
    hide2_layer_tensor = hide2_layer(hide1_layer_tensor)
    output_layer_tensor = output_layer(hide2_layer_tensor)# 3. 使用inputs与outputs建立函数链式模型;
    model = keras.Model(inputs=input_layer, outputs=output_layer_tensor)   # inputs与outputs一定是Layer调用输出的张量# 4. 训练
    #   4.1. 训练参数
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['mse'])
    #   4.2. 训练
    data, target = datasets.load_iris(return_X_y=True)
    data = data[:100, :]   # 取前面100个样本(第一类与第二类)
    target = target[:100]
    model.fit(x=data, y=target, batch_size=10, epochs=1000, verbose=0)
    #   4.3. 预测与评估
    # 6.预测
    pre_result = model.predict(data)
    category = [0 if item<=0.5 else 1 for item in pre_result ]
    accuracy = (target == category).mean()
    print(F'分类准确度:{accuracy *100.0:5.2f}%', )
    分类准确度:100.00%
  3. 函数式模型的示例代码-使用Layer的apply函数
    apply函数实际是__call__运算符的别名。

    # Author:Louis Young
    # Note:使用Iris数据集,构建的4-8-4-1的全链接神经网络
    import tensorflow as tf
    import tensorflow.keras as keras
    import tensorflow.keras.layers as layers
    import sklearn.datasets as datasets# 1. 定义Layer层;
    #   1.1. 输入层:必须是InputLayer或者Input创建的Tensor;
    input_layer = keras.Input(shape=(4,))   # 4是Iris的特征维数(4个特征:可以参考sklearn中关于iris数据集的特征说明)
    #   1.2. 隐藏层:8-4
    hide1_layer = layers.Dense(units=8, activation='relu')
    hide2_layer = layers.Dense(units=4, activation='relu')
    #   1.3. 输出层:1
    output_layer = layers.Dense(units=1, activation='sigmoid')#  2. 构建Layer之间的函数链式关系
    hide1_layer_tensor = hide1_layer.apply(input_layer)            # <----------------------使用apply
    hide2_layer_tensor = hide2_layer.apply(hide1_layer_tensor)
    output_layer_tensor = output_layer.apply(hide2_layer_tensor)
    # 3. 使用inputs与outputs建立函数链式模型;
    model = keras.Model(inputs=input_layer, outputs=output_layer_tensor)   # inputs与outputs一定是Layer调用输出的张量# 4. 训练
    #   4.1. 训练参数
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['mse'])
    #   4.2. 训练
    data, target = datasets.load_iris(return_X_y=True)
    data = data[:100, :]   # 取前面100个样本(第一类与第二类)
    target = target[:100]
    model.fit(x=data, y=target, batch_size=10, epochs=1000, verbose=0)
    #   4.3. 预测与评估
    # 5.预测
    pre_result = model.predict(data)
    category = [0 if item<=0.5 else 1 for item in pre_result ]
    accuracy = (target == category).mean()
    print(F'分类准确度:{accuracy *100.0:5.2f}%', )
    
Tensor("dense_29/Identity:0", shape=(None, 1), dtype=float32)
分类准确度:100.00%

2. 顺序式模型

顺序式模型的编程特点:

  1. Layer提供input与output属性;
  2. Sequential类通过Layer的input与output属性来维护层之间的关系,构建网络模型;
    • 第一个Layer必须是InputLayer或者Input函数构建的张量;

1.顺序式模型示意图

2.顺序式模型的示例代码-layers参数构建模型

# Author:Louis Young
# Note:使用Iris数据集,构建的4-8-4-1的全链接神经网络
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
import sklearn.datasets as datasets# 1. 构建Layer层
# 1. 定义Layer层;
#   1.1. 输入层:必须是InputLayer或者Input创建的Tensor;
input_layer = keras.Input(shape=(4,))   # 4是Iris的特征维数(4个特征:可以参考sklearn中关于iris数据集的特征说明)
#   1.2. 隐藏层:8-4
hide1_layer = layers.Dense(units=8, activation='relu')
hide2_layer = layers.Dense(units=4, activation='relu')
#   1.3. 输出层:1
output_layer = layers.Dense(units=1, activation='sigmoid')# 2. 使用Sequential构建顺序模型
seq_model = keras.Sequential(layers=[input_layer, hide1_layer, hide2_layer, output_layer])# -------------------下面部分与上面代码完全相同
# 3. 训练
#   3.1. 训练参数
seq_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['mse'])
#   3.2. 训练
data, target = datasets.load_iris(return_X_y=True)
data = data[:100, :]   # 取前面100个样本(第一类与第二类)
target = target[:100]
seq_model.fit(x=data, y=target, batch_size=10, epochs=1000, verbose=0)
#   3.3. 预测与评估
# 4.预测
pre_result = seq_model.predict(data)
category = [0 if item<=0.5 else 1 for item in pre_result ]
accuracy = (target == category).mean()
print(F'分类准确度:{accuracy *100.0:5.2f}%', )
分类准确度:100.00%

3.顺序式模型的示例代码-使用add方法构建模型

# Author:Louis Young
# Note:使用Iris数据集,构建的4-8-4-1的全链接神经网络
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
import sklearn.datasets as datasets# 1. 构建Layer层
# 1. 定义Layer层;
#   1.1. 输入层:必须是InputLayer或者Input创建的Tensor;
input_layer = keras.Input(shape=(4,))   # 4是Iris的特征维数(4个特征:可以参考sklearn中关于iris数据集的特征说明)
#   1.2. 隐藏层:8-4
hide1_layer = layers.Dense(units=8, activation='relu')
hide2_layer = layers.Dense(units=4, activation='relu')
#   1.3. 输出层:1
output_layer = layers.Dense(units=1, activation='sigmoid')# 2. 使用Sequential构建顺序模型
seq_model = keras.Sequential()
seq_model.add(input_layer)
seq_model.add(hide1_layer)
seq_model.add(hide2_layer)
seq_model.add(output_layer)# -------------------下面部分与上面代码完全相同
# 3. 训练
#   3.1. 训练参数
seq_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['mse'])
#   3.2. 训练
data, target = datasets.load_iris(return_X_y=True)
data = data[:100, :]   # 取前面100个样本(第一类与第二类)
target = target[:100]
seq_model.fit(x=data, y=target, batch_size=10, epochs=1000, verbose=0)
#   3.3. 预测与评估
# 4.预测
pre_result = seq_model.predict(data)
category = [0 if item<=0.5 else 1 for item in pre_result ]
accuracy = (target == category).mean()
print(F'分类准确度:{accuracy *100.0:5.2f}%', )
分类准确度:100.00%

4.Layer类input与output属性的意义

# Author:Louis Young
# Note:使用Iris数据集,构建的4-8-4-1的全链接神经网络
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
import sklearn.datasets as datasets# 1. 构建Layer层
# 1. 定义Layer层;
#   1.1. 输入层:必须是InputLayer或者Input创建的Tensor;
input_layer = keras.Input(shape=(4,))   # 4是Iris的特征维数(4个特征:可以参考sklearn中关于iris数据集的特征说明)
#   1.2. 隐藏层:8-4
hide1_layer = layers.Dense(units=8, activation='relu')
hide2_layer = layers.Dense(units=4, activation='relu')
#   1.3. 输出层:1
output_layer = layers.Dense(units=1, activation='sigmoid')# 2. 使用Sequential构建顺序模型
seq_model = keras.Sequential()
seq_model.add(input_layer)
seq_model.add(hide1_layer)# seq_model = keras.Sequential([input_layer, hide1_layer])   与上面三个语句的作用一样。# add方法本质也是自动调用Layer的可调用对象,只有调用后,Layer才具有input与output属性
print(hide1_layer.input)    # 可以注销22行。会出现错误,就可以理解add函数的作用。
Tensor("input_17:0", shape=(None, 4), dtype=float32)

二. 经典的模型实现-定制模型Model

专业的模型应用:建议子类化Model实现自己的模型。

1. 子类化Model说明

  • 模型的子类化,就是重载call函数。

    • call函数来自model的父类:tensorflow.python.keras.engine.base_layer.Layer

      • Model应该是特殊的Layer。
  • Mode的继承结构

        tf.keras.models.Model|- tensorflow.python.keras.engine.network.Network|- tensorflow.python.keras.engine.base_layer.Layer|- tensorflow.python.module.module.Module|- tensorflow.python.training.tracking.tracking.AutoTrackable

    通过继承 Model 类并在 call 方法中实现自己的前向传播,以创建自己的完全定制化的模型。注意:Model 类继承 API 引入于 Keras 2.2.0。

2. 使用定制Model构建模型

  1. 定制过程

    • 继承Model类;
    • 定制构造器,实现定制属性传递;
    • 定制call函数,实现模型的输出;
  2. 定制Model示例代码
    # Author:Louis Young
    # Note:使用Iris数据集,构建的4-8-4-1的全链接神经网络
    import tensorflow as tf
    import tensorflow.keras as keras
    import tensorflow.keras.layers as layers
    import sklearn.datasets as datasetsclass ModelException(Exception):def __init__(self, msg='模型构建异常'):self.message = msg# 1. 构建模型
    class IrisModel(keras.Model):# 构造器def __init__(self, networks):super(IrisModel, self).__init__(name='iris_model')# 判定参数类型是否是listif not isinstance(networks, list):raise ModelException('networks指定网络结构,类型是列表')# 生成networks属性self.networks = networks# 构建层self._layers = []for _net in networks[:-1]:  # 不考虑输入层layer = layers.Dense(units=_net, activation='relu')self._layers.append(layer)# 最后一层使用sigmoid函数layer = layers.Dense(units=networks[-1], activation='sigmoid')self._layers.append(layer)# forward方法:构建网络模型def call(self, inputs, **kwargs):# 根据层构建模型输出# 第一层的输入来自参数inputsx = self._layers[0](inputs)for _layer in self._layers[1:]:# 上一层输出作为下一层输入调用参数x = _layer(x)# 返回最后一层作为输出return x# 2. 创建模型实例
    model = IrisModel([8, 4, 1])  # 不包含输入的层4
    # ----------------------------------------< 以上为典型的模型构建方式。# 3. 定义训练参数
    model.compile(optimizer='adam',     # 指定优化器loss='binary_crossentropy',   # 指定损失函数metrics=['accuracy']
    )# 4. 数据加载
    data, target = datasets.load_iris(return_X_y=True)
    data = data[:100, :]   # 取前面100个样本(第一类与第二类)
    target = target[:100]
    # 5. 训练
    model.fit(x=data, y=target, batch_size=10, epochs=100, verbose=0)# 6.预测
    # pre_result = model.predict(data)
    pre_result = model(data)    # 与上一语句作用一样 predict函数等价于对象的调用
    category = [0 if item <= 0.5 else 1 for item in pre_result ]
    accuracy = (target == category).mean()
    print(F'分类准确度:{accuracy *100.0:5.2f}%', )
    分类准确度:100.00%

三. 模型的定制训练

  • 使用Model提供的compile与fit实现训练,确实很方便、易于阅读理解。但想提供更强大的训练控制,就需要理解Model的compile与fit函数实现的细节。

    • 这种细节实际上还是tensorflow的封装,下面我们从更加底层来了解模型的训练。
  • 我们提供一个例子,通过例子来解释模型的训练细节。

1. 定义训练参数

1.1. 优化器对象

  1. Adam构造器说明

    __init__(learning_rate=0.001,      # 学习率beta_1=0.9,beta_2=0.999,epsilon=1e-07,amsgrad=False,name='Adam',**kwargs)
  2. 优化器的优化调用
        apply_gradients(             # 梯度更新grads_and_vars,  name=None)
  3. 优化器创建代码
    import tensorflow.keras.optimizers as optimizers
    optimizer = optimizers.Adam(learning_rate=0.0001)

1.2. 损失对象

- 该对象是可调用对象,用来实现损失计算。
  1. CategoricalCrossentropy损失类的构造器说明:

    __init__(from_logits=False,label_smoothing=0,reduction=losses_utils.ReductionV2.AUTO,name='categorical_crossentropy')
  2. 可调用对象运算符说明
        __call__(y_true,        # 标签值y_pred,        # 预测值sample_weight=None)

    调用后,可以使用result函数获取结果。

  3. 损失对象构造

    import tensorflow.keras.losses as losses
    loss =losses.CategoricalCrossentropy()

1.3. 梯度计算

- 使用`tf.GradientTape`计算梯度
  1. 上下文环境

        __enter__()__exit__(typ,value,traceback
    )
  2. 计算梯度
    返回与sources一样的结构的梯度结构。

        gradient(target,                # 误差项sources,output_gradients=None,unconnected_gradients=tf.UnconnectedGradients.NONE)
  3. 梯度对象与梯度计算代码

    with tf.GradientTape() as tape:gradients = tape.gradient(loss,      # 损失张量(不是对象)model.trainable_variables)    # 需要更新的可训练权重张量

1.4. 评估度量

- 评估方式用来计算准确率,精准率,召回率等。
- 下面是Accuracy类的说明
  1. Accuracy构造器

        __init__(name='accuracy',dtype=None)
    

    可调用运算符
    Accuracy类的继承结构是:

        Accuracy|- MeanMetricWrapper|- Mean|- Reduce|- Metric|- tensorflow.python.keras.engine.base_layer.Layer
    

    其中可调用运算符定义:

        def __call__(self, *args, **kwargs):
    

    调用后,可以使用result函数获取结果。

    import tensorflow.keras.metrics as metrics
    metric = metrics.Accuracy()
    

2. 训练过程实现

实现步骤:

  1. 计算模型输出
  2. 计算损失值(损失张量,不是损失对象)
  3. 根据损失值,计算误差项
  4. 使用优化器更新梯度

2.1. 训练准备-创建模型

采用上面重复的代码:

# Author:Louis Young
# Note:使用Iris数据集,构建的4-8-4-1的全链接神经网络
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
import tensorflow.keras.optimizers as optimizers
import tensorflow.keras.losses as losses
import tensorflow.keras.metrics as metrics
import sklearn.datasets as datasetsclass ModelException(Exception):def __init__(self, msg='模型构建异常'):self.message = msg# 1. 构建模型
class IrisModel(keras.Model):# 构造器def __init__(self, networks):super(IrisModel, self).__init__(name='iris_model')# 判定参数类型是否是listif not isinstance(networks, list):raise ModelException('networks指定网络结构,类型是列表')# 生成networks属性self.networks = networks# 构建层self._layers = []for _net in networks[:-1]:  # 不考虑输入层layer = layers.Dense(units=_net, activation='relu')self._layers.append(layer)# 最后一层使用sigmoid函数layer = layers.Dense(units=networks[-1], activation='sigmoid')self._layers.append(layer)# forward方法:构建网络模型def call(self, inputs, **kwargs):# 根据层构建模型输出# 第一层的输入来自参数inputsx = self._layers[0](inputs)for _layer in self._layers[1:]:# 上一层输出作为下一层输入调用参数x = _layer(x)# 返回最后一层作为输出return x# 2. 创建模型实例
model = IrisModel([8, 4, 1])  # 不包含输入的层4
# ----------------------------------------< 以上为典型的模型构建方式。

2.2. 定义训练需要的对象

一般训练必须的对象

  • 优化器:optimizers
  • 损失:losses
  • 梯度计算:tf.GradientTape

可选的对象:如果需要在训练的时候,获取一些评估数据,则可以使用。

  • 评估度量:metrics
# 1. 优化器对象
optimizer = optimizers.Adam()
# 2. 损失计算对象
losser = losses.BinaryCrossentropy()
# 3. 准确率计算对象
accuracier = metrics.Accuracy()
# 4. 梯度计算对象  # GradientTape构建后只能调用一次,所以在with中使用
# tape = tf.GradientTape()

2.3. 训练实现

  1. 准备数据

    # 准备数据
    data, target = datasets.load_iris(return_X_y=True)
    data = data[:100, :]   # 取前面100个样本(第一类与第二类)
    target = target[:100]
    
  2. 训练
    epochs = 100
    batch_size = 10
    batch_num = int(math.ceil(len(data) / batch_size))
    
    for epoch in range(epochs):for i in range(len(data)):with tf.GradientTape() as tape:start_ = i * batch_sizeend_ = (i + 1) * batch_size# 计算输出predictions = model(data[start_: end_])# 计算损失loss_value = losser(target[start_: end_], predictions)# 计算梯度,不能在with中调用gradients = tape.gradient(loss_value, model.trainable_variables)# 更新权重optimizer.apply_gradients(zip(gradients, model.trainable_variables))pre_result = model(data)
    category = [0 if item <= 0.5 else 1 for item in pre_result ]
    accuracy = (target == category).mean()
    print(F'分类准确度:{accuracy *100.0:5.2f}%')
    print(pre_result)
    
分类准确度:100.00%
tf.Tensor(
[[0.05429551][0.06767229][0.06427257][0.06895139]...省略  [0.99639302][0.95713528][0.99546698]], shape=(100, 1), dtype=float64)

训练100轮,每轮批次大小10,批次数量是10,训练完成后(共训练次数是100*10=1000次),观察分类预测输出值,训练的效果还不错(因为是鸢尾花简单的数据集:D)

Keras的Model模型使用相关推荐

  1. keras系列︱Sequential与Model模型、keras基本结构功能(一)

    不得不说,这深度学习框架更新太快了尤其到了Keras2.0版本,快到Keras中文版好多都是错的,快到官方文档也有旧的没更新,前路坑太多. 到发文为止,已经有theano/tensorflow/CNT ...

  2. Keras Model模型方法

    Model模型方法 compile compile(self, optimizer, loss, metrics=None, loss_weights=None, sample_weight_mode ...

  3. 将keras的h5模型转化为onnx

    将keras的h5模型转化为onnx 先安装 pip install keras2onnx import keras import keras2onnx import onnx from keras. ...

  4. Sequential 顺序模型和 Model 模型【TensorFlow2入门手册】

    文章目录 Keras 模型 Sequential 顺序模型 Sequential 使用方法 Model 模型 Model 使用方法 Keras 模型 Keras提供的模型,其中分为两类: Sequen ...

  5. 2020-12-11 keras通过model.fit_generator训练模型(节省内存)

    keras通过model.fit_generator训练模型(节省内存) 前言 前段时间在训练模型的时候,发现当训练集的数量过大,并且输入的图片维度过大时,很容易就超内存了,举个简单例子,如果我们有2 ...

  6. DL之Keras:基于Keras框架建立模型实现【预测】功能的简介、设计思路、案例分析、代码实现之详细攻略(经典,建议收藏)

    DL之Keras:基于Keras框架建立模型实现[预测]功能的简介.设计思路.案例分析.代码实现之详细攻略(经典,建议收藏) 目录 Keras框架使用分析 Keras框架设计思路 案例分析 代码实现 ...

  7. 【Keras速成】Keras图像分类从模型自定义到测试

    文章首发于微信公众号<与有三学AI> [Keras速成]Keras图像分类从模型自定义到测试 这是给大家准备的Keras速成例子 这一次我们讲讲keras这个简单.流行的深度学习框架,一个 ...

  8. as转html5工具,将keras的h5模型转换为tensorflow的pb模型

    背景:目前keras框架使用简单,很容易上手,深得广大算法工程师的喜爱,但是当部署到客户端时,可能会出现各种各样的bug,甚至不支持使用keras,本文来解决的是将keras的h5模型转换为客户端常用 ...

  9. 为什么将表格的method改为post后就无法工作_用Python将Keras深度学习模型部署为Web应用程序...

    构建一个很棒的机器学习项目是一回事,但归根结底,你希望其他人能够看到你的辛勤工作.当然,你可以将整个项目放在GitHub上,但是怎么让你的祖父母也看到呢?我们想要的是将深度学习模型部署为世界上任何人都 ...

最新文章

  1. linux进程和程序的却别,操作系统:进程的概念和与程序的区别
  2. Generator + Promises, the best of all worlds in ES6
  3. 如何在Git中更改多次提交的作者和提交者名称以及电子邮件?
  4. Newtonsoft.Json高级用法
  5. Tomcat配置JNDI数据源
  6. mac解压rar命令_苹果mac电脑上很好用的免费压缩软件?ezip压缩软件分享
  7. 电力自动化及继电保护实验室规章制度
  8. java多线程基础(synchronize关键字)
  9. Winform窗体验证登陆
  10. 移动应用开发 jQuery Mobile
  11. html中border的作用,border在html中是什么意思
  12. POI excel单元格中内容换行
  13. Android仿微信朋友圈发布动态
  14. 汉高任命荣杰博士为大中华区总裁;沃尔玛中国2021届校招正式启动 | 美通企业日报...
  15. JAVA中的flush()方法
  16. CRM管理系统带给企业五大实际效益
  17. golang testify 测试库
  18. 问道手游服务器维护,问道手游2月23日更新维护(所有公测服务器)
  19. RocketMQ系列:搭建3m-3s模式的rocketmq集群
  20. easyshop 下载地址

热门文章

  1. 小时候,幸福很简单;长大后,简单很幸福!
  2. 转 做个男人,做个成熟的男人,做个有城府的男人
  3. 蓝月传奇手游苹果IOS脚本下载地址
  4. Boost ASIO proactor 浅析
  5. 雄关漫道真如铁 而今迈步从头越
  6. Quill编辑器介绍及扩展
  7. 【CQBZOJ - 1205】因式分解问题
  8. P-NUCLEO-IHM001 电机开发套件(一)
  9. js实现小球抛物线运动
  10. 25 匹马,5 个赛道,没有计时器,请问最低多少次可以找出跑得最快的 3匹马