过拟合(高方差)与欠拟合(高偏差)

过拟合与欠拟合

1、机器学习的根本问题是优化和泛化之间的对立
优化(optimization)是指调节模型以在训练数据上得到最佳性能(即机器学习中的学习),而泛化(generalization)是指训练好的模型在前所未见的数据上的性能好坏。机器学习的目的当然是得到良好的泛化,但你无法控制泛化,只能基于训练数据调节模型。
2、优化和泛化是相关的:
训练数据上的损失越小,测试数据上的损失也越小。这时的模型是欠拟合(underfit)的,即仍有改进的空间,网络还没有对训练数据中所有相关模式建模。但在训练数据上迭代一定次数之后,泛化不再提高,验证指标先是不变,然后开始变差,即模型开始过拟合
3、降低过拟合的方法叫作正则化(regularization)。
4、将使用IMDB测试集作为我们的验证集
5、IMDB数据集包含了50000条偏向明显的评论,其中25000条作为训练集,25000作为测试集。label为pos(positive)和neg(negative)
6、另外在kaggle也有相似的数据
7、enumerate(sequence, [start=0])
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
8、防止过拟合的最简单的方法就是减小模型大小,减少模型中可学习参数的个数(这由层 数和每层的单元个数决定)

始终牢记:深度学习模型通常都很擅长拟合训练数据,但真正的挑战在于泛化,而不是拟合。

9、你使用的模型应该具有足够多的参数,以防欠拟合
要找到合适的模型大小,一般的工作流程是开始时选择相对较少的层和参数,然后逐渐增加层的大小或增加新层,直到这种增加对验证损失的影响变得很小
9、例如,IMDB在最后一层使用了sigmoid函数,回归的例子最后一层没有使用激活函数
10、模型优化-RMSprop优化模型RMSprop的处理方法
11、添加权重正则化
你可能知道奥卡姆剃刀(Occam’s razor)原理:如果一件事情有两种解释,那么最可能正 确的解释就是最简单的那个,即假设更少的那个。这个原理也适用于神经网络学到的模型:给 定一些训练数据和一种网络架构,很多组权重值(即很多模型)都可以解释这些数据。简单模 型比复杂模型更不容易过拟合。
这里的简单模型(simple model)是指参数值分布的熵更小的模型(或参数更少的模型,比如上一节的例子)。因此,一种常见的降低过拟合的方法就是强制让模型权重只能取较小的值, 从而限制模型的复杂度,这使得权重值的分布更加规则(regular)。这种方法叫作权重正则化(weight regularization),其实现方法是向网络损失函数中添加与较大权重值相关的成本(cost)。 这个成本有两种形式。
•L1 正则化(L1 regularization):添加的成本与权重系数的绝对值[权重的 L1 范数(norm)] 成正比。
•L2 正则化(L2 regularization):添加的成本与权重系数的平方(权重的 L2 范数)成正比。 神经网络的 L2 正则化也叫权重衰减(weight decay)。不要被不同的名称搞混,权重衰减 与 L2 正则化在数学上是完全相同的。
在 Keras 中,添加权重正则化的方法是向层传递 权重正则化项实例(weight regularizer instance)作为关键字参数。下列代码将向电影评论分类网络中添加 L2 权重正则化。

12、添加 dropout 正则化
dropout 是神经网络最有效也最常用的正则化方法之一,它是由多伦多大学的 Geoffrey Hinton和他的学生开发的。对某一层使用 dropout,就是在训练过程中随机将该层的一些输出特征舍弃(设置为 0)。假设在训练过程中,某一层对给定输入样本的返回值应该是向量 [0.2, 0.5, 1.3, 0.8, 1.1]。使用 dropout 后,这个向量会有几个随机的元素变成 0,比如 [0, 0.5,1.3, 0, 1.1]。dropout 比率(dropout rate)是被设为 0 的特征所占的比例,通常在 0.2~0.5 范围内。测试时没有单元被舍弃,而该层的输出值需要按 dropout 比率缩小,因为这时比训练时有更多的单元被激活,需要加以平衡。
假设有一个包含某层输出的 Numpy 矩阵 layer_output,其形状为 (batch_size, features)。训练时,我们随机将矩阵中一部分值设为 0。

13、总结一下,防止神经网络过拟合的常用方法包括:
•获取更多的训练数据
•减小网络容量
•添加权重正则化
•添加 dropout

由于电脑内存问题并没有跑出结果

