tensorflow2(快速入门)

版本问题

导包

import tensorflow as tf

加载数据

加载并准备 MNIST 数据集。将样本数据从整数转换为浮点数:

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

搭建模型

通过堆叠层来构建 tf.keras.Sequential 模型。

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])
  1. Flatten 层:

    • 作用: 将输入的二维数据(如图像)展平为一维。这对于将图像数据传递给全连接层(Dense layer)是必要的,因为全连接层通常接受一维输入。
    • 参数input_shape (tuple) - 输入数据的形状。这里 (28, 28) 表示输入数据是 28x28 的二维数组(如 MNIST 图像)。
  2. Dense 层:

    • 作用: 全连接层,每个神经元与前一层的每一个神经元都连接。它对输入数据进行线性变换,并通过激活函数引入非线性。
    • 参数:
      • units (int) - 神经元的数量。这决定了该层的输出维度。例如,这里是 128。
      • activation (str or function) - 激活函数,用于引入非线性。这里使用的是 'relu'(Rectified Linear Unit),它将负值置为零,正值保持不变。
  3. Dropout 层:

    • 作用: 用于正则化,防止模型过拟合。它在训练过程中随机“丢弃”或忽略一定比例的神经元,减少过拟合的风险。
    • 参数:
      • rate (float) - 表示丢弃的比例。在这里,0.2 表示在训练过程中,有 20% 的神经元会被随机忽略。
  4. Dense 层(输出层):

    • 作用: 这是模型的输出层,用于生成最终的预测结果。这里的输出层没有激活函数,意味着它将计算线性输出值。
    • 参数:
      • units (int) - 神经元的数量。这里是 10,通常对应于分类问题中的类别数(例如 MNIST 数据集中有 10 个数字类别)。

对于每个样本,模型都会返回一个包含 logits 或 log-odds 分数的向量,每个类一个。

predictions = model(x_train[:1]).numpy()
predictions

[[-0.06230168 -0.4859897  -0.4349398   0.502046    0.8077229   0.466933
  -0.27846724 -0.13608396 -0.27969462  0.17068624]]

在深度学习模型中,特别是在分类任务中,model(x_train[:1]).numpy() 返回的是模型对于输入样本的预测结果。这些结果通常是 logits 或 log-odds 分数,具体的理解如下:

  • Logits: Logits 是模型的原始输出值,通常是经过最后一层线性变换得到的。它们表示每个类别的相对得分,并且通常不会直接用于概率预测。Logits 可以看作是每个类的未归一化的得分。

model(x_train[:1]) 调用模型对输入 x_train[:1](一个样本)的预测,返回的是 logits。这些 logits 是一个包含每个类分数的向量。

例如,假设模型是一个用于 MNIST 手写数字分类的神经网络,并且模型的最后一层是一个全连接层,其输出维度为 10(因为 MNIST 有 10 个类别)。对于一个输入样本,model(x_train[:1]) 可能返回一个形如 [[-0.5, 2.3, 0.1, ..., 1.2]] 的数组,这里的每个值都代表了对应类别的 logits。

为了从 logits 转换为概率,通常会使用 Softmax 函数。Softmax 函数将 logits 转换为概率分布,使得所有类别的概率和为 1

tf.nn.softmax 函数将这些 logits 转换为每个类的概率

print(tf.nn.softmax(predictions).numpy())

[[0.07015824 0.18569683 0.05213543 0.04906429 0.13317907 0.02939027
  0.10510781 0.115359   0.10000554 0.15990353]]

注:可以将 tf.nn.softmax 烘焙到网络最后一层的激活函数中。虽然这可以使模型输出更易解释,但不建议使用这种方式,因为在使用 softmax 输出时不可能为所有模型提供精确且数值稳定的损失计算。

使用 losses.SparseCategoricalCrossentropy 为训练定义损失函数,它会接受 logits 向量和 True 索引,并为每个样本返回一个标量损失。

loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

此损失等于 true 类的负对数概率:如果模型确定类正确,则损失为零。

tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) 是 TensorFlow 中用于多分类任务的损失函数。在训练过程中,它用于衡量模型预测的类别概率分布与真实类别标签之间的差距。让我们详细解释一下这段代码和其含义:

这里 SparseCategoricalCrossentropy 是一个损失函数,专门用于处理类别标签为整数索引(而不是 one-hot 编码)的分类任务。

  • from_logits=True: 这个参数表示模型的输出是 logits(未经 softmax 激活的原始预测分数)。如果 from_logits=False,则表示模型的输出已经经过 softmax 激活,变成了概率分布。在这种情况下,损失函数会内部应用 softmax 来计算类别概率。

SparseCategoricalCrossentropy 计算的是交叉熵损失,它衡量的是模型预测的概率分布与实际标签分布之间的差异。具体来说,它计算了 true 类别的负对数概率。这个损失函数的公式如下:

loss = -log(softmax(z)_{i})

其中:

  • z \) 是模型输出的 logits 向量。
  • 真实标签 i 是 logits 向量中实际的类别索引。
  1. Logits 输入: 模型输出的是一个 logits 向量,每个元素表示一个类别的未归一化的预测分数。假设有三个类别,模型的 logits 输出可能是[2.0,1.0,0.1]。

  2. Softmax 应用: 损失函数内部会对 logits 应用 softmax 函数,将其转换为概率分布。对于上述 logits,softmax 计算的结果可能是[0.7,0.2,0.1]。

  3. 计算负对数概率: 根据实际标签,找到正确类别的概率并取其负对数。例如,如果真实标签是类别 0,对应的概率是 0.7,损失就是 −log(0.7)。

在深度学习中,使用 from_logits=True 的 SparseCategoricalCrossentropy 损失函数意味着模型输出的是 logits(即未经 softmax 归一化的原始预测分数)。

  1. 选择合适的输出层

    • 没有激活函数:模型的最后一层(输出层)应该是一个全连接层(Dense 层),但不需要应用 softmax 激活函数。这样,网络输出的是 logits。

    • 示例代码

      import tensorflow as tf
      
      # 假设分类任务有 10 个类别
      num_classes = 10
      
      model = tf.keras.Sequential([
          tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),
          tf.keras.layers.Dense(num_classes)  # 这里没有激活函数
      ])
      

    在上述示例中,Dense(num_classes) 输出了一个形状为 (batch_size, num_classes) 的 logits 张量。

  2. 定义损失函数

    • 使用 from_logits=True 的 SparseCategoricalCrossentropy 损失函数来计算损失。

    • 示例代码

      loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
  3. 编译

  •  在开始训练之前,使用 Keras Model.compile 配置和编译模型。将 optimizer 类设置为 adam,将 loss 设置为您之前定义的 loss_fn 函数,并通过将 metrics 参数设置为 accuracy 来指定要为模型评估的指标。

    model.compile(optimizer='adam',
                  loss=loss_fn,
                  metrics=['accuracy'])

训练模型

  • 训练模型时,确保目标标签(ground truth labels)是整数索引(而不是 one-hot 编码)。

  • 示例代码

    model.fit(train_data, train_labels, epochs=5, batch_size=32)

使用 from_logits=True 的好处

  1. 数值稳定性

    • 避免数值不稳定性:直接对 logits 应用 softmax 可能导致数值不稳定性,尤其是在极端值的情况下(例如 logits 的绝对值非常大)。使用 from_logits=True 的损失函数内部会更稳定地处理这个过程,减轻数值不稳定问题。
  2. 性能优化

    • 更高效的计算:损失函数会内部处理 softmax 和交叉熵的计算,这可以避免在模型中额外计算 softmax。尤其在训练大型模型时,这可以减少计算开销和内存使用。
  3. 简化模型设计

    • 模型更简洁:在模型中不需要额外添加 softmax 层,使得模型结构更简洁。这样可以减少模型复杂度和潜在的错误来源。

让我们更详细地讨论 model.compile 方法的参数,并通过一些实际场景的例子来说明它们的用途。

1. optimizer

描述: 优化器是训练过程中用于更新模型权重的算法。不同的优化器具有不同的更新规则。

常见选择:

  • 'adam': 自适应动量优化器,通常效果很好,适合大多数任务。
  • 'sgd': 随机梯度下降,常与动量(momentum)一起使用。
  • 'rmsprop': 根均方根传播,适用于处理稀疏梯度问题。

示例场景:

  • 场景: 在训练一个用于图像分类的卷积神经网络(CNN)。希望模型在训练时快速收敛且能处理各种学习率的情况。
  • 代码:
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    

2. loss

描述: 损失函数用来衡量模型预测结果与实际标签之间的差距。在训练过程中,优化器会最小化这个损失函数。

常见选择:

  • 'categorical_crossentropy': 适用于多类别分类任务,目标是 one-hot 编码
  • 'sparse_categorical_crossentropy': 适用于多类别分类任务,目标是整数标签
  • 'mean_squared_error': 适用于回归任务,计算预测值与实际值的均方误差。

示例场景:

  • 场景: 进行房价预测任务,目标是通过特征预测房屋价格。目标是连续的实数。
  • 代码:
    model.compile(optimizer='adam', loss='mean_squared_error', metrics=['mae'])
    

