繁体   English   中英

在2D数据上演示Keras的过度拟合

[英]Demonstrating overfitting with Keras on 2D data

我是一位计算机科学老师,目前正在开设深度学习入门课程。 Python和Keras框架是我选择的工具。

我想通过在一些预定义的2D数据上训练越来越复杂的模型来向学生展示过拟合的地方,就像本示例末尾一样。

过度拟合演示1

同样的想法出现在吴安德(Andrew Ng) 关于神经网络调整课程的编程活动中。

过度拟合演示1

但是,无论我怎么努力,我都无法用Keras复制这种行为。 使用相同的数据集和超参数,决策边界始终“平滑”,并且模型永远不会适合数据集中的嘈杂点。 请在下面查看我的结果, 然后单击此处浏览相关代码。 这是相关的摘录:

# Varying the hidden layer size to observe underfitting and overfitting
plt.figure(figsize=(16, 32))
hidden_layer_dimensions = [1, 2, 3, 4, 5, 20, 50]
for i, hidden_layer_size in enumerate(hidden_layer_dimensions):
    fig = plt.subplot(4, 2, i+1)
    plt.title('Hidden Layer size: {:d}'.format(hidden_layer_size))

    model = Sequential()
    model.add(Dense(hidden_layer_size, activation='tanh', input_shape=(2,)))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(SGD(lr=1.0), 'binary_crossentropy', metrics=['accuracy'])
    history = model.fit(data, targets, verbose=0, epochs=50)

    plot_decision_boundary(lambda x: model.predict(x) > 0.5, data, targets, fig)

在此处输入图片说明

难道我做错了什么? Keras引入了一些内部优化机制吗? 我可以通过其他编译选择来缓解它们吗?

您的问题是所有示例都是大小不同的一层神经网络! 如果打印权重,则在增加图层大小(例如从5到50)后,您会注意到其他神经元(例如45个神经元)的权重接近于零,因此它们是相同的。

您已经增加了神经网络的深度,以查看过度拟合。 例如,我更改了您的代码,使得前两个示例是单层NN,第三个示例[[30,30,30,30])是四层NN(完整的源代码在这里 ):

# Generate moon-shaped data with less samples and more noise
# data, targets = make_moons(500, noise=0.45)
from sklearn.datasets import make_moons, make_classification

data, targets =  make_classification(n_samples = 200, n_features=2, n_redundant=0, n_informative=2,
                           random_state=2, n_clusters_per_class=2)
plot_data(data, targets)
plt.figure(figsize=(16, 32))
hidden_layer_dimensions = [[2], [20], [30, 30, 30, 30]]

for i, hidden_layer_sizes in enumerate(hidden_layer_dimensions):
    fig = plt.subplot(4, 2, i+1)
    plt.title('Hidden Layer size: {}'.format(str(hidden_layer_sizes)))
    model = Sequential()
    for j, layer_size in enumerate(hidden_layer_sizes):
      if j == 0:
        model.add(Dense(layer_size, activation='tanh', input_shape=(2,)))
      else:
        model.add(Dense(layer_size, activation='tanh'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(SGD(lr=0.1), 'binary_crossentropy', metrics=['accuracy'])
    history = model.fit(data, targets, verbose=0, epochs=500)
    plot_decision_boundary(lambda x: model.predict(x) > 0.5, data, targets, fig)

结果如下: 数据集 结果

您也可以使用Tensorflow Playground实现您的目标。 请检查一下! 它有一个不错的交互式用户界面

您还可以增加历元数,并使用“ relu”作为激活层,以便获得锐利的边缘,例如Andrew Ng。 我将您的笔记本在带有50个神经元的1层网络的协作实验室下运行,并向您的卫星添加了噪音,以便获得独立的彩色区域。 请看一下,别忘了激活GPU(执行/修饰符类型d'execution)。

# Varying the hidden layer size to observe underfitting and overfitting
plt.figure(figsize=(16, 32))
hidden_layer_dimensions = [50]
for i, hidden_layer_size in enumerate(hidden_layer_dimensions):
    fig = plt.subplot(4, 2, i+1)
    plt.title('Hidden Layer size: {:d}'.format(hidden_layer_size))

    model = Sequential()
    model.add(Dense(hidden_layer_size, activation='relu', input_shape=(2,)))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(SGD(lr=1.0), 'binary_crossentropy', metrics=['accuracy'])
    history = model.fit(data, targets, verbose=0, epochs=5000)

    plot_decision_boundary(lambda x: model.predict(x) > 0.5, data, targets, fig)

5000个纪元+ relu(看起来像您想要的)

5000个历元+ tanh(tanh为您平滑了太多曲线)

最终,我通过显着增加梯度下降和参数更新的次数来对数据进行过度拟合。 它与tanh和ReLU激活功能都非常有效。

这是更新的行:

history = model.fit(x_train, y_train, verbose=0, epochs=5000, batch_size=200)

完整的代码在这里 ,给出以下结果。

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM