3.2tensorflow自定义模型步骤方法
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
https://www.cnblogs.com/bclshuai/p/11380657.html
1.1 模型和层
1.1.1 简介
层:就是将输入数据和变量之间进行计算的方法,可以理解为一个个函数。tf.Keras.layers中包含了大量的深度学习中常用的预定义层,也可以自定义层。
模型:则是将各种层进行组织和连接,封装成一个流程,描述了如何将输入的数据通过各种层组织连接计算得到输出。对于线性模型,不是用公式计算
y=ax+b,而是直接调用y_pred=model(x),得出值。线性模型model中包含了参数a,b,线性计算关系y=ax+b.
可以简单的理解为层是类的函数,model是类的封装,不仅包含层,还包含变量a,b,同时包含运算关系和流程。
1.1.2 自定义模型
自定义模型只要继承tf.keras.Model基类,然后重写模型的_init_函数和call函数,_init_函数中定义了keras层或者自定义层,也就是各种方法,call函数中定义层之间的连接,也就是将输入数据调用init中创建的方法,组织方法调用的流程,得出最后的结果输出。例如对线性函数y=ax+b的自定义模型。
全连接层的参数说明
def __init__(self, units,#输出张量的维度, activation=None,#激活函数 use_bias=True,#是否加入偏置向量,即f(AX+b)中的b kernel_initializer='glorot_uniform',#权值A的初始化 bias_initializer='zeros',#偏置向量的初始化 kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs):
自定义模型步骤
(1) 自定义类继承tf.keras.Model
(2) 重写init函数,在函数内部定义层;
(3) 重写call函数,在call函数中连接各个层输出结果;
(4) 用自定义类创建模型对象
(5) for循环内创建梯度、损失函数,算法迭代更新参数
(6) 得出参数矩阵输出结果
实例代码:
import tensorflow as tf
#继承model,自定义线性类
class linemodel(tf.keras.Model):#继承model类
#重写init函数,在init函数中实现自定义层
def __init__(self):
super().__init__()
#定义层
#Dense是全连接层,内部是线性函数+激活函数实现,不指定激活函数时,只是线性变换y=AX+b
self.line=tf.keras.layers.Dense(units=1,activation=None,#自定义线程层line
kernel_initializer=tf.zeros_initializer(),
bias_initializer=tf.zeros_initializer())
#重写call函数,连接各个层
def call(self, inputs):#重写call函数
output=self.line(inputs)#将层进行连接输出结果
return output#返回结果
#使用模型
X=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]])#定义常量矩阵2行3列
y=tf.constant([[10.0],[20.0]])#定义目标结果矩阵,2行1列
model=linemodel()#定义模型变量
y1=model(X)
print(y1)
optimizer=tf.keras.optimizers.SGD(learning_rate=0.01)
for i in range(100):
with tf.GradientTape() as tape:
y_pred=model(X)#定义预测模型
loss =tf.reduce_mean(tf.square(y_pred-y))#定义损失函数
grad=tape.gradient(loss,model.variables)#计算梯度
#更新参数
optimizer.apply_gradients(grads_and_vars=zip(grad,model.variables))
print(model.variables)#显示模型的参数
y2=model(X)#检测模型
print(y2)
输出结果:
tf.Tensor(
[[0.]
[0.]], shape=(2, 1), dtype=float32)
[<tf.Variable 'linemodel/dense/kernel:0' shape=(3, 1) dtype=float32, numpy=
array([[0.40784496],
[1.191065 ],
[1.9742855 ]], dtype=float32)>, <tf.Variable 'linemodel/dense/bias:0' shape=(1,) dtype=float32, numpy=array([0.78322077], dtype=float32)>]
tf.Tensor(
[[ 9.496052]
[20.215637]], shape=(2, 1), dtype=float32)
上面的输出结果中kernel是模型中的参数矩阵a,bias是模型中的参数矩阵b。最后是用训练好的模型计算的结果和真实的结果[10,20]之间很接近。这就自定义模型,并训练使用模型参数的例子。
为什么不是重载_call_函数而是重载call函数?
karas模型内部定义的_call_函数,_call_函数内部除了会调用call函数,还需要做一些自己的内部操作。所以会暴露call接口用于重载。