Yukyukuon / blog

博客的文章
1 stars 0 forks source link

Deep Learning with Python 4 #23

Open Yukyukuon opened 1 year ago

Yukyukuon commented 1 year ago

书第四章:机器学习基础

机器学习的4个分支

监督学习(Supervised learning)

无监督学习(Unsupervised learning)

无监督学习是指在没有目标的情况下寻找输入数据的有趣变换,其目的在于数据可视化、数据压缩、数据去噪或更好地理解数据中的相关性。降维(dimensionalityreduction)和聚类(clustering)都是众所周知的无监督学习方法。

自监督学习(Self-supervised Learning)

自监督学习是没有人工标注的标签的监督学习,你可以将它看作没有人类参与的监督学习。标签仍然存在(因为总要有什么东西来监督学习过程),但它们是从输入数据中生成的,通常是使用启发式算法生成的。

强化学习(Reinforcement learning)

在强化学习中,智能体(agent)接收有关其环境的信息,并学会选择使某种奖励最大化的行动。

评估机器学习模型

简单的留出验证(hold-out validation)

留出一定比例的数据作为测试集。在剩余的数据上训练模型,然后在测试集上评估模型。 但有一个缺点:如果可用的数据很少,那么可能验证集和测试集包含的样本就太少,从而无法在统计学上代表数据。这个问题很容易发现:如果在划分数据前进行不同的随机打乱,最终得到的模型性能差别很大,那么就存在这个问题。

K 折验证(K-fold validation)

将数据划分为大小相同的K 个分区。对于每个分区i,在剩余的K-1 个分区上训练模型,然后在分区i 上评估模型。最终分数等于K 个分数的平均值。对于不同的训练集- 测试集划分,如果模型性能的变化很大,那么这种方法很有用。与留出验证一样,这种方法也需要独立的验证集进行模型校正。

带有打乱数据的重复K 折验证(iterated K-fold validation with shuffling)

具体做法是多次使用K 折验证,在每次将数据划分为K 个分区之前都先将数据打乱。最终分数是每次K 折验证分数的平均值。注意,这种方法一共要训练和评估P×K 个模型(P是重复次数),计算代价很大。

数据预处理、特征工程和特征学习

数据预处理

向量化(Vectorization)

神经网络的所有输入和目标都必须是浮点数张量(在特定情况下可以是整数张量)。无论处理什么数据(声音、图像还是文本),都必须首先将其转换为张量,这一步叫作数据向量化(data vectorization)。

值标准化(Value Normalization)

输入数据应该具有以下特征:

处理缺失值

一般来说,对于神经网络,将缺失值设置为0 是安全的,只要0 不是一个有意义的值。网络能够从数据中学到0 意味着缺失数据,并且会忽略这个值。

注意,如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络不可能学会忽略缺失值。在这种情况下,你应该人为生成一些有缺失项的训练样本:多次复制一些训练样本,然后删除测试数据中可能缺失的某些特征。

特征工程(feature engineering)

将数据输入模型之前,利用你自己关于数据和机器学习算法(这里指神经网络)的知识对数据进行硬编码的变换(不是模型学到的),以改善模型的效果。

过拟合和欠拟合

优化(optimization)是指调节模型以在训练数据上得到最佳性能(即机器学习中的学习) 泛化(generalization)是指训练好的模型在前所未见的数据上的性能好坏 正则化(regularization)降低过拟合的方法
正则化的方法:

添加权重正则化

给定一些训练数据和一种网络架构,很多组权重值(即很多模型)都可以解释这些数据。简单模型比复杂模型更不容易过拟合。 简单模型(simple model)是指参数值分布的熵更小的模型(或参数更少的模型)。

一种常见的降低过拟合的方法就是强制让模型权重只能取较小的值,从而限制模型的复杂度,这使得权重值的分布更加规则(regular)。这种方法叫作权重正则化(weight regularization),其实现方法是向网络损失函数中添加与较大权重值相关的成本(cost)。 这个成本有两种形式:

# 添加L2正则化
from keras import regularizers
l2_model = models.Sequential()
l2_model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
                         activation='relu', input_shape=(10000,)))
l2_model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
                         activation='relu'))
l2_model.add(layers.Dense(1, activation='sigmoid'))

# 添加L1正则化,改为
regularizers.l1(0.001)

# 同时添加L1和L2正则化
regularizers.l1_l2(l1=0.001, l2=0.001)

添加dropout 正则化

对某一层使用dropout,就是在训练过程中随机将该层的一些输出特征舍弃(设置为0)。 dropout 比率(dropout rate)是被设为0 的特征所占的比例,通常在0.2~0.5范围内。测试时没有单元被舍弃,而该层的输出值需要按dropout 比率缩小,因为这时比训练时有更多的单元被激活,需要加以平衡。

# 训练时对激活矩阵使用dropout,并在训练时成比例增大。测试时激活矩阵保持不变
layer_output *= np.random.randint(0, high=2, size=layer_output.shape)
layer_output /= 0.5

在Keras 中,你可以通过Dropout 层向网络中引入dropout,dropout 将被应用于前面一层的输出。

model.add(layers.Dropout(0.5))

机器学习的通用工作流程

定义问题,收集数据集

只有明确了输入、输出以及所使用的数据,你才能进入下一阶段。注意你在这一阶段所做的假设。

选择衡量成功的指标

要控制一件事物,就需要能够观察它。要取得成功,就必须给出成功的定义:精度?准确率(precision)和召回率(recall)?客户保留率?衡量成功的指标将指引你选择损失函数,即模型要优化什么。它应该直接与你的目标(如业务成功)保持一致。

确定评估方法

一旦明确了目标,你必须确定如何衡量当前的进展。

准备数据

一旦知道了要训练什么、要优化什么以及评估方法,那么你就几乎已经准备好训练模型了。但首先你应该将数据格式化,使其可以输入到机器学习模型中(这里假设模型为深度神经网络)。

开发比基准更好的模型

这一阶段的目标是获得统计功效(statistical power),即开发一个小型模型,它能够打败纯随机的基准(dumb baseline)。 如果你尝试了多种合理架构之后仍然无法打败随机基准,那么原因可能是问题的答案并不在输入数据中。 一切顺利,你还需要选择三个关键参数来构建第一个工作模型:

问题类型 最后一层的激活 损失函数
二分类问题 sigmoid binary_crossentropy
多分类、单标签问题 softmax categorical_crossentropy
多分类、多标签问题 sigmoid binary_crossentropy
回归到任意值 mse
回归到0~1 范围内的值 sigmoid mse 或binary_crossentropy

扩大模型规模:开发过拟合的模型

一旦得到了具有统计功效的模型,问题就变成了:模型是否足够强大?它是否具有足够多的层和参数来对问题进行建模? 要搞清楚你需要多大的模型,就必须开发一个过拟合的模型

模型正则化与调节超参数(Regularizing your model and tuning your hyperparamenters)

你将不断地调节模型、训练、在验证数据上评估(这里不是测试数据)、再次调节模型,然后重复这一过程,直到模型达到最佳性能。

注意:每次使用验证过程的反馈来调节模型,都会将有关验证过程的信息泄露到模型中。如果只重复几次,那么无关紧要;但如果系统性地迭代许多次,最终会导致模型对验证过程过拟合(即使模型并没有直接在验证数据上训练)。这会降低验证过程的可靠性。

如果测试集上的性能比验证集上差很多,那么这可能意味着你的验证流程不可靠,或者你在调节模型参数时在验证数据上出现了过拟合。在这种情况下,你可能需要换用更加可靠的评估方法,比如重复的K 折验证。