import gc
import keras # Keras就是一个包含各种各样深度学习模型并且方便调用的库,通过接口你便可以构造想要的模型,调用即可
from keras.datasets import imdb
import numpy as np


(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words = 10000)
def vectorize_sequences(sequences, dimension = 10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.
    return results

x_train = vectorize_sequences(train_data)
x_test =  vectorize_sequences(test_data)
y_train = vectorize_sequences(train_labels).astype("float32")
y_test = vectorize_sequences(test_labels).astype("float32")

x_val = x_train[:3000]
partial_x_train = x_test[:3000]
y_val = y_train[:3000]
partial_y_train = y_test[:3000]

# 原始神经网络,定义层和激活函数
from keras import models
from keras import layers
original_models = models.Sequential()
original_models.add(layers.Dense(16, activation="relu", input_shape=(10000, )))
original_models.add(layers.Dense(16, activation="relu"))
original_models.add(layers.Dense(1, activation="sigmoid"))
# 添加损失函数和优化器还有评价指标
original_models.compile(optimizer = "rmsprop",
                        loss = "binary_crossentropy",
                        metrics = ["acc"])

# 添加一个小的网络模型 
smaller_models = models.Sequential()
smaller_models.add(layers.Dense(4, activation = "relu", input_shape = (10000, )))
smaller_models.add(layers.Dense(4, activaton = "relu"))
smaller_models.add(layers.Dense(1, activation = "sigmoid"))
original_models.compile(optimizer = "rmsprop",
                        loss = "binary_crossentrop",
                        metrics = ["acc"])

original_hist = original_models.fit(x_val, y_val,
                                    epochs = 20,
                                    batch_size = 512,
                                    validation_data = (partial_x_train, partial_y_train))

smaller_models_hist = smaller_models.fit(x_train, y_train,
                                         epochs = 20,
                                         batch_size = 512,
                                         validation_data = (x_test, y_test ))
epochs = range(1, 20)
original_val_loss = original_hist.history("val_loss")
smallers_models_val_loss = smaller_models_hist.history("val_loss")

import matplotlib.pyplot as plt

plt.plot(epochs, original_val_loss, "b+", label = "Original model")
plt.plot(epochs, smallers_models_val_loss, "bo", label = "smaller model")
plt.xlabel("Epocs")
plt.ylabel("Validation loss")
plt.legend()
plt.show()

'''
# 再向这个基准中添加一个容量更大的网络(容量远大于问题所需)。
bigger_model = models.Sequential()
bigger_model.add(layers.Dense(512, activation='relu', input_shape=(10000,)))
bigger_model.add(layers.Dense(512, activation='relu'))
bigger_model.add(layers.Dense(1, activation='sigmoid'))

bigger_model.compile(optimizer='rmsprop',
                     loss='binary_crossentropy',
                     metrics=['acc'])

bigger_model_hist = bigger_model.fit(x_train, y_train,
                                     epochs=20,
                                     batch_size=512,
                                     validation_data=(x_test, y_test))
# 下图显示了更大的网络与参考网络的性能对比。圆点是更大网络的验证损失值,十字是原始网络的验证损失值
bigger_model_val_loss = bigger_model_hist.history['val_loss']

plt.plot(epochs, original_val_loss, 'b+', label='Original model')
plt.plot(epochs, bigger_model_val_loss, 'bo', label='Bigger model')
plt.xlabel('Epochs')
plt.ylabel('Validation loss')
plt.legend()

plt.show()

# 下图同时给出了这两个网络的训练损失
original_train_loss = original_hist.history['loss']
bigger_model_train_loss = bigger_model_hist.history['loss']

plt.plot(epochs, original_train_loss, 'b+', label='Original model')
plt.plot(epochs, bigger_model_train_loss, 'bo', label='Bigger model')
plt.xlabel('Epochs')
plt.ylabel('Training loss')
plt.legend()

plt.show()

# 添加权重正则化
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'))


l2_model.compile(optimizer='rmsprop',
                 loss='binary_crossentropy',
                 metrics=['acc']) 

# 下图显示了 L2 正则化惩罚的影响
l2_model_hist = l2_model.fit(x_train, y_train,
                             epochs=20,
                             batch_size=512,
                             validation_data=(x_test, y_test))

l2_model_val_loss = l2_model_hist.history['val_loss']

plt.plot(epochs, original_val_loss, 'b+', label='Original model')
plt.plot(epochs, l2_model_val_loss, 'bo', label='L2-regularized model')
plt.xlabel('Epochs')
plt.ylabel('Validation loss')
plt.legend()

plt.show()


# 你还可以用 Keras 中以下这些权重正则化项来代替 L2 正则化

from keras import regularizers

# L1 regularization(L1 正则化)
regularizers.l1(0.001)

# L1 and L2 regularization at the same time(同时做 L1 和 L2 正则化)
regularizers.l1_l2(l1=0.001, l2=0.001)

#我们向 IMDB 网络中添加两个 Dropout 层,来看一下它们降低过拟合的效果我们向 IMDB 网络中添加两个 Dropout 层,来看一下它们降低过拟合的效果
dpt_model = models.Sequential()
dpt_model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
dpt_model.add(layers.Dropout(0.5))
dpt_model.add(layers.Dense(16, activation='relu'))
dpt_model.add(layers.Dropout(0.5))
dpt_model.add(layers.Dense(1, activation='sigmoid'))

dpt_model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['acc'])

dpt_model_hist = dpt_model.fit(x_train, y_train,
                               epochs=20,
                               batch_size=512,
                               validation_data=(x_test, y_test))

dpt_model_val_loss = dpt_model_hist.history['val_loss']

plt.plot(epochs, original_val_loss, 'b+', label='Original model')
plt.plot(epochs, dpt_model_val_loss, 'bo', label='Dropout-regularized model')
plt.xlabel('Epochs')
plt.ylabel('Validation loss')
plt.legend()

plt.show()
'''
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 过拟合欠拟合机器学习中常见的问题。 过拟合指的是模型在训练集上表现很好,但在新的、未见过的数据上表现不佳。这是因为模型“过于复杂”,它在训练集上学习了训练集的噪音,而无法适应新数据。 欠拟合指的是模型在训练集上和测试集上都表现不佳,这是因为模型“过于简单”,它无法捕捉到训练集中的复杂关系。 总之,过拟合是模型在训练集上表现过好,在测试集上表现过差,而欠拟合是模型在训练集和测试集上都表现不佳. ### 回答2: 过拟合欠拟合机器学习中常见的两种模型错误。 过拟合表示模型在训练数据上表现较好,但在测试数据上表现较差。过拟合一般发生在模型复杂度过或者训练数据过少的情况下。当模型过于复杂时,它会过度关注训练数据中的噪声或异常值,从而导致其捕捉到的模式过于特定,无法泛化到新的数据。过拟合的模型可能会出现较低的偏差(训练误差小),但较方差(测试误差大),即对训练数据敏感性,对新数据泛化能力差。 相反,欠拟合表示模型无法捕捉到数据中的全部模式和结构,无法很好地拟合训练数据。欠拟合一般发生在模型复杂度过低的情况下,或者训练数据中存在较多的噪声或复杂模式时。欠拟合的模型可能会出现较偏差(训练误差大),但较低的方差(测试误差小),即对训练数据敏感性低,对新数据泛化能力强。 区别总结如下: - 过拟合表示模型过于复杂,过度拟合训练数据,导致其在测试数据上表现较差;欠拟合表示模型过于简单,无法很好地拟合训练数据。 - 过拟合的模型具有低偏差方差欠拟合的模型具有偏差和低方差。 - 过拟合主要解决方法有降低模型复杂度、增加训练数据量、正则化等;欠拟合主要解决方法有增加模型复杂度、优化模型参数等。 ### 回答3: 过拟合欠拟合是在机器学习中常见的两种模型问题。过拟合指的是模型过度适应了训练数据集,导致在新的未见过的数据上表现不佳。欠拟合则是指模型无法学习到数据中的特征和规律,无论是在训练数据集还是未见过的新数据上都表现不佳。 过拟合的主要特征是模型在训练数据上表现非常好,但在测试数据上表现较差。原因通常是模型过于复杂,参数过多,或者训练数据集太小。过拟合的模型会记住训练集中的噪声和异常值,从而泛化性差。解决过拟合的方法包括增加训练数据,减少模型复杂度(如降低参数个数或使用正则化方法)以及采用交叉验证等。 相反,欠拟合的模型通常是由于模型过于简单,无法拟合数据中的复杂关系和特征。因此,无论在训练数据还是新数据上,欠拟合的模型都具有较的误差。解决欠拟合的方法包括增加模型复杂度、增加特征数量、改进特征提取方法等。 总而言之,过拟合欠拟合机器学习中常见的模型问题,过拟合指模型过于适应训练数据而泛化能力差,欠拟合指模型过于简单无法拟合数据的复杂规律。解决过拟合欠拟合的方法都需要在训练过程中进行调整,以使模型在未见过的新数据上表现更好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值