3. loss_weights

描述: 如果模型有多个输出,可以为每个输出指定不同的损失权重。这对训练复杂模型很有用。

示例场景:

  • 场景: 你在进行多任务学习,一个模型同时进行图像分类和物体检测。你希望分类任务的损失对总损失的贡献比检测任务大。
  • 代码:
    model.compile(optimizer='adam', 
                  loss=['categorical_crossentropy', 'mean_squared_error'],
                  loss_weights=[0.7, 0.3],
                  metrics=['accuracy'])
    

4. metrics

描述: 评估指标用于监控模型在训练和验证过程中的性能。它们不影响模型训练,但提供了有关模型性能的有用信息。

常见选择:

  • 'accuracy': 常用于分类任务,表示预测准确率。
  • 'mae': 平均绝对误差,常用于回归任务。
  • 'mse': 均方误差,回归任务的另一个常用指标。

示例场景:

  • 场景: 在训练一个二分类模型,如垃圾邮件分类器。希望监控模型的准确率。
  • 代码:
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    

5. loss_reduction

描述: 指示如何将损失值从单个样本聚合成批次损失值。主要用于处理自定义损失函数时的行为控制。

示例场景:

  • 场景: 使用自定义损失函数,并希望控制损失聚合的方式(例如,取平均或求和)。
  • 代码:
    model.compile(optimizer='adam', 
                  loss=tf.keras.losses.MeanSquaredError(reduction=tf.keras.losses.Reduction.SUM))
    

6. weighted_metrics

描述: 计算加权指标,可以根据样本权重调整指标值。

示例场景:

  • 场景: 在处理类别不平衡的数据集时,你希望按样本权重计算指标。
  • 代码:
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'], weighted_metrics=['accuracy'])
    

7. run_eagerly

描述: 如果设置为 True,模型将以 Eager Execution 模式运行,这有助于调试,但可能导致训练速度变慢。

示例场景:

  • 场景: 你在调试模型,并需要逐步检查每一步的执行情况。
  • 代码:
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', run_eagerly=True)
    

8. steps_per_execution

描述: 在每次 tf.function 执行时,处理的步骤数。可以提高训练效率,减少上下文切换的开销。

示例场景:

  • 场景: 你希望在大型数据集上进行训练,通过每次执行多个步骤来优化训练速度。
  • 代码:
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', steps_per_execution=10)
    

训练、保存、调用模型

我们详细讨论 model.fit 方法的所有参数,并结合实际场景进行解释。接着,我们讲解如何保存训练后的模型、如何调用和预测新数据。下面是 model.fit 方法及其参数的详细说明。

