深度学习Trick——用权重约束减轻深层网络过拟合|附(Keras)实现代码

在深度学习中,批量归一化(batch normalization)以及对损失函数加一些正则项这两类方法,一般可以提升模型的性能。这两类方法基本上都属于权重约束,用于减少深度学习神经网络模型对训练数据的过拟合,并改善模型对新数据的性能。
       目前,存在多种类型的权重约束方法,例如最大化或单位向量归一化,有些方法也必须需要配置超参数。
       在本教程中,使用Keras API,用于向深度学习神经网络模型添加权重约束以减少过拟合。
       完成本教程后,您将了解:

  • 如何使用Keras API创建向量范数约束;
  • 如何使用Keras API为MLP、CNN和RNN层添加权重约束;
  • 如何通过向现有模型添加权重约束来减少过度拟合;

下面,让我们开始吧。

本教程分为三个部分:

  • Keras中的权重约束;
  • 图层上的权重约束;
  • 权重约束案例研究;

Keras中权重约束

Keras API支持权重约束,且约束可以按每层指定。
       使用约束通常涉及在图层上为输入权重设置kernel_constraint参数,偏差权重设置为bias_constraint。通常,权重约束方法不涉及偏差权重。
       一组不同的向量规范在keras.constraints模块可以用作约束:

  • 最大范数(max_norm):强制权重等于或低于给定限制;
  • 非负规范(non_neg):强制权重为正数;
  • 单位范数(unit_norm):强制权重为1.0;
  • Min-Max范数(min_max_norm):强制权重在一个范围之间;

例如,可以导入和实例化约束:

# import norm
from keras.constraints import max_norm
# instantiate norm
norm = max_norm(3.0)

图层上的权重约束

权重规范可用于Keras的大多数层,下面介绍一些常见的例子:

MLP权重约束

下面的示例是在全连接层上设置最大范数权重约束:

# example of max norm on a dense layer
from keras.layers import Dense
from keras.constraints import max_norm
...
model.add(Dense(32, kernel_constraint=max_norm(3), bias_constraint==max_norm(3)))
...

CNN权重约束

下面的示例是在卷积层上设置最大范数权重约束:

# example of max norm on a cnn layer
from keras.layers import Conv2D
from keras.constraints import max_norm
...
model.add(Conv2D(32, (3,3), kernel_constraint=max_norm(3), bias_constraint==max_norm(3)))
...

RNN权重约束

与其他图层类型不同,递归神经网络允许我们对输入权重和偏差以及循环输入权重设置权重约束。通过图层的recurrent_constraint参数设置递归权重的约束。
       下面的示例是在LSTM图层上设置最大范数权重约束:

# example of max norm on an lstm layer
from keras.layers import LSTM
from keras.constraints import max_norm
...
model.add(LSTM(32, kernel_constraint=max_norm(3), recurrent_constraint=max_norm(3), bias_constraint==max_norm(3)))
...

基于以上的基本知识,下面进行实例实践。

权重约束案例研究

在本节中,将演示如何使用权重约束来减少MLP对简单二元分类问题的过拟合问题。
       此示例只是提供了一个模板,读者可以举一反三,将权重约束应用于自己的神经网络以进行分类和回归问题。

二分类问题

使用标准二进制分类问题来定义两个半圆观察,每个类一个半圆。其中,每个观测值都有两个输入变量,它们具有相同的比例,输出值分别为0或1,该数据集也被称为“ 月亮”数据集,这是由于绘制时,每个类中出现组成的形状类似于月亮。
       可以使用make_moons()函数生成观察结果,设置参数为添加噪声、随机关闭,以便每次运行代码时生成相同的样本。

# generate 2d classification dataset
X, y = make_moons(n_samples=100, noise=0.2, random_state=1)

可以在图表上绘制两个变量x和y坐标,并将数据点所属的类别的颜色作为观察的颜色。
       下面列出生成数据集并绘制数据集的完整示例:

# generate two moons dataset
from sklearn.datasets import make_moons
from matplotlib import pyplot
from pandas import DataFrame
# generate 2d classification dataset
X, y = make_moons(n_samples=100, noise=0.2, random_state=1)
# scatter plot, dots colored by class value
df = DataFrame(dict(x=X[:,0], y=X[:,1], label=y))
colors = {0:‘red‘, 1:‘blue‘}
fig, ax = pyplot.subplots()
grouped = df.groupby(‘label‘)
for key, group in grouped:
    group.plot(ax=ax, kind=‘scatter‘, x=‘x‘, y=‘y‘, label=key, color=colors[key])
pyplot.show()

运行该示例会创建一个散点图,可以从图中看到,对应类别显示的图像类似于半圆形或月亮形状。

上图的数据集表明它是一个很好的测试问题,因为不能用直线划分,需要非线性方法,比如神经网络来解决。
       只生成了100个样本,这对于神经网络而言较小,也提供了过拟合训练数据集的概率,并且在测试数据集上具有更高的误差。因此,也是应用正则化的一个好例子。此外,样本具有噪声,使模型有机会学习不一致的样本的各个方面。

多层感知器过拟合

在机器学习力,MLP模型可以解决这类二进制分类问题。
       MLP模型只具有一个隐藏层,但具有比解决该问题所需的节点更多的节点,从而提供过拟合的可能。
       在定义模型之前,需要将数据集拆分为训练集和测试集,按照3:7的比例将数据集划分为训练集和测试集。

# generate 2d classification dataset
X, y = make_moons(n_samples=100, noise=0.2, random_state=1)
# split into train and test
n_train = 30
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]

接下来,定义模型。隐藏层的节点数设置为500、激活函数为RELU,但在输出层中使用Sigmoid激活函数以预测输出类别为0或1。
       该模型使用二元交叉熵损失函数进行优化,这类激活函数适用于二元分类问题和Adam版本梯度下降方法。

# define model
model = Sequential()
model.add(Dense(500, input_dim=2, activation=‘relu‘))
model.add(Dense(1, activation=‘sigmoid‘))
model.compile(loss=‘binary_crossentropy‘, optimizer=‘adam‘, metrics=[‘accuracy‘])

然后,设置迭代次数为4,000次,默认批量训练样本数量为32。

# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)

这里将测试数据集作为验证数据集验证算法的性能:

# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print(‘Train: %.3f, Test: %.3f‘ % (train_acc, test_acc))

最后,绘制出模型每个时期在训练和测试集上性能。如果模型确实对训练数据集过拟合了,对应绘制的曲线将会看到,模型在训练集上的准确度继续增加,而测试集上的性能是先上升,之后下降。

# plot history
pyplot.plot(history.history[‘acc‘], label=‘train‘)
pyplot.plot(history.history[‘val_acc‘], label=‘test‘)
pyplot.legend()
pyplot.show()

将以上过程组合在一起,列出完整示例:

# mlp overfit on the moons dataset
from sklearn.datasets import make_moons
from keras.layers import Dense
from keras.models import Sequential
from matplotlib import pyplot
# generate 2d classification dataset
X, y = make_moons(n_samples=100, noise=0.2, random_state=1)
# split into train and test
n_train = 30
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]
# define model
model = Sequential()
model.add(Dense(500, input_dim=2, activation=‘relu‘))
model.add(Dense(1, activation=‘sigmoid‘))
model.compile(loss=‘binary_crossentropy‘, optimizer=‘adam‘, metrics=[‘accuracy‘])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print(‘Train: %.3f, Test: %.3f‘ % (train_acc, test_acc))
# plot history
pyplot.plot(history.history[‘acc‘], label=‘train‘)
pyplot.plot(history.history[‘val_acc‘], label=‘test‘)
pyplot.legend()
pyplot.show()

运行该示例,给出模型在训练数据集和测试数据集上的性能。
       可以看到模型在训练数据集上的性能优于测试数据集,这是发生过拟合的标志。鉴于神经网络和训练算法的随机性,每次仿真的具体结果可能会有所不同。因为模型是过拟合的,所以通常不会期望在相同数据集上能够重复运行得到相同的精度。

Train: 1.000, Test: 0.914

创建一个图,显示训练和测试集上模型精度的线图。从图中可以看到模型过拟合时的预期形状,其中测试精度达到一个临界点后再次开始减小。

具有权重约束的多层感知器过拟合

为了和上面做对比,现在对MLP使用权重约束。目前,有一些不同的权重约束方法可供选择。本文选用一个简单且好用的约束——简单地标准化权重,使得其范数等于1.0,此约束具有强制所有传入权重变小的效果。
       在Keras中可以通过使用unit_norm来实现,并且将此约束添加到第一个隐藏层,如下所示:

model.add(Dense(500, input_dim=2, activation=‘relu‘, kernel_constraint=unit_norm()))

此外,也可以通过使用min_max_norm并将minmaximum设置为1.0 来实现相同的结果,例如:

model.add(Dense(500, input_dim=2, activation=‘relu‘, kernel_constraint=min_max_norm(min_value=1.0, max_value=1.0)))

但是无法通过最大范数约束获得相同的结果,因为它允许规范等于或低于指定的限制; 例如:

model.add(Dense(500, input_dim=2, activation=‘relu‘, kernel_constraint=max_norm(1.0)))

下面列出具有单位规范约束的完整代码:

# mlp overfit on the moons dataset with a unit norm constraint
from sklearn.datasets import make_moons
from keras.layers import Dense
from keras.models import Sequential
from keras.constraints import unit_norm
from matplotlib import pyplot
# generate 2d classification dataset
X, y = make_moons(n_samples=100, noise=0.2, random_state=1)
# split into train and test
n_train = 30
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]
# define model
model = Sequential()
model.add(Dense(500, input_dim=2, activation=‘relu‘, kernel_constraint=unit_norm()))
model.add(Dense(1, activation=‘sigmoid‘))
model.compile(loss=‘binary_crossentropy‘, optimizer=‘adam‘, metrics=[‘accuracy‘])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print(‘Train: %.3f, Test: %.3f‘ % (train_acc, test_acc))
# plot history
pyplot.plot(history.history[‘acc‘], label=‘train‘)
pyplot.plot(history.history[‘val_acc‘], label=‘test‘)
pyplot.legend()
pyplot.show()

运行该示例,给出模型在训练数据集和测试数据集上的性能。
       从下图可以看到,对权重进行严格约束确实提高了模型在验证集上的性能,并且不会影响训练集的性能。

Train: 1.000, Test: 0.943

从训练和测试精度曲线图来看,模型已经在训练数据集上不再过拟合了,且模型在训练和测试数据集的精度保持在一个稳定的水平。

扩展

本节列出了一些读者可能希望探索扩展的教程:

  • 报告权重标准:更新示例以计算网络权重的大小,并证明使用约束后,确实使得幅度更小;
  • 约束输出层:更新示例以将约束添加到模型的输出层并比较结果;
  • 约束偏置:更新示例以向偏差权重添加约束并比较结果;
  • 反复评估:更新示例以多次拟合和评估模型,并报告模型性能的均值和标准差;

原文链接
本文为云栖社区原创内容,未经允许不得转载。

原文地址:https://www.cnblogs.com/yunqishequ/p/10043298.html

时间: 2024-08-29 23:35:19

深度学习Trick——用权重约束减轻深层网络过拟合|附(Keras)实现代码的相关文章

深度学习框架哪家强:TensorFlow?Caffe?MXNet?Keras?PyTorch?

