当前位置:   article > 正文

机器学习笔记_建立模型属于机器学习吗

建立模型属于机器学习吗

基础概念

机器学习拥有三个阶段:准备数据、建立模型、模型应用
准备数据阶段分三个步骤:收集数据、探索数据、数据预处理
建立模型分为三个步骤:训练模型、评估模型、优化模型,不断迭代
数据可能存在各种问题:数据缺失、数据不规范,有异常数据、非数值数据、无关数据和数据分布不均衡
训练模型又分为三步:1.根据实际问题和数据情况,选择一个合适的模型 2.根据具体问题来具体分析,构建损失函数 3.求解损失函数

举个例子

Tensorflow官网拿来的例子

准备数据

1.获取数据集

首先从tensorflow自带数据集中获取fashion_mnist,该数据集包含 10 个类别的 70,000 个灰度图像。这些图像以低分辨率(28x28 像素)展示了单件衣物

# 该数据集包含 10 个类别的 70,000 个灰度图像。这些图像以低分辨率(28x28 像素)
fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
  • 1
  • 2
  • 3

加载数据集会返回四个 NumPy 数组:

  • train_images 和 train_labels 数组是训练集,即模型用于学习的数据。
  • test_images 和 test_labels 数组是测试集,会被用来对模型进行测试。
2.浏览数据集

简单浏览数据集的形状

# 查看训练集图片形状
train_images.shape
# (60000, 28, 28) 60000条 28*28

# 查看训练集标签数量
len(train_labels)
# 60000 60000条
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

打印数据集

for i in range(10):
    tf.print(train_images[i], summarize=-1) # -1表示完整打印
  • 1
  • 2

b.txt
转成图片

# 该包需要安装Pillow
from PIL import Image