model.fit 方法的参数

  1. x

    • 类型: 训练数据(通常是 NumPy 数组、TensorFlow 张量或其他形式的输入数据)。
    • 作用: 作为模型训练的输入数据。
    • 示例场景: 你正在训练一个图像分类模型,x_train 是包含图像数据的数组。
  2. y

    • 类型: 训练数据的标签(通常是 NumPy 数组、TensorFlow 张量或其他形式的标签)。
    • 作用: 作为模型训练的目标数据。
    • 示例场景: 对应于 x_trainy_train 是图像数据对应的分类标签。
  3. batch_size

    • 类型: 整数或 None。
    • 作用: 定义每次梯度更新的样本数。默认值为 32。
    • 示例场景: 你有一个大的数据集,选择较小的 batch_size 可以使内存占用更少,但可能会导致训练速度变慢。
    • 代码:
      model.fit(x_train, y_train, epochs=5, batch_size=64)
      
  4. epochs

    • 类型: 整数。
    • 作用: 定义训练过程中模型的迭代次数。
    • 示例场景: 你希望模型经过 5 次完整的训练周期,以期获得更好的训练效果。
    • 代码:
      model.fit(x_train, y_train, epochs=5)
      
  5. verbose

    • 类型: 整数(0, 1, 2)。
    • 作用: 设置训练过程的日志显示模式。0 表示无输出,1 表示进度条,2 表示每个 epoch 后一行日志。
    • 示例场景: 你希望在训练过程中查看详细的进度信息。
    • 代码:
      model.fit(x_train, y_train, epochs=5, verbose=1)
      
  6. validation_split

    • 类型: 浮点数,介于 0 和 1 之间。
    • 作用: 从训练数据中分割出一部分数据作为验证集。比如设置为 0.2 表示将 20% 的训练数据用于验证。
    • 示例场景: 你希望在每个 epoch 后评估模型性能,但没有单独的验证集数据。
    • 代码:
      model.fit(x_train, y_train, epochs=5, validation_split=0.2)
      
  7. validation_data

    • 类型: 元组 (x_val, y_val),x_val 和 y_val 是验证数据和对应的标签。
    • 作用: 提供单独的验证集数据,用于在每个 epoch 后评估模型。
    • 示例场景: 你有一个专门的验证集 x_val 和 y_val,希望在训练过程中使用它来监控模型性能。
    • 代码:
      model.fit(x_train, y_train, epochs=5, validation_data=(x_val, y_val))
      
  8. shuffle

    • 类型: 布尔值或字符串 (‘batch’)。
    • 作用: 是否在每个 epoch 前打乱训练数据。默认值是 True
    • 示例场景: 如果训练数据有序且存在偏差,你可能希望打乱数据以提高模型泛化能力。
    • 代码:
      model.fit(x_train, y_train, epochs=5, shuffle=True)
      
  9. class_weight

    • 类型: 字典或 None。
    • 作用: 为不同类别指定不同的权重,用于处理类别不平衡问题。
    • 示例场景: 你的数据集中某些类别的样本远少于其他类别,想要调整训练过程中对这些类别的重视程度。
    • 代码:
      class_weight = {0: 1., 1: 5.}
      model.fit(x_train, y_train, epochs=5, class_weight=class_weight)
      
  10. sample_weight

    • 类型: 数组或 None。
    • 作用: 为每个训练样本指定不同的权重。
    • 示例场景: 你有一个训练数据集,其中某些样本比其他样本更重要。
    • 代码:
      sample_weight = np.array([1, 2, 1, 1, ...])
      model.fit(x_train, y_train, epochs=5, sample_weight=sample_weight)
      
  11. initial_epoch

    • 类型: 整数。
    • 作用: 从指定的 epoch 开始训练,可以用来继续训练。
    • 示例场景: 你之前训练了模型到第 10 个 epoch,现在希望继续从第 11 个 epoch 开始训练。
    • 代码:
      model.fit(x_train, y_train, epochs=15, initial_epoch=10)
      
  12. steps_per_epoch

    • 类型: 整数。
    • 作用: 每个 epoch 包含的步骤数,通常用于 tf.data 数据集。
    • 示例场景: 你在使用自定义数据集时,想指定每个 epoch 训练的步骤数。
    • 代码:
      model.fit(x_train, y_train, epochs=5, steps_per_epoch=100)
      
  13. validation_steps

    • 类型: 整数。
    • 作用: 每个验证 epoch 包含的步骤数,通常用于 tf.data 数据集。
    • 示例场景: 你在使用自定义验证集时,指定每个验证 epoch 的步骤数。
    • 代码:
      model.fit(x_train, y_train, epochs=5, validation_data=(x_val, y_val), validation_steps=50)
      
  14. max_queue_size

    • 类型: 整数。
    • 作用: 数据预取队列的大小。用于控制数据加载的并发性。
    • 示例场景: 你希望加快数据加载速度,通过调整队列大小来优化数据预取。
    • 代码:
      model.fit(x_train, y_train, epochs=5, max_queue_size=10)
      
  15. workers

    • 类型: 整数。
    • 作用: 用于数据加载的线程数。
    • 示例场景: 你希望使用多个线程来提高数据加载速度。
    • 代码:
      model.fit(x_train, y_train, epochs=5, workers=4)
      
  16. use_multiprocessing

    • 类型: 布尔值。
    • 作用: 是否使用多进程数据加载。
    • 示例场景: 在数据预处理或加载过程中,你希望通过多进程加速数据读取。
    • 代码:
      model.fit(x_train, y_train, epochs=5, use_multiprocessing=True)
      

训练完的模型如何保存和调用

保存模型:

  • 场景: 训练完成后,你希望将模型保存到磁盘以便下次使用。
  • 代码:
    model.save('my_model.h5')  # 保存为 HDF5 格式
    

加载模型:

  • 场景: 你希望加载之前保存的模型进行预测或进一步训练。
  • 代码:
    from tensorflow.keras.models import load_model
    model = load_model('my_model.h5')
    

使用模型进行预测

预测新数据:

  • 场景: 你有一些新的图像数据,希望使用训练好的模型进行分类。
  • 代码:
    predictions = model.predict(x_new)  # x_new 是新的图像数据
    

示例完整流程:

  1. 训练模型:

    model.fit(x_train, y_train, epochs=5, batch_size=32, validation_split=0.2)
    
  2. 保存模型:

    model.save('my_model.h5')
    
  3. 加载模型:

    from tensorflow.keras.models import load_model
    model = load_model('my_model.h5')
    
  4. 预测新数据:

    predictions = model.predict(x_new)
    

  • 31
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

背水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值