深度学习框架哪家强:TensorFlow?Caffe?MXNet?Keras?PyTorch?对于这几大框架在运行各项深度任务时的性能差异如何,各位读者不免会有所好奇. 微软数据科学家Ilia Karmanov最新测试的结果显示,亚马逊MXNet在CNN.RNN与NLP情感分析任务上性能强劲,而TensorFlow仅擅长于特征提取. 测试详情更新在Ilia Karmanov的GitHub项目DeepLearningFrameworks(https://github.com/ilkarman/De

深度学习训练技巧---权重初始化

全零初始化 全零初始化即所有的变量均被初始化为0,这应该是最笨.最省事的随机化方法了.然而这种偷懒的初始化方法非常不适合深度学习,因为这种初始化方法没有打破神经元之间的对称性,将导致收敛速度很慢甚至训练失败. 常量初始化(constant) 把权值或者偏置初始化为一个常数,具体是什么常数,可以自己定义 高斯分布初始化(gaussian) 需要给定高斯函数的均值与标准差 positive_unitball初始化 让每一个神经元的输入的权值和为 1,例如:一个神经元有100个输入,让这100个输入的

分享《深度学习入门:基于Python的理论与实现 》中文版PDF和源代码

下载:(https://pan.baidu.com/s/1agBctMG7HF45VwhYpQHDSQ) <深度学习入门:基于Python的理论与实现>高清中文版PDF+源代码 高清中文版PDF,314页,带目录标签,可复制粘贴,高清晰.配套源代码. 深度学习真正意义上的入门书,深入浅出地剖析了深度学习的原理和相关技术.书中使用Python3,尽量不依赖外部库或工具,从基本的数学知识出发,带领读者从零创建一个经典的深度学习网络,使读者在此过程中逐步理解深度学习. 其中,高清中文版如图: 如图:

深度学习原理与框架-递归神经网络-RNN网络基本框架(代码?) 1.rnn.LSTMCell(生成单层LSTM) 2.rnn.DropoutWrapper(对rnn进行dropout操作) 3.tf.contrib.rnn.MultiRNNCell(堆叠多层LSTM) 4.mlstm_cell.zero_state(state初始化) 5.mlstm_cell(进行LSTM求解)

问题:LSTM的输出值output和state是否是一样的 1. rnn.LSTMCell(num_hidden, reuse=tf.get_variable_scope().reuse)  # 构建单层的LSTM网络 参数说明:num_hidden表示隐藏层的个数,reuse表示LSTM的参数进行复用 2.rnn.DropoutWrapper(cell, output_keep_prob=keep_prob) # 表示对rnn的输出层进行dropout 参数说明:cell表示单层的lstm,o

Windows10+Anaconda3下深度学习环境创建。安装tensorflow(cpu版),theano,keras

一.安装Tensorflow9=(cpu版) 在cmd(命令行窗口win+R+输入cmd)或者Anaconda里,进入虚拟环境(conda activate + 虚拟环境名(不加,默认Base)),直接conda install tensorflow,然后自动下载相关依赖包 二.安装Theano 1.安装g++编译器(Theano需要g++编译器支持):conda install mingw libpython 2.安装Theano:输入conda install theano 3.导入后报错:

深度学习在图像识别中的研究进展与展望

深度学习在图像识别中的研究进展与展望 深度学习是近十年来人工智能领域取得的最重要的突破之一.它在语音识别.自然语言处理.计算机视觉.图像与视频分析.多媒体等诸多领域都取得了巨大成功.本文将重点介绍深度学习在物体识别.物体检测.视频分析的最新研究进展,并探讨其发展趋势. 1.深度学习发展历史的回顾 现在的深度学习模型属于神经网络.神经网络的历史可以追溯到上世纪四十年代,曾经在八九十年代流行.神经网络试图通过大脑认知的机理,解决各种机器学习的问题.1986年Rumelhart.Hinton和Will

MXNet设计笔记之:深度学习的编程模式比较

市面上流行着各式各样的深度学习库,它们风格各异.那么这些函数库的风格在系统优化和用户体验方面又有哪些优势和缺陷呢?本文旨在于比较它们在编程模式方面的差异,讨论这些模式的基本优劣势,以及我们从中可以学到什么经验. 我们主要关注编程模式本身,而不是其具体实现.因此,本文并不是一篇关于深度学习库相互比较的文章.相反,我们根据它们所提供的接口,将这些函数库分为几大类,然后讨论各类形式的接口将会对深度学习编程的性能和灵活性产生什么影响.本文的讨论可能不只针对于深度学习,但我们会采用深度学习的例子来分析和优

图像识别中的深度学习 转

转:http://mp.weixin.qq.com/s?__biz=MzAwNDExMTQwNQ==&mid=209152042&idx=1&sn=fa0053e66cad3d2f7b107479014d4478#rd#opennewwindow 1.深度学习发展历史 深度学习是近十年来人工智能领域取得的重要突破.它在语音识别.自然语言处理.计算机视觉.图像与视频分析.多媒体等诸多领域的应用取得了巨大成功.现有的深度学习模型属于神经网络.神经网络的起源可追溯到20世纪40年代,曾经

DeepMind背后的人工智能:深度学习原理初探

去年11月,一篇名为<Playing Atari with Deep Reinforcement Learning>的文章被初创人工智能公司DeepMind的员工上传到了arXiv网站.两个月之后,谷歌花了500万欧元买下了DeepMind公司,而人们对这个公司的了解仅限于这篇文章.近日,Tartu大学计算机科学系计算神经学小组的学者在robohub网站发表文章,阐述了他们对DeepMind人工智能算法的复现. 在arXiv发表的原始论文中,描述了一个单个的网络,它能够自我学习从而自动的玩一些