# 转图像
for labels in range(100):
    picture = Image.fromarray(train_images[labels])
    picture = picture.convert("L")
    picture.save(save_path + "" + str(labels) + ".png")
    tf.print(labels, summarize=-1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

img0.pngimg1.pngimg2.pngimg3.pngimg4.pngimg5.pngimg6.pngimg7.pngimg8.pngimg9.pngimg10.pngimg11.pngimg12.pngimg13.pngimg14.pngimg15.pngimg16.pngimg17.pngimg18.pngimg19.pngimg20.pngimg21.pngimg22.pngimg23.pngimg24.pngimg25.pngimg26.pngimg27.pngimg28.pngimg29.pngimg30.pngimg31.pngimg32.pngimg33.pngimg34.pngimg35.pngimg36.pngimg37.pngimg38.pngimg39.pngimg40.pngimg41.pngimg42.pngimg43.pngimg44.pngimg45.pngimg46.pngimg47.pngimg48.pngimg49.pngimg50.pngimg51.pngimg52.pngimg53.pngimg54.pngimg55.pngimg56.pngimg57.pngimg58.pngimg59.pngimg60.pngimg61.pngimg62.pngimg63.pngimg64.pngimg65.pngimg66.pngimg67.pngimg68.pngimg69.pngimg70.pngimg71.pngimg72.pngimg73.pngimg74.pngimg75.pngimg76.pngimg77.pngimg78.pngimg79.pngimg80.pngimg81.pngimg82.pngimg83.pngimg84.pngimg85.pngimg86.pngimg87.pngimg88.pngimg89.pngimg90.pngimg91.pngimg92.pngimg93.pngimg94.pngimg95.pngimg96.pngimg97.pngimg98.pngimg99.png
图像是 28x28 的 NumPy 数组,像素值介于 0 到 255 之间。标签是整数数组,介于 0 到 9 之间。这些标签对应于图像所代表的服装类:

标签
0T恤/上衣
1裤子
2套头衫
3连衣裙
4外套
5凉鞋
6衬衫
7运动鞋
8
9短靴

3.预处理数据

在训练网络之前,必须对数据进行预处理。通过以下代码可以看到图像的像素值介于0-255之间。

import matplotlib.pyplot as plt

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

image.png
我们需要将这些值缩小到0-255之间,以此输入到神经网络模型中进行训练,所以我们需要将训练集与测试集除以255

train_images = train_images / 255.0
test_images = test_images / 255.0
  • 1
  • 2

建立模型

1.设置层
# 设置三层
model = tf.keras.Sequential([
    # 第一层,简单处理
    # 展平 (28,28) -> (1,28*28)
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    # 第二层
    # 密集链接/全连接神经层 128个神经元 隐藏层
    # 激活函数采用relu
    tf.keras.layers.Dense(128, activation='relu'),
    # 感觉这像是一个输出层
    tf.keras.layers.Dense(10)
])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.编译模型

在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:

  • 损失函数 - 测量模型在训练期间的准确程度。希望最小化此函数,以便将模型“引导”到正确的方向上。
  • 优化器 - 决定模型如何根据其看到的数据和自身的损失函数进行更新。
  • 指标 - 用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
# 2.编译模型
model.compile(
    # 优化器(梯度)
    optimizer='adam',
    # 损失函数
    # 交叉熵函数
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    # 精度 准确
    metrics=['accuracy'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

训练模型

训练神经网络模型需要执行以下步骤:

  1. 将训练数据馈送给模型。在本例中,训练数据位于 train_images 和 train_labels 数组中。
  2. 模型学习将图像和标签关联起来。
  3. 要求模型对测试集(在本例中为 test_images 数组)进行预测。
  4. 验证预测是否与 test_labels 数组中的标签相匹配。
1.向模型馈送数据

将训练数据馈送给模型,由模型迭代训练

# 拟合(训练)
# epochs 代数
model.fit(train_images, train_labels, epochs=10)
# 拟合结果 以两轮输出为例
# Epoch 9/10
# 1875/1875 [==============================] - 3s 2ms/step - loss: 0.2499 - accuracy: 0.9076
# Epoch 10/10
# 1875/1875 [==============================] - 3s 2ms/step - loss: 0.2410 - accuracy: 0.9099
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.评估准确率

在测试集上评估模型的准确率

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)
# 评估结果
# 313/313 - 1s - loss: 0.3453 - accuracy: 0.8794 - 747ms/epoch - 2ms/step
# Test accuracy: 0.8794000148773193 测试准确率略低于训练准确率
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

结果表明,模型在测试数据集上的准确率略低于训练数据集。训练准确率和测试准确率之间的差距代表_过拟合_。过拟合是指机器学习模型在新的、以前未曾见过的输入上的表现不如在训练数据上的表现。过拟合的模型会“记住”训练数据集中的噪声和细节,从而对模型在新数据上的表现产生负面影响。

3.进行预测

附加一个Softmax()函数,将模型的输出转换成更容易理解的概率。然后进行预测

# 加一层 概率模型
probability_model = tf.keras.Sequential([model, 
                                         tf.keras.layers.Softmax()])
# 进行预测
predictions = probability_model.predict(test_images)
# 打印第一个数据
print(predictions[0])
# array([8.5380130e-08, 1.2862756e-06, 1.7201529e-07, 2.4579521e-09,
#       1.1657544e-05, 3.9379053e-02, 3.2284350e-07, 2.0818772e-02,
#       3.1966898e-08, 9.3978864e-01], dtype=float32)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4.验证预测结果
# 需要 matplotlib.pyplot 支持
def plot_image(i, predictions_array, true_label, img):
    true_label, img = true_label[i], img[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])

    plt.imshow(img, cmap=plt.cm.binary)

    predicted_label = np.argmax(predictions_array)
    if predicted_label == true_label:
        color = 'blue'
    else:
        color = 'red'

    plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                         100*np.max(predictions_array),
                                         class_names[true_label]),
               color=color)

def plot_value_array(i, predictions_array, true_label):
    true_label = true_label[i]
    plt.grid(False)
    plt.xticks(range(10))
    plt.yticks([])
    thisplot = plt.bar(range(10), predictions_array, color="#777777")
    plt.ylim([0, 1])
    predicted_label = np.argmax(predictions_array)

    thisplot[predicted_label].set_color('red')
    thisplot[true_label].set_color('blue')

# 验证第i张图
i = 12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

