Keras的Model模型使用
本主题主要阐述下Keras框架中的模型Model的使用,主要包含的内容:
1.模型的两种使用方式;
2.经典模型的实现(定制模型);
3.模型的定制训练;
一. 模型使用的两种方式
Keras通过两个API提供两种计算模型:
- 函数式模型:通过Model类API;
- 顺序式模型:通过Sequential类API;
本文的业务背景还是是深度全链接网络;
实现4 -> 8 -> 4 -> 1网络。
1. 函数式模型
- 函数式模型的编程特点是:
- 程序员构建层,通过Layer对象的可调用特性,或者使用apply与call实现链式函数调用;
- Model只需要通过inputs与outputs;
- 这种模式之所以称为函数式模型,是因为Layer提供了几种函数式调用方式,通过这种调用建立层之间的网络模型。
- Layer是可调用对象,提供
__call__
可调用运算符(...)
; - apply函数;
- Layer是可调用对象,提供
- 函数式模型的示意图
- 函数式模型的示例代码 - 使用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%
函数式模型的示例代码-使用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. 顺序式模型
顺序式模型的编程特点:
- Layer提供input与output属性;
- 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。
- call函数来自model的父类:
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构建模型
定制过程
- 继承Model类;
- 定制构造器,实现定制属性传递;
- 定制call函数,实现模型的输出;
- 定制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. 优化器对象
- Adam构造器说明
__init__(learning_rate=0.001, # 学习率beta_1=0.9,beta_2=0.999,epsilon=1e-07,amsgrad=False,name='Adam',**kwargs)
- 优化器的优化调用
apply_gradients( # 梯度更新grads_and_vars, name=None)
- 优化器创建代码
import tensorflow.keras.optimizers as optimizers optimizer = optimizers.Adam(learning_rate=0.0001)
1.2. 损失对象
- 该对象是可调用对象,用来实现损失计算。
- CategoricalCrossentropy损失类的构造器说明:
__init__(from_logits=False,label_smoothing=0,reduction=losses_utils.ReductionV2.AUTO,name='categorical_crossentropy')
- 可调用对象运算符说明
__call__(y_true, # 标签值y_pred, # 预测值sample_weight=None)
调用后,可以使用result函数获取结果。
损失对象构造
import tensorflow.keras.losses as losses loss =losses.CategoricalCrossentropy()
1.3. 梯度计算
- 使用`tf.GradientTape`计算梯度
- 上下文环境
__enter__()__exit__(typ,value,traceback )
计算梯度
返回与sources一样的结构的梯度结构。gradient(target, # 误差项sources,output_gradients=None,unconnected_gradients=tf.UnconnectedGradients.NONE)
梯度对象与梯度计算代码
with tf.GradientTape() as tape:gradients = tape.gradient(loss, # 损失张量(不是对象)model.trainable_variables) # 需要更新的可训练权重张量
1.4. 评估度量
- 评估方式用来计算准确率,精准率,召回率等。
- 下面是Accuracy类的说明
- 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. 训练过程实现
实现步骤:
- 计算模型输出
- 计算损失值(损失张量,不是损失对象)
- 根据损失值,计算误差项
- 使用优化器更新梯度
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. 训练实现
- 准备数据
# 准备数据 data, target = datasets.load_iris(return_X_y=True) data = data[:100, :] # 取前面100个样本(第一类与第二类) target = target[:100]
- 训练
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模型使用相关推荐
- keras系列︱Sequential与Model模型、keras基本结构功能(一)
不得不说,这深度学习框架更新太快了尤其到了Keras2.0版本,快到Keras中文版好多都是错的,快到官方文档也有旧的没更新,前路坑太多. 到发文为止,已经有theano/tensorflow/CNT ...
- Keras Model模型方法
Model模型方法 compile compile(self, optimizer, loss, metrics=None, loss_weights=None, sample_weight_mode ...
- 将keras的h5模型转化为onnx
将keras的h5模型转化为onnx 先安装 pip install keras2onnx import keras import keras2onnx import onnx from keras. ...
- Sequential 顺序模型和 Model 模型【TensorFlow2入门手册】
文章目录 Keras 模型 Sequential 顺序模型 Sequential 使用方法 Model 模型 Model 使用方法 Keras 模型 Keras提供的模型,其中分为两类: Sequen ...
- 2020-12-11 keras通过model.fit_generator训练模型(节省内存)
keras通过model.fit_generator训练模型(节省内存) 前言 前段时间在训练模型的时候,发现当训练集的数量过大,并且输入的图片维度过大时,很容易就超内存了,举个简单例子,如果我们有2 ...
- DL之Keras:基于Keras框架建立模型实现【预测】功能的简介、设计思路、案例分析、代码实现之详细攻略(经典,建议收藏)
DL之Keras:基于Keras框架建立模型实现[预测]功能的简介.设计思路.案例分析.代码实现之详细攻略(经典,建议收藏) 目录 Keras框架使用分析 Keras框架设计思路 案例分析 代码实现 ...
- 【Keras速成】Keras图像分类从模型自定义到测试
文章首发于微信公众号<与有三学AI> [Keras速成]Keras图像分类从模型自定义到测试 这是给大家准备的Keras速成例子 这一次我们讲讲keras这个简单.流行的深度学习框架,一个 ...
- as转html5工具,将keras的h5模型转换为tensorflow的pb模型
背景:目前keras框架使用简单,很容易上手,深得广大算法工程师的喜爱,但是当部署到客户端时,可能会出现各种各样的bug,甚至不支持使用keras,本文来解决的是将keras的h5模型转换为客户端常用 ...
- 为什么将表格的method改为post后就无法工作_用Python将Keras深度学习模型部署为Web应用程序...
构建一个很棒的机器学习项目是一回事,但归根结底,你希望其他人能够看到你的辛勤工作.当然,你可以将整个项目放在GitHub上,但是怎么让你的祖父母也看到呢?我们想要的是将深度学习模型部署为世界上任何人都 ...
最新文章
- linux进程和程序的却别,操作系统:进程的概念和与程序的区别
- Generator + Promises, the best of all worlds in ES6
- 如何在Git中更改多次提交的作者和提交者名称以及电子邮件?
- Newtonsoft.Json高级用法
- Tomcat配置JNDI数据源
- mac解压rar命令_苹果mac电脑上很好用的免费压缩软件?ezip压缩软件分享
- 电力自动化及继电保护实验室规章制度
- java多线程基础(synchronize关键字)
- Winform窗体验证登陆
- 移动应用开发 jQuery Mobile
- html中border的作用,border在html中是什么意思
- POI excel单元格中内容换行
- Android仿微信朋友圈发布动态
- 汉高任命荣杰博士为大中华区总裁;沃尔玛中国2021届校招正式启动 | 美通企业日报...
- JAVA中的flush()方法
- CRM管理系统带给企业五大实际效益
- golang testify 测试库
- 问道手游服务器维护,问道手游2月23日更新维护(所有公测服务器)
- RocketMQ系列:搭建3m-3s模式的rocketmq集群
- easyshop 下载地址