7. 训练

作者: hdszzwy | 来源:发表于2022-07-31 11:10 被阅读0次

本章将讨论如何训练模型。TensorFlow封装了一些tf.Keras的API用于简化训练过程,但是本章只会用到基本类而不会涉及高级API。

机器学习的基本步骤

使用机器学习解决问题,通常包含有一些基本步骤:

  • 获取训练数据
  • 定义模型
  • 定义损失函数
  • 计算训练数据的损失值
  • 计算损失对于训练参数的梯度,并使用优化器更新变量
  • 评价模型
    为了熟悉流程,我们以简单的线性回归为例进行讲解。

数据获取

有监督学习需要的数据包含有输入特征和输出标签。通过从输入和输出的匹配中训练到一个模型,使得其可以根据输入预测输出。
在TensorFlow中,一条输入数据被表示为一个张量或一个向量。同时,有监督学习的输出也被表示为一个张量。
下列的代码中,是在一条线性关系上增加了高斯噪声。

TRUE_W = 3.0
TRUE_B = 2.0

NUM_EXAMPLES = 201

x = tf.linspace(-2, 2, NUM_EXAMPLES)
x = tf.cast(x, tf.float32)


def f(x):
    return x * TRUE_W + TRUE_B


noise = tf.random.normal(shape=[NUM_EXAMPLES])

y = f(x) + noise

plt.plot(x, y, '.')
plt.show()

模型定义

我们一般使用tf.Variable表示模型的参数。一个tf.Variable对象存储了一个张量值。tf.Module封装了变量和计算。当然,想要封装变量和计算,只需要一个Python类即可,但是你可以通过继承tf.Module从而使用一些已经实现的功能。下面代码定义了两个变量w和b:

class MyModel(tf.Module):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.w = tf.Variable(5.0)
        self.b = tf.Variable(0.0)

    def __call__(self, x):
        return self.w * x + self.b


model = MyModel()

print("Variables:", model.variables)

assert model(3.0).numpy() == 15.0

上述代码中的初始化变量设置成了一个固定的数字。但是keras已经提供了多种初始化的方法,你可以自由使用。

定义损失函数

损失函数用于评估,模型的预测值与现实标签之间的接近程度。训练过程即最小化损失函数的过程。本章采用L2损失函数,即均方误差作为损失函数。

def loss(target_y, predicted_y):
    return tf.reduce_mean(tf.square(target_y - predicted_y))

训练过程

所谓训练过程,就是不断的重复以下四个步骤:

  • 输入一批数据,让模型进行预测
  • 计算损失函数评估预测值与真实值之间的差距
  • 使用gradient tape得到梯度
  • 使用梯度更新模型中的参数。
    tf.keras.optimizers里面封装了一些常用的梯度下降法的变种。但是,我们将借助于tape自己实现一个梯度下降法。最终的代码如下:
import tensorflow as tf
import matplotlib.pyplot as plt

colors = plt.rcParams['axes.prop_cycle'].by_key()['color']

TRUE_W = 3.0
TRUE_B = 2.0

NUM_EXAMPLES = 201

# A vector of random x values
x = tf.linspace(-2, 2, NUM_EXAMPLES)
x = tf.cast(x, tf.float32)


def f(x):
    return x * TRUE_W + TRUE_B


# Generate some noise
noise = tf.random.normal(shape=[NUM_EXAMPLES])

# Calculate y
y = f(x) + noise


class MyModel(tf.Module):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.w = tf.Variable(5.0)
        self.b = tf.Variable(0.0)

    def __call__(self, x):
        return self.w * x + self.b


def loss(target_y, predicted_y):
    return tf.reduce_mean(tf.square(target_y - predicted_y))


def train(model, x, y, learning_rate):
    with tf.GradientTape() as tape:
        current_loss = loss(y, model(x))
    dw, db = tape.gradient(current_loss, [model.w, model.b])

    model.w.assign_sub(learning_rate * dw)
    model.b.assign_sub(learning_rate * db)


model = MyModel()
weights = []
biases = []
epochs = range(100)


def report(model, loss):
    return f"W = {model.w.numpy():1.2f}, b = {model.b.numpy():1.2f}, loss={loss:2.5f}"


def training_loop(model, x, y):
    for epoch in epochs:
        train(model, x, y, learning_rate=0.01)
        weights.append(model.w.numpy())
        biases.append(model.b.numpy())
        current_loss = loss(y, model(x))

        print(f"Epoch {epoch:2d}: ")
        print("    ", report(model, current_loss))


training_loop(model, x, y)

plt.plot(x, y, '.', label="Data")
plt.plot(x, f(x), label="Ground truth")
plt.plot(x, model(x), label="Predictions")
plt.legend()
plt.show()