image.png

保存模型

1.在训练中保存(checkpoints)

类似于游戏中的即时存档(检查点保存),每训练一段数据就进行一次保存。

# 1.保存
# 检查点保存路径
checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 创建回调只保存模型权重
# Create a callback that saves the model's weights
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
                                                 save_weights_only=True,
                                                 verbose=1)

# 在训练模型的时候加callbacks回调 去保存检查点
model.fit(train_images, 
          train_labels,  
          epochs=10,
          validation_data=(test_images, test_labels),
          callbacks=[cp_callback])  # Pass callback to training

# 这步操作可能会产生警告,警告数据会输出出去,忽略就好
# This may generate warnings related to saving the state of the optimizer.
# These warnings (and similar warnings throughout this notebook)
# are in place to discourage outdated usage, and can be ignored.

# 2.加载权重
# Loads the weights
model.load_weights(checkpoint_path)

# 3.用加载的权重进行验证
# Re-evaluate the model
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100 * acc))

# 感觉变低了...毕竟临时训练的模型
# 32/32 - 0s - loss: 0.4327 - sparse_categorical_accuracy: 0.8640 - 72ms/epoch - 2ms/step
# Restored model, accuracy: 86.40% 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

上述代码可将权重存储到检查点格式文件(仅包含二进制格式训练权重) 的合集中。检查点包含:

  • 一个或多个包含模型权重的分片。
  • 一个索引文件,指示哪些权重存储在哪个分片中。

如果您在一台计算机上训练模型,您将获得一个具有如下后缀的分片:.data-00000-of-00001

2.保存整个模型

调用 tf.keras.Model.save 以将模型的架构、权重和训练配置保存在单个 file/folder 中。这样一来,可以导出模型,以便在不访问原始 Python 代码的情况下使用它。由于优化器状态已经恢复,可以从中断的位置恢复训练。
整个模型可以保存为两种不同的文件格式(SavedModel 和 HDF5)。TensorFlow SavedModel 格式是 TF2.x 中的默认文件格式。但是,模型能够以 HDF5 格式保存。
保存全功能模型会非常有用,可以在 TensorFlow.js(Saved Model、HDF5)中加载它们,然后在网络浏览器中训练和运行,或者使用 TensorFlow Lite(Saved Model、HDF5)转换它们以在移动设备上运行自定义对象(例如,子类化模型或层)在保存和加载时需要特别注意。

# 保存模型(不兼容v1模型)
model.save('saved_model/my_model')
# 加载模型
new_model = tf.keras.models.load_model('saved_model/my_model')
# 检查模型
new_model.summary()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

调整超参

超参是在开始机器学习之前,就人为设置好的参数。
通常情况下,需要对超参数进行优化,给学习机选择一组最优超参数,以提高学习的性能和效果。
超参数是控制训练过程和 ML 模型拓扑的变量。这些变量在训练过程中保持不变,并会直接影响 ML 程序的性能。超参数有两种类型:

  1. 模型超参数:影响模型的选择,例如隐藏层的数量和宽度
  2. 算法超参数:影响学习算法的速度和质量,例如随机梯度下降 (SGD) 的学习率以及 k 近邻 (KNN) 分类器的近邻数
如何调教一组超参

同样是Tensorflow官网的栗子
Keras Tuner 是一个库,可帮助我们为 TensorFlow 程序选择最佳的超参数集。为我们的机器学习 (ML) 应用选择正确的超参数集,这一过程称为_超参数调节_或_超调_。
首先需要导入这个库

# 经过我的测试
# conda install 找不到这个库,可能是我的版本的问题
# 导入用import keras_tuner as kt
pip install -q -U keras-tuner
  • 1
  • 2
  • 3
  • 4

然后需要定义一个模型,我们称之为超模型
可以通过两种方式定义超模型:

  • 使用模型构建工具函数
  • 将 Keras Tuner API 的 HyperModel 类子类化
