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接口用于重载。

posted @ 2021-03-20 14:02  一字千金  阅读(160)  评论(0编辑  收藏  举报