print("Current loss: %1.6f" % loss(model(x), y).numpy())

结果为:

Epoch  0: 
     W = 4.95, b = 0.04, loss=9.74990
Epoch  1: 
     W = 4.90, b = 0.08, loss=9.33798
Epoch  2: 
     W = 4.85, b = 0.12, loss=8.94586
Epoch  3: 
     W = 4.80, b = 0.16, loss=8.57255
Epoch  4: 
     W = 4.75, b = 0.19, loss=8.21715
......
Epoch 93: 
     W = 3.20, b = 1.72, loss=1.12299
Epoch 94: 
     W = 3.20, b = 1.72, loss=1.11778
Epoch 95: 
     W = 3.19, b = 1.73, loss=1.11279
Epoch 96: 
     W = 3.19, b = 1.73, loss=1.10802
Epoch 97: 
     W = 3.19, b = 1.74, loss=1.10346
Epoch 98: 
     W = 3.18, b = 1.75, loss=1.09909
Epoch 99: 
     W = 3.18, b = 1.75, loss=1.09492
Current loss: 1.094921
预测结果对比.png

基于Keras的解决方案

下面使用keras来解决上面提到的线性回归的问题。
基于tf.keras.Model的代码与上面的建模代码相差不大,需要记住,Keras的模型都继承自tf.kears.Module。你可以使用model.compile()方法来配置参数,也可以使用model.fit()方法进行训练,还使用极其简洁的代码来指定使用L2损失函数和梯度下降法。你还可以使用在外部已经定义好的损失函数和优化器,那么重写上面的例子的代码就变成了:

TRUE_W = 3.0
TRUE_B = 2.0

NUM_EXAMPLES = 201

# A vector of random x values
x = tf.linspace(-2, 2, NUM_EXAMPLES)
x = tf.cast(x, tf.float32)


def f(x):
    return x * TRUE_W + TRUE_B


# Generate some noise
noise = tf.random.normal(shape=[NUM_EXAMPLES])

# Calculate y
y = f(x) + noise


class MyModelKeras(tf.keras.Model):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # Initialize the weights to `5.0` and the bias to `0.0`
        # In practice, these should be randomly initialized
        self.w = tf.Variable(5.0)
        self.b = tf.Variable(0.0)

    def call(self, x):
        return self.w * x + self.b


keras_model = MyModelKeras()
keras_model.compile(
    # By default, fit() uses tf.function().  You can
    # turn that off for debugging, but it is on now.
    run_eagerly=False,

    # Using a built-in optimizer, configuring as an object
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),

    # Keras comes with built-in MSE error
    # However, you could use the loss function
    # defined above
    loss=tf.keras.losses.mean_squared_error,
)
print(x.shape[0])
keras_model.fit(x, y, epochs=100, batch_size=1000)

fit方法需要指定数据和批次和epoch大小,上面的代码中,设置了epoch为10,每批次数据量为1000。

相关文章

  • 作业三(7.8)

    作业7.爬山联想 作业8:关键词训练

  • 7. 训练

    本章将讨论如何训练模型。TensorFlow封装了一些tf.Keras的API用于简化训练过程,但是本章只会用到基...

  • 随笔7.训练

    孩子目前注意力不太好,我是又急又苦,感觉教育孩子比讲课和写论文都难。可能我没有把握要领和适当的方...

  • 口才训练(7.坐姿)

    标准坐姿要领: 1.精神饱满,表情自然,目光平视前方或注视交谈对象。 2.身体端正舒展,重心垂直向下或稍向前倾,腰...

  • 《别样芳华》上卷:军旅雏鹰(5.7)

    第五章 下连队 7.步兵战术(一) 步兵战术训练,是步兵很重要的一项训练内容,战术素养的高低,会直接影响在战场上保...

  • 振羽高飞的Scalers Talk第四轮新概念朗读持续力训练da

    振羽高飞的Scalers Talk第四轮新概念朗读持续力训练day8 [Day:7. 2018-10-15]...

  • 振羽高飞的Scalers Talk第四轮新概念朗读持续力训练da

    振羽高飞的Scalers Talk第四轮新概念朗读持续力训练day7 [Day:7. 2018-10-14] L...

  • 2019-09-28

    7.

  • keras入门

    1. 加载模块 2. 初始化变量 3.准备数据 4.建立模型 5.编译模型 6. 迭代训练 7.模型评估 8. 模型保存

  • 挑战突破

    下午接到002的邀请,晚上金种子密训练营开营主持,7.点过回到家,家婆做饭7:47速度吃完,把自己准备好开始…...

网友评论

      本文标题:7. 训练

      本文链接:https://www.haomeiwen.com/subject/yiynirtx.html