def model_builder(hp):
    model = keras.Sequential()
    # 采用的仍是fashion_mnist所以把输入打平
    model.add(keras.layers.Flatten(input_shape=(28, 28)))

    # 为第一层的神经元数调优,设置其为超参
    # 设定范围为32-512个
    hp_units = hp.Int('units', min_value=32, max_value=512, step=32)
    model.add(keras.layers.Dense(units=hp_units, activation='relu'))
    model.add(keras.layers.Dense(10))

    # 为学习率调优,设置它为超参
    # 设定范围为 0.01, 0.001, or 0.0001
    hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4])

    # 编译模型
    model.compile(optimizer=keras.optimizers.Adam(learning_rate=hp_learning_rate),
                  loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])

    return model
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

开始进行魔法调参
实例化调节器以执行超调。Keras Tuner 提供了四种调节器:RandomSearch、Hyperband、BayesianOptimization 和 Sklearn。在本教程中,您将使用 Hyperband 调节器。
要实例化 Hyperband 调节器,必须指定超模型、要优化的 objective 和要训练的最大周期数 (max_epochs)。

tuner = kt.Hyperband(model_builder,
                     objective='val_accuracy',
                     max_epochs=10,
                     factor=3,
                     directory='my_dir',
                     project_name='intro_to_kt')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Hyperband 调节算法使用自适应资源分配和早停法来快速收敛到高性能模型。该过程采用了体育竞技争冠模式的排除法。算法会将大量模型训练多个周期,并仅将性能最高的一半模型送入下一轮训练。(什么大逃杀模式)Hyperband 通过计算 1 + logfactor(max_epochs) 并将其向上舍入到最接近的整数来确定要训练的模型的数量。
创建回调以在验证损失达到特定值后提前停止训练。

stop_early = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)
  • 1


运行超参数搜索。除了上面的回调外,搜索方法的参数也与 tf.keras.model.fit 所用参数相同。

tuner.search(img_train, label_train, epochs=50, validation_split=0.2, callbacks=[stop_early])

# 找到最佳超参
best_hps=tuner.get_best_hyperparameters(num_trials=1)[0]

# 输出
print(f"""
The hyperparameter search is complete. The optimal number of units in the first densely-connected
layer is {best_hps.get('units')} and the optimal learning rate for the optimizer
is {best_hps.get('learning_rate')}.
""")

# 发现最佳的情况是192个神经元,学习率0.001
# Trial 30 Complete [00h 00m 36s]
# val_accuracy: 0.8759999871253967
# 
# Best val_accuracy So Far: 0.887333333492279
# Total elapsed time: 00h 07m 28s
# INFO:tensorflow:Oracle triggered exit
# 
# The hyperparameter search is complete. The optimal number of units in the first densely-connected
# layer is 192 and the optimal learning rate for the optimizer
# is 0.001.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

接下来就是拿着超参去训练模型了,这就不用赘述了吧

常用损失函数

交叉熵损失Cross Entropy(ce) loss

交叉熵是信息论中的一个重要概念,主要用于衡量两个概率分布之间的差异image.png
其中p表示样本真实概率分布,q表示模型预测概率分布,n是总样本个数
就5分类[0,1,2,3,4]而言,预测输出的是每类的概率,一般是经过softmax之后的,各类之和为1。交叉熵函数可以由最大似然函数在伯努利分布(0-1分布)的条件下推导出来,似然函数就是在某个参数下,整体估计真实情况一样的概率,越大代表越相近。

0-1损失

一般用于二分类y∈[0, 1]或者y∈[-1, 1],当预测值y’和y相等时,损失为0;不等时损失为1,不常用。
image.png

对数损失log-loss

其中P(Y|X)条件概率,表示X正确分类为Y的概率。交叉熵损失也是对数损失的一种。最小化交叉熵函数的本质就是对数似然函数的最大化
image.png

均方误差损失Mean Square Error(MSE)

一个距离计算,常用回归计算
image.png

绝对值(absolute)损失

L1损失对应绝对值损失;假设样本服从拉普拉斯分布
L2损失对应平方损失,没有除以N做平均;假设样本服从标准高斯分布
image.png


参考资料

常用损失函数
Tensorflow2.0教程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/123836
推荐阅读
相关标签
  

闽ICP备14008679号