• Keras学习记录之模型编译-训练-评估-预测


    模型编译

    compile调用格式

    Keras的模型编译的语法格式为:

    compile(optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)
    

    但我们最常用的还是以下这种:
    在完成了模型的构建后, 可以使用 .compile() 来配置学习过程
    在训练模型之前,需要配置学习过程,这是通过 compile 方法完成的。它接收三个参数:

    参数

    • 优化器 optimizer。它可以是现有优化器的字符串标识符,如 rmsprop 或 adagrad,也可以是 Optimizer类的实例。详见:optimizers。
    • 损失函数 loss,模型试图最小化的目标函数。它可以是现有损失函数的字符串标识符,如 categorical_crossentropy 或mse,也可以是一个目标函数。详见:losses。
    • 评估标准 metrics。对于任何分类问题,你都希望将其设置为 metrics =
      [‘accuracy’]。评估标准可以是现有的标准的字符串标识符,也可以是自定义的评估标准函数。

    常见调用格式

    model.compile(loss='categorical_crossentropy',
                  optimizer='sgd',
                  metrics=['accuracy'])
    

    如果需要,你还可以进一步地配置你的优化器。Keras 的核心原则是使事情变得相当简单,同时又允许用户在需要的时候能够进行完全的控制(终极的控制是源代码的易扩展性)。

    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True))
    

    自定义Compile

    自定义评价函数应该在编译的时候(compile)传递进去。该函数需要以 (y_true, y_pred) 作为输入参数,并返回一个张量作为输出结果。

    import keras.backend as K
    def mean_pred(y_true, y_pred):
        return K.mean(y_pred)
    
    model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['accuracy', mean_pred])
    

    优化器调用格式

    优化器 (optimizer) 是编译 Keras 模型的所需的两个参数之一:

    from keras import optimizers
    model = Sequential()
    model.add(Dense(64, kernel_initializer='uniform', input_shape=(10,)))
    model.add(Activation('softmax'))
    sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(loss='mean_squared_error', optimizer=sgd)
    

    你可以先实例化一个优化器对象,然后将它传入 model.compile(),像上述示例中一样, 或者你可以通过名称来调用优化器。在后一种情况下,将使用优化器的默认参数。

    # 传入优化器名称: 默认参数将被采用
    model.compile(loss='mean_squared_error', optimizer='sgd')
    

    常见优化器

    SGD
    keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
    

    随机梯度下降优化器。

    包含扩展功能的支持: - 动量(momentum)优化, - 学习率衰减(每次参数更新后) - Nestrov 动量 (NAG) 优化

    参数
    lr: float >= 0. 学习率。
    momentum: float >= 0. 参数,用于加速 SGD 在相关方向上前进,并抑制震荡。
    decay: float >= 0. 每次参数更新后学习率衰减值。
    nesterov: boolean. 是否使用 Nesterov 动量。
    
    Adam
    keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
    

    Adam 优化器。

    默认参数遵循原论文中提供的值。

    参数
    lr: float >= 0. 学习率。
    beta_1: float, 0 < beta < 1. 通常接近于 1。
    beta_2: float, 0 < beta < 1. 通常接近于 1。
    epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()。
    decay: float >= 0. 每次参数更新后学习率衰减值。
    amsgrad: boolean. 是否应用此算法的 AMSGrad 变种,来自论文 "On the Convergence of Adam and Beyond"

    此外还可以根据问题种类进行细分

    # 多分类问题
    model.compile(optimizer='rmsprop',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])
    
    # 二分类问题
    model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['accuracy'])
    
    # 均方误差回归问题
    model.compile(optimizer='rmsprop',
                  loss='mse')
    
    # 自定义评估标准函数
    import keras.backend as K
    
    def mean_pred(y_true, y_pred):
        return K.mean(y_pred)
    
    model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['accuracy', mean_pred])
    

    模型训练

    fit调用格式

    迭代训练参数格式为:

    fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)
    

    参数

    1. x: 训练数据的 Numpy 数组。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,x 可以是 None(默认)。
    2. y: 目标(标签)数据的 Numpy 数组。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,y 可以是 None(默认)。
    3. batch_size: 整数或 None。每次提度更新的样本数。如果未指定,默认为 32.
    4. epochs: 整数。训练模型迭代轮次。一个轮次是在整个 x 或 y 上的一轮迭代。请注意,与 initial_epoch一起,epochs 被理解为 「最终轮次」。模型并不是训练了 epochs 轮,而是到第 epochs 轮停止训练。
    5. verbose: 0, 1 或 2。日志显示模式。 0 = 安静模式, 1 = 进度条, 2 = 每轮一行。
    6. callbacks: 一系列的 keras.callbacks.Callback 实例。一系列可以在训练时使用的回调函数。详见
      callbacks。
    7. validation_split: 在 0 和 1之间浮动。用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。验证数据是混洗之前x 和y 数据的最后一部分样本中。
    8. validation_data: 元组 (x_val,y_val) 或元组(x_val,y_val,val_sample_weights),用来评估损失,以及在每轮结束时的任何模型度量指标。模型将不会在这个数据上进行训练。这个参数会覆盖
      validation_split。
    9. shuffle: 布尔值(是否在每轮迭代之前混洗数据)或者 字符串 (batch)。batch 是处理 HDF5数据限制的特殊选项,它对一个 batch 内部的数据进行混洗。当 steps_per_epoch 非 None 时,这个参数无效。

    返回

    一个 History 对象。其 History.history 属性是连续 epoch 训练损失和评估值,以及验证集损失和评估值的记录(如果适用)。

    异常

    RuntimeError: 如果模型从未编译。
    ValueError: 在提供的输入数据与模型期望的不匹配的情况下。

    常用的为以下几个参数:
    Keras 模型在输入数据和标签的 Numpy 矩阵上进行训练。为了训练一个模型,通常会使用 fit 函数。
    现在,可以批量地在训练数据上进行迭代了,这也是拟合训练模型的过程:

    # x_train 和 y_train 是 Numpy 数组 -- 就像在 Scikit-Learn API 中一样。
    model.fit(x_train, y_train, epochs=5, batch_size=32)
    

    或者,你可以手动地将批次的数据提供给模型(不常用):

    model.train_on_batch(x_batch, y_batch)
    

    可视化

    训练历史可视化
    Keras Model 上的 fit() 方法返回一个 History 对象。History.history 属性是一个记录了连续迭代的训练/验证(如果存在)损失值和评估值的字典。这里是一个简单的使用 matplotlib 来生成训练/验证集的损失和准确率图表的例子:可以拿过来直接用
    model.compile(loss=‘categorical_crossentropy’,optimizer=Adam(),metrics=[‘acc’])中acc要与下面的图表中acc一致

    import matplotlib.pyplot as plt
    
    history = model.fit(x, y, validation_split=0.25, epochs=50, batch_size=16, verbose=1)
    
    # 绘制训练 & 验证的准确率值
    plt.plot(history.history['acc'])
    plt.plot(history.history['val_acc'])
    plt.title('Model accuracy')
    plt.ylabel('Accuracy')
    plt.xlabel('Epoch')
    plt.legend(['Train', 'Test'], loc='upper left')
    plt.show()
    
    # 绘制训练 & 验证的损失值
    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.title('Model loss')
    plt.ylabel('Loss')
    plt.xlabel('Epoch')
    plt.legend(['Train', 'Test'], loc='upper left')
    plt.show()
    

    案例展示

    针对不同的问题,模型编译不同,训练方法也是不同:

    # 对于具有 2 个类的单输入模型(二进制分类):
    model = Sequential()
    model.add(Dense(32, activation='relu', input_dim=100))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['accuracy'])
    # 生成虚拟数据
    import numpy as np
    data = np.random.random((1000, 100))
    labels = np.random.randint(2, size=(1000, 1))
    
    # 训练模型,以 32 个样本为一个 batch 进行迭代
    model.fit(data, labels, epochs=10, batch_size=32)
    
    # 对于具有 10 个类的单输入模型(多分类分类):
    model = Sequential()
    model.add(Dense(32, activation='relu', input_dim=100))
    model.add(Dense(10, activation='softmax'))
    model.compile(optimizer='rmsprop',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])
    
    # 生成虚拟数据
    import numpy as np
    data = np.random.random((1000, 100))
    labels = np.random.randint(10, size=(1000, 1))
    
    # 将标签转换为分类的 one-hot 编码
    one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)
    
    # 训练模型,以 32 个样本为一个 batch 进行迭代
    model.fit(data, one_hot_labels, epochs=10, batch_size=32)
    

    基于 LSTM 的序列分类:

    以博主目前学习的LSTM模型为例

    from keras.models import Sequential
    from keras.layers import Dense, Dropout
    from keras.layers import Embedding
    from keras.layers import LSTM
    
    max_features = 1024
    
    model = Sequential()
    model.add(Embedding(max_features, output_dim=256))
    model.add(LSTM(128))
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))
    
    model.compile(loss='binary_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])
    
    model.fit(x_train, y_train, batch_size=16, epochs=10)
    score = model.evaluate(x_test, y_test, batch_size=16)
    

    基于 1D 卷积的序列分类:

    from keras.models import Sequential
    from keras.layers import Dense, Dropout
    from keras.layers import Embedding
    from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D
    
    seq_length = 64
    
    model = Sequential()
    model.add(Conv1D(64, 3, activation='relu', input_shape=(seq_length, 100)))
    model.add(Conv1D(64, 3, activation='relu'))
    model.add(MaxPooling1D(3))
    model.add(Conv1D(128, 3, activation='relu'))
    model.add(Conv1D(128, 3, activation='relu'))
    model.add(GlobalAveragePooling1D())
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))
    
    model.compile(loss='binary_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])
    
    model.fit(x_train, y_train, batch_size=16, epochs=10)
    score = model.evaluate(x_test, y_test, batch_size=16)
    

    基于栈式 LSTM 的序列分类

    在这个模型中,我们将 3 个 LSTM 层叠在一起,使模型能够学习更高层次的时间表示。
    前两个 LSTM 返回完整的输出序列,但最后一个只返回输出序列的最后一步,从而降低了时间维度(即将输入序列转换成单个向量)
    在这里插入图片描述

    from keras.models import Sequential
    from keras.layers import LSTM, Dense
    import numpy as np
    
    data_dim = 16
    timesteps = 8
    num_classes = 10
    
    # 期望输入数据尺寸: (batch_size, timesteps, data_dim)
    model = Sequential()
    model.add(LSTM(32, return_sequences=True,
                   input_shape=(timesteps, data_dim)))  # 返回维度为 32 的向量序列
    model.add(LSTM(32, return_sequences=True))  # 返回维度为 32 的向量序列
    model.add(LSTM(32))  # 返回维度为 32 的单个向量
    model.add(Dense(10, activation='softmax'))
    
    model.compile(loss='categorical_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])
    
    # 生成虚拟训练数据
    x_train = np.random.random((1000, timesteps, data_dim))
    y_train = np.random.random((1000, num_classes))
    
    # 生成虚拟验证数据
    x_val = np.random.random((100, timesteps, data_dim))
    y_val = np.random.random((100, num_classes))
    
    model.fit(x_train, y_train,
              batch_size=64, epochs=5,
              validation_data=(x_val, y_val))
    

    “stateful” 渲染的的栈式 LSTM 模型

    有状态 (stateful) 的循环神经网络模型中,在一个 batch 的样本处理完成后,其内部状态(记忆)会被记录并作为下一个 batch 的样本的初始状态。这允许处理更长的序列,同时保持计算复杂度的可控性。

    from keras.models import Sequential
    from keras.layers import LSTM, Dense
    import numpy as np
    
    data_dim = 16
    timesteps = 8
    num_classes = 10
    batch_size = 32
    
    # 期望输入数据尺寸: (batch_size, timesteps, data_dim)
    # 请注意,我们必须提供完整的 batch_input_shape,因为网络是有状态的。
    # 第 k 批数据的第 i 个样本是第 k-1 批数据的第 i 个样本的后续。
    model = Sequential()
    model.add(LSTM(32, return_sequences=True, stateful=True,
                   batch_input_shape=(batch_size, timesteps, data_dim)))
    model.add(LSTM(32, return_sequences=True, stateful=True))
    model.add(LSTM(32, stateful=True))
    model.add(Dense(10, activation='softmax'))
    
    model.compile(loss='categorical_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])
    
    # 生成虚拟训练数据
    x_train = np.random.random((batch_size * 10, timesteps, data_dim))
    y_train = np.random.random((batch_size * 10, num_classes))
    
    # 生成虚拟验证数据
    x_val = np.random.random((batch_size * 3, timesteps, data_dim))
    y_val = np.random.random((batch_size * 3, num_classes))
    
    model.fit(x_train, y_train,
              batch_size=batch_size, epochs=5, shuffle=False,
              validation_data=(x_val, y_val))
    

    只需一行代码就能评估模型性能:

    loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
    

    或者对新的数据生成预测:

    classes = model.predict(x_test, batch_size=128)
    

    模型评估

    常用格式:

    evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)
    

    在测试模式,返回误差值和评估标准值。
    计算逐批次进行。

    参数

    1. x: 训练数据的 Numpy 数组。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,x 可以是 None(默认)。
    2. y: 目标(标签)数据的 Numpy 数组。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。
      如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,y 可以是 None(默认)。
    3. batch_size: 整数或 None。每次提度更新的样本数。如果未指定,默认为 32.
    4. verbose: 0, 1。日志显示模式。0 = 安静模式, 1 = 进度条。
    5. sample_weight: 训练样本的可选 Numpy 权重数组,用于对损失函数进行加权(仅在训练期间)。可以传递与输入样本长度相同的平坦(1D)Numpy 数组(权重和样本之间的 1:1 映射),或者在时序数据的情况下,可以传递尺寸为 (samples, sequence_length) 的 2D 数组,以对每个样本的每个时间步施加不同的权重。在这种情况下,你应该确保在
      compile() 中指定 sample_weight_mode="temporal"
    6. steps: 整数或 None。 声明评估结束之前的总步数(批次样本)。默认值 None。

    返回

    标量测试误差(如果模型只有单个输出且没有评估指标)或标量列表(如果模型具有多个输出和/或指标)。 属性 model.metrics_names 将提供标量输出的显示标签。

    模型预测

    predict调用格式

    predict(x, batch_size=None, verbose=0, steps=None)
    

    为输入样本生成输出预测。
    计算逐批次进行。

    参数

    1. x: 输入数据,Numpy 数组(或者如果模型有多个输入,则为 Numpy 数组列表)。
    2. batch_size: 整数。如未指定,默认为 32。
    3. verbose: 日志显示模式,0 或 1。
    4. steps: 声明预测结束之前的总步数(批次样本)。默认值 None。

    返回

    预测的 Numpy 数组。

    异常

    ValueError: 如果提供的输入数据与模型的期望数据不匹配,或者有状态模型收到的数量不是批量大小的倍数。

  • 相关阅读:
    yii2 field 条件筛选
    【Java面试题】传统行业八年经验,连续4次面试都败在Nacos配置更新的工作流程
    【锁】CAS(Compare And Swap)
    [音视频] SDL 渲染
    空域图像增强-图像滤波处理
    LeetCode 438. 找到字符串中所有字母异位词__滑动窗口
    香港金融交易解决方案提供商【移动财经】申请840美元纳斯达克IPO上市
    【学习推荐】极客时间-左耳听风专栏
    ThreadPoolExecutor 线程池参数详解,执行流程
    sgu 176 Flow construction (有汇源有上下界的最小流)
  • 原文地址:https://blog.csdn.net/pengxiang1998/article/details/127042220