赞
踩
机器学习拥有三个阶段:准备数据、建立模型、模型应用
准备数据阶段分三个步骤:收集数据、探索数据、数据预处理
建立模型分为三个步骤:训练模型、评估模型、优化模型,不断迭代
数据可能存在各种问题:数据缺失、数据不规范,有异常数据、非数值数据、无关数据和数据分布不均衡
训练模型又分为三步:1.根据实际问题和数据情况,选择一个合适的模型 2.根据具体问题来具体分析,构建损失函数 3.求解损失函数
Tensorflow官网拿来的例子
首先从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()
加载数据集会返回四个 NumPy 数组:
简单浏览数据集的形状
# 查看训练集图片形状
train_images.shape
# (60000, 28, 28) 60000条 28*28
# 查看训练集标签数量
len(train_labels)
# 60000 60000条
打印数据集
for i in range(10):
tf.print(train_images[i], summarize=-1) # -1表示完整打印
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)
图像是 28x28 的 NumPy 数组,像素值介于 0 到 255 之间。标签是整数数组,介于 0 到 9 之间。这些标签对应于图像所代表的服装类:
标签 | 类 |
---|---|
0 | T恤/上衣 |
1 | 裤子 |
2 | 套头衫 |
3 | 连衣裙 |
4 | 外套 |
5 | 凉鞋 |
6 | 衬衫 |
7 | 运动鞋 |
8 | 包 |
9 | 短靴 |
在训练网络之前,必须对数据进行预处理。通过以下代码可以看到图像的像素值介于0-255之间。
import matplotlib.pyplot as plt
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
我们需要将这些值缩小到0-255之间,以此输入到神经网络模型中进行训练,所以我们需要将训练集与测试集除以255
train_images = train_images / 255.0
test_images = test_images / 255.0
# 设置三层
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)
])
在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:
# 2.编译模型
model.compile(
# 优化器(梯度)
optimizer='adam',
# 损失函数
# 交叉熵函数
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
# 精度 准确
metrics=['accuracy'])
训练神经网络模型需要执行以下步骤:
将训练数据馈送给模型,由模型迭代训练
# 拟合(训练)
# 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
在测试集上评估模型的准确率
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 测试准确率略低于训练准确率
结果表明,模型在测试数据集上的准确率略低于训练数据集。训练准确率和测试准确率之间的差距代表_过拟合_。过拟合是指机器学习模型在新的、以前未曾见过的输入上的表现不如在训练数据上的表现。过拟合的模型会“记住”训练数据集中的噪声和细节,从而对模型在新数据上的表现产生负面影响。
附加一个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)
# 需要 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.保存 # 检查点保存路径 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%
上述代码可将权重存储到检查点格式文件(仅包含二进制格式训练权重) 的合集中。检查点包含:
如果您在一台计算机上训练模型,您将获得一个具有如下后缀的分片:.data-00000-of-00001
调用 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()
超参是在开始机器学习之前,就人为设置好的参数。
通常情况下,需要对超参数进行优化,给学习机选择一组最优超参数,以提高学习的性能和效果。
超参数是控制训练过程和 ML 模型拓扑的变量。这些变量在训练过程中保持不变,并会直接影响 ML 程序的性能。超参数有两种类型:
同样是Tensorflow官网的栗子
Keras Tuner 是一个库,可帮助我们为 TensorFlow 程序选择最佳的超参数集。为我们的机器学习 (ML) 应用选择正确的超参数集,这一过程称为_超参数调节_或_超调_。
首先需要导入这个库
# 经过我的测试
# conda install 找不到这个库,可能是我的版本的问题
# 导入用import keras_tuner as kt
pip install -q -U keras-tuner
然后需要定义一个模型,我们称之为超模型
可以通过两种方式定义超模型:
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
开始进行魔法调参
实例化调节器以执行超调。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')
Hyperband 调节算法使用自适应资源分配和早停法来快速收敛到高性能模型。该过程采用了体育竞技争冠模式的排除法。算法会将大量模型训练多个周期,并仅将性能最高的一半模型送入下一轮训练。(什么大逃杀模式)Hyperband 通过计算 1 + logfactor(max_epochs) 并将其向上舍入到最接近的整数来确定要训练的模型的数量。
创建回调以在验证损失达到特定值后提前停止训练。
stop_early = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)
运行超参数搜索。除了上面的回调外,搜索方法的参数也与 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.
接下来就是拿着超参去训练模型了,这就不用赘述了吧
交叉熵是信息论中的一个重要概念,主要用于衡量两个概率分布之间的差异
其中p表示样本真实概率分布,q表示模型预测概率分布,n是总样本个数
就5分类[0,1,2,3,4]而言,预测输出的是每类的概率,一般是经过softmax之后的,各类之和为1。交叉熵函数可以由最大似然函数在伯努利分布(0-1分布)的条件下推导出来,似然函数就是在某个参数下,整体估计和真实情况一样的概率,越大代表越相近。
一般用于二分类y∈[0, 1]或者y∈[-1, 1],当预测值y’和y相等时,损失为0;不等时损失为1,不常用。
其中P(Y|X)条件概率,表示X正确分类为Y的概率。交叉熵损失也是对数损失的一种。最小化交叉熵函数的本质就是对数似然函数的最大化
一个距离计算,常用回归计算
L1损失对应绝对值损失;假设样本服从拉普拉斯分布
L2损失对应平方损失,没有除以N做平均;假设样本服从标准高斯分布
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。