更好的深度学习神经网络速成课程。
在7天内提升深度学习模型的性能。
配置神经网络模型通常被称为“黑魔法”。
这是因为对于给定问题,配置网络没有硬性规定。我们无法分析计算给定数据集的最佳模型类型或模型配置。
幸运的是,现代深度学习库(如Keras)提供了已知可解决配置和训练神经网络时特定问题的技术。
在本速成课程中,您将发现如何在七天内自信地提升深度学习模型的性能。
这是一篇内容丰富且重要的文章。您可能想把它加入书签。
用我的新书《更好的深度学习》来启动你的项目,书中包含分步教程和所有示例的 Python 源代码文件。
让我们开始吧。
- 2020年1月更新:更新了Keras 2.3和TensorFlow 2.0的API。

如何获得更好的深度学习性能(7天迷你课程)
图片来源:Damian Gadal,保留部分权利。
本速成课程适合谁?
在开始之前,让我们确保您来对了地方。
以下列表提供了一些关于本课程设计对象的一般性指导。
您需要了解
- 掌握基本的Python和NumPy。
- 深度学习的Keras基础知识。
您不需要知道:
- 如何成为数学天才!
- 如何成为深度学习专家!
本速成课程将带您从一个略懂深度学习的开发者,成长为一个能够提升深度学习项目性能的开发者。
注意:本速成课程假设您已具备一个可运行的 Python 2 或 3 SciPy 环境,并至少安装了 NumPy 和 Keras 2。如果您在环境设置方面需要帮助,可以按照此处的逐步教程进行操作。
想要通过深度学习获得更好的结果吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
速成课程概览
本速成课程分为七节课。
您可以每天完成一节课(推荐),或者在一天内完成所有课程(硬核)。这真的取决于您的可用时间和热情程度。
以下七节课程将帮助您自信地提高深度学习模型的性能
- 第一课:更好的深度学习框架
- 第二课:批量大小
- 第三课:学习率调度
- 第四课:批量归一化
- 第五课:权重正则化
- 第六课:添加噪声
- 第七课:提前停止
每节课可能需要60秒到30分钟不等。请慢慢来,按照自己的节奏完成课程。在下面的评论中提问,甚至发布结果。
这些课程要求您自己去探索如何完成任务。我将为您提供提示,但每节课的重点之一是迫使您学习去哪里寻找帮助(提示:我所有的答案都在这个博客上,请使用搜索框)。
我确实以相关文章链接的形式提供了更多帮助,因为我希望您建立一些信心和动力。
在评论中发布您的结果;我会为您加油!
坚持下去;不要放弃。
注意:这只是一门速成课程。如需更多详细信息和完善的教程,请参阅我的相关书籍《更好的深度学习》。
第一课:更好的深度学习框架
在本课中,您将发现一个可用于系统地提升深度学习模型性能的框架。
Keras 等现代深度学习库允许您在几分钟内用几行代码定义并开始拟合各种神经网络模型。
然而,针对新的预测建模问题配置神经网络以获得良好性能仍然具有挑战性。
关于深度学习神经网络模型性能不佳,有三种直接的问题类型可以诊断;它们是:
- 学习问题。学习问题表现为模型无法有效学习训练数据集,或者在学习训练数据集时进展缓慢或性能不佳。
- 泛化问题。泛化问题表现为模型过拟合训练数据集,并在保留数据集上表现不佳。
- 预测问题。预测问题表现为随机训练算法对最终模型有强烈影响,导致行为和性能存在高度方差。
所提出的分解中三个领域之间的顺序关系使得深度学习模型性能问题可以首先被隔离,然后用特定的技术或方法进行解决。
我们可以将解决这些问题的技术总结如下
- 更好的学习。改进或加速神经网络模型权重响应训练数据集进行调整的技术。
- 更好的泛化能力。提高神经网络模型在保留数据集上性能的技术。
- 更好的预测。减少最终模型性能方差的技术。
您可以使用此框架首先诊断您遇到的问题类型,然后确定一种要评估的技术以尝试解决您的问题。
您的任务
本课中,您必须列出属于框架三个领域中每个领域两项技术或重点关注的方面。
有麻烦了?请注意,作为本迷你课程的一部分,我们将从三个领域中的两个领域中查看一些示例。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
下一步
在下一课中,您将学习如何通过批量大小来控制学习速度。
第二课:批量大小
在本课中,您将发现训练神经网络时批量大小的重要性。
神经网络使用梯度下降进行训练,其中用于更新权重的误差估计是基于训练数据集的子集计算的。
用于估计误差梯度的训练数据集中的样本数量称为批量大小,这是一个重要的超参数,它影响学习算法的动态。
批量大小的选择控制着算法学习的速度,例如:
- 批量梯度下降。批量大小设置为训练数据集中的样本数量,误差估计更准确,但权重更新之间的时间更长。
- 随机梯度下降。批量大小设置为1,误差估计有噪声,但权重更新频繁。
- 小批量梯度下降。批量大小设置为大于1且小于训练样本数量的值,介于批量梯度下降和随机梯度下降之间。
Keras 允许您通过 `fit()` 函数的 `batch_size` 参数来配置批量大小,例如:
1 2 |
# 拟合模型 历史 = 模型.拟合(训练X, 训练y, 历元数=1000, 批量大小=长度(训练X)) |
以下示例展示了在二分类问题上使用批量梯度下降的多层感知器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# 批量梯度下降示例 from sklearn.datasets import make_circles from keras.layers import Dense from keras.models import Sequential from keras.optimizers import SGD from matplotlib import pyplot # 生成数据集 X, y = make_circles(n_samples=1000, noise=0.1, random_state=1) # 分割成训练集和测试集 n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 定义模型 model = Sequential() 模型.添加(密集(50, 输入维度=2, 激活='relu')) 模型.添加(密集(1, 激活='sigmoid')) # 编译模型 opt = SGD(lr=0.01, momentum=0.9) 模型.编译(损失='binary_crossentropy', 优化器=opt, 指标=['accuracy']) # 拟合模型 历史 = 模型.拟合(训练X, 训练y, 验证数据=(测试X, 测试y), 历元数=1000, 批量大小=长度(训练X), 详细模式=0) # 评估模型 _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) 打印('训练: %.3f, 测试: %.3f' % (train_acc, test_acc)) # 绘制损失学习曲线 pyplot.子图(211) pyplot.标题('交叉熵损失', 填充=-40) pyplot.绘制(历史.历史['loss'], 标签='train') pyplot.绘制(历史.历史['val_loss'], 标签='test') pyplot.legend() # 绘制准确率学习曲线 pyplot.子图(212) pyplot.标题('准确率', 填充=-40) pyplot.绘制(历史.历史['accuracy'], 标签='train') pyplot.绘制(历史.历史['val_accuracy'], 标签='test') pyplot.legend() pyplot.show() |
您的任务
在本课中,您必须使用每种梯度下降类型(批量、小批量和随机)运行代码示例,并描述它在训练过程中对学习曲线产生的影响。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
下一步
在下一课中,您将学习如何使用学习率调度在训练期间微调模型。
第三课:学习率调度
在本课中,您将学习如何配置自适应学习率调度,以便在训练过程中微调模型。
在此搜索过程的每个步骤中模型的变化量,或步长,被称为“学习率”,它可能是您神经网络最重要的超参数,用于在问题上获得良好性能。
配置固定学习率非常具有挑战性,需要仔细实验。使用固定学习率的替代方法是在训练过程中改变学习率。
Keras 提供了 `ReduceLROnPlateau` 学习率调度器,当检测到模型性能出现平台期时(例如,给定数量的训练周期内没有变化),它将调整学习率。例如:
1 2 |
# 定义学习率调度 rlrp = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=5, min_delta=1E-7, verbose=1) |
此回调旨在在模型停止改进后降低学习率,希望在训练期间微调模型权重。
以下示例展示了在二分类问题上使用学习率调度的多层感知器,如果验证损失在5个训练周期内没有变化,学习率将降低一个数量级。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# 学习率调度示例 from sklearn.datasets import make_circles from keras.layers import Dense from keras.models import Sequential from keras.optimizers import SGD 从 keras.回调 导入 ReduceLROnPlateau from matplotlib import pyplot # 生成数据集 X, y = make_circles(n_samples=1000, noise=0.1, random_state=1) # 分割成训练集和测试集 n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 定义模型 model = Sequential() 模型.添加(密集(50, 输入维度=2, 激活='relu')) 模型.添加(密集(1, 激活='sigmoid')) # 编译模型 opt = SGD(lr=0.01, momentum=0.9) 模型.编译(损失='binary_crossentropy', 优化器=opt, 指标=['accuracy']) # 定义学习率调度 rlrp = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=5, min_delta=1E-7, verbose=1) # 拟合模型 历史 = 模型.拟合(训练X, 训练y, 验证数据=(测试X, 测试y), 历元数=300, 详细模式=0, 回调=[rlrp]) # 评估模型 _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) 打印('训练: %.3f, 测试: %.3f' % (train_acc, test_acc)) # 绘制损失学习曲线 pyplot.子图(211) pyplot.标题('交叉熵损失', 填充=-40) pyplot.绘制(历史.历史['loss'], 标签='train') pyplot.绘制(历史.历史['val_loss'], 标签='test') pyplot.legend() # 绘制准确率学习曲线 pyplot.子图(212) pyplot.标题('准确率', 填充=-40) pyplot.绘制(历史.历史['accuracy'], 标签='train') pyplot.绘制(历史.历史['val_accuracy'], 标签='test') pyplot.legend() pyplot.show() |
您的任务
本课中,您必须在有和没有学习率调度的情况下运行代码示例,并描述学习率调度对训练过程中学习曲线的影响。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
下一步
在下一课中,您将学习如何通过批量归一化加速训练过程。
第四课:批量归一化
在本课中,您将学习如何使用批量归一化来加速深度学习神经网络的训练过程。
批量归一化,简称batchnorm,被提出作为一种技术,有助于协调模型中多个层的更新。
引入批量归一化的论文作者将训练期间输入分布的变化称为“内部协变量偏移”。批量归一化旨在通过缩放前一层的输出,特别是通过对每个小批量中每个输入变量的激活进行标准化(例如,前一层某个节点的激活),来对抗内部协变量偏移。
Keras 通过一个独立的 `BatchNormalization` 层支持批量归一化,该层可以添加到模型的隐藏层之间。例如:
1 |
模型.添加(BatchNormalization()) |
以下示例演示了在二分类问题上使用批量归一化的多层感知器模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# 批量归一化示例 from sklearn.datasets import make_circles from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD 从 keras.层 导入 BatchNormalization from matplotlib import pyplot # 生成数据集 X, y = make_circles(n_samples=1000, noise=0.1, random_state=1) # 分割成训练集和测试集 n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 定义模型 model = Sequential() 模型.添加(密集(50, 输入维度=2, 激活='relu')) 模型.添加(BatchNormalization()) 模型.添加(密集(1, 激活='sigmoid')) # 编译模型 opt = SGD(lr=0.01, momentum=0.9) 模型.编译(损失='binary_crossentropy', 优化器=opt, 指标=['accuracy']) # 拟合模型 历史 = 模型.拟合(训练X, 训练y, 验证数据=(测试X, 测试y), 历元数=300, 详细模式=0) # 评估模型 _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) 打印('训练: %.3f, 测试: %.3f' % (train_acc, test_acc)) # 绘制损失学习曲线 pyplot.子图(211) pyplot.标题('交叉熵损失', 填充=-40) pyplot.绘制(历史.历史['loss'], 标签='train') pyplot.绘制(历史.历史['val_loss'], 标签='test') pyplot.legend() # 绘制准确率学习曲线 pyplot.子图(212) pyplot.标题('准确率', 填充=-40) pyplot.绘制(历史.历史['accuracy'], 标签='train') pyplot.绘制(历史.历史['val_accuracy'], 标签='test') pyplot.legend() pyplot.show() |
您的任务
在本课中,您必须在有和没有批量归一化的情况下运行代码示例,并描述批量归一化对训练过程中学习曲线的影响。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
下一步
在下一课中,您将学习如何使用权重正则化来减少过拟合。
第五课:权重正则化
在本课中,您将学习如何使用权重正则化来减少深度学习神经网络的过拟合。
具有大权重的模型比具有小权重的模型更复杂。这表明网络可能对训练数据过度专业化。
可以更新学习算法,以鼓励网络使用小权重。
一种方法是改变用于网络优化的损失计算,使其也考虑权重的大小。这被称为权重正则化或权重衰减。
Keras 通过层上的 `kernel_regularizer` 参数支持权重正则化,该参数可以配置为使用 L1 或 L2 向量范数,例如:
1 |
模型.添加(密集(500, 输入维度=2, 激活='relu', 核正则化器=l2(0.01))) |
以下示例演示了在二分类问题上使用权重衰减的多层感知器模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# 权重衰减示例 from sklearn.datasets import make_circles from keras.models import Sequential from keras.layers import Dense 从 keras.正则化器 导入 l2 from matplotlib import pyplot # 生成数据集 X, y = make_circles(n_samples=100, noise=0.1, random_state=1) # 分割成训练集和测试集 n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 定义模型 model = Sequential() 模型.添加(密集(500, 输入维度=2, 激活='relu', 核正则化器=l2(0.01))) 模型.添加(密集(1, 激活='sigmoid')) # 编译模型 模型.编译(损失='binary_crossentropy', 优化器='adam', 指标=['accuracy']) # 拟合模型 历史 = 模型.拟合(训练X, 训练y, 验证数据=(测试X, 测试y), 历元数=4000, 详细模式=0) # 评估模型 _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) 打印('训练: %.3f, 测试: %.3f' % (train_acc, test_acc)) # 绘制损失学习曲线 pyplot.子图(211) pyplot.标题('交叉熵损失', 填充=-40) pyplot.绘制(历史.历史['loss'], 标签='train') pyplot.绘制(历史.历史['val_loss'], 标签='test') pyplot.legend() # 绘制准确率学习曲线 pyplot.子图(212) pyplot.标题('准确率', 填充=-40) pyplot.绘制(历史.历史['accuracy'], 标签='train') pyplot.绘制(历史.历史['val_accuracy'], 标签='test') pyplot.legend() pyplot.show() |
您的任务
在本课中,您必须在有和没有权重正则化的情况下运行代码示例,并描述它对训练过程中学习曲线的影响。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
下一步
在下一课中,您将学习如何通过向模型添加噪声来减少过拟合。
第六课:添加噪声
在本课中,您将发现,在训练过程中向神经网络添加噪声可以提高网络的鲁棒性,从而带来更好的泛化能力和更快的学习速度。
使用小数据集训练神经网络可能导致网络记忆所有训练样本,进而导致在保留数据集上表现不佳。
一种使输入空间更平滑且更易学习的方法是在训练期间向输入添加噪声。
在神经网络模型训练期间添加噪声具有正则化效果,进而提高了模型的鲁棒性。
可以通过 Keras 的 `GaussianNoise` 层向模型添加噪声。例如:
1 |
模型.添加(GaussianNoise(0.1)) |
噪声可以添加到模型的输入层或隐藏层之间。
以下示例演示了在二分类问题上,在隐藏层之间添加噪声的多层感知器模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# 添加噪声示例 from sklearn.datasets import make_circles from keras.models import Sequential from keras.layers import Dense 从 keras.层 导入 GaussianNoise from matplotlib import pyplot # 生成数据集 X, y = make_circles(n_samples=100, noise=0.1, random_state=1) # 分割成训练集和测试集 n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 定义模型 model = Sequential() 模型.添加(密集(500, 输入维度=2, 激活='relu')) 模型.添加(GaussianNoise(0.1)) 模型.添加(密集(1, 激活='sigmoid')) # 编译模型 模型.编译(损失='binary_crossentropy', 优化器='adam', 指标=['accuracy']) # 拟合模型 历史 = 模型.拟合(训练X, 训练y, 验证数据=(测试X, 测试y), 历元数=4000, 详细模式=0) # 评估模型 _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) 打印('训练: %.3f, 测试: %.3f' % (train_acc, test_acc)) # 绘制损失学习曲线 pyplot.子图(211) pyplot.标题('交叉熵损失', 填充=-40) pyplot.绘制(历史.历史['loss'], 标签='train') pyplot.绘制(历史.历史['val_loss'], 标签='test') pyplot.legend() # 绘制准确率学习曲线 pyplot.子图(212) pyplot.标题('准确率', 填充=-40) pyplot.绘制(历史.历史['accuracy'], 标签='train') pyplot.绘制(历史.历史['val_accuracy'], 标签='test') pyplot.legend() pyplot.show() |
您的任务
在本课中,您必须在有和没有添加噪声的情况下运行代码示例,并描述它对训练过程中学习曲线的影响。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
下一步
在下一课中,您将学习如何使用提前停止来减少过拟合。
第七课:提前停止
在本课中,您将发现,在神经网络过拟合训练数据集之前提前停止训练可以减少过拟合并提高深度神经网络的泛化能力。
训练神经网络的一个主要挑战是如何确定训练时长。
训练不足意味着模型将欠拟合训练集和测试集。训练过多意味着模型将过拟合训练数据集,并在测试集上表现不佳。
一种折衷方案是在训练数据集上进行训练,但在验证数据集上的性能开始下降时停止训练。这种简单、有效且广泛使用的神经网络训练方法称为提前停止。
Keras 通过 `EarlyStopping` 回调支持提前停止,该回调允许您指定在训练期间要监控的指标。
1 2 |
# 有耐心的提前停止 es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=200) |
以下示例演示了一个多层感知器,在二分类问题上使用提前停止,当验证损失在200个训练周期内没有改善时,它将停止训练。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# 提前停止示例 from sklearn.datasets import make_circles from keras.models import Sequential from keras.layers import Dense 从 keras.回调 导入 EarlyStopping from matplotlib import pyplot # 生成数据集 X, y = make_circles(n_samples=100, noise=0.1, random_state=1) # 分割成训练集和测试集 n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 定义模型 model = Sequential() 模型.添加(密集(500, 输入维度=2, 激活='relu')) 模型.添加(密集(1, 激活='sigmoid')) # 编译模型 模型.编译(损失='binary_crossentropy', 优化器='adam', 指标=['accuracy']) # 有耐心的提前停止 es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=200) # 拟合模型 历史 = 模型.拟合(训练X, 训练y, 验证数据=(测试X, 测试y), 历元数=4000, 详细模式=0, 回调=[es]) # 评估模型 _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) 打印('训练: %.3f, 测试: %.3f' % (train_acc, test_acc)) # 绘制损失学习曲线 pyplot.子图(211) pyplot.标题('交叉熵损失', 填充=-40) pyplot.绘制(历史.历史['loss'], 标签='train') pyplot.绘制(历史.历史['val_loss'], 标签='test') pyplot.legend() # 绘制准确率学习曲线 pyplot.子图(212) pyplot.标题('准确率', 填充=-40) pyplot.绘制(历史.历史['accuracy'], 标签='train') pyplot.绘制(历史.历史['val_accuracy'], 标签='test') pyplot.legend() pyplot.show() |
您的任务
在本课中,您必须在有和没有提前停止的情况下运行代码示例,并描述它对训练过程中学习曲线的影响。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
下一步
这是您的最后一课。
结束!
(看您已经取得了多大的进步!)
您做到了。干得好!
花点时间回顾一下您已经走了多远。
您发现了:
- 一个可以系统地诊断和改进深度学习模型性能的框架。
- 批量大小可用于控制训练过程中估计误差的精度和学习速度。
- 学习率调度可用于在训练期间微调模型权重。
- 批量归一化可用于显著加速神经网络模型的训练过程。
- 权重正则化将根据权重大小惩罚模型并减少过拟合。
- 添加噪声将使模型对输入差异更具鲁棒性,并减少过拟合。
- 提前停止将在正确的时间停止训练过程并减少过拟合。
这仅仅是您深度学习性能提升之旅的开始。请继续练习并发展您的技能。
迈出下一步,查阅我关于提升深度学习性能的书籍。
总结
您对这个迷你课程的学习情况如何?
您喜欢这个速成课程吗?
您有任何问题吗?有没有遇到什么难点?
告诉我。在下面留言。
嗨,Jason,
谢谢您的教程。
我正在尝试rlrp = ReduceLROnPlateau(monitor=’val_loss’, factor=0.1, patience=5, min_delta=1E-7, verbose=1)
但出现了以下错误;
TypeError Traceback (most recent call last)
in ()
5 # 定义学习率调度
6 # rlrp = ReduceLROnPlateau(monitor=’val_loss’, factor=0.5, patience=5, epsilon=1E-7, verbose=1)
----> 7 rlrp = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=5, min_delta=1E-7, verbose=1)
8
9
TypeError: __init__() 得到了意外的关键字参数'min_delta'
听到这个消息我很难过。
或许确认您的Keras版本是最新的,例如2.2.4+
另外,这里有更多关于API的帮助
https://keras.org.cn/callbacks/#reducelronplateau
非常好的教程
嘿,Jason,这是我两个月前开始学习机器学习以来,上过最愉快的课程。我15年前学过一些代数,但很难入门这个主题。
本文中的实用技巧以及现成的代码让我终于理解了这些主题。
谢谢!
谢谢,很高兴它有帮助!
嗨,Jason,首先感谢您的教程。
教程中的所有内容都运行良好,我按照它并从每个步骤中提取结论都获得了合理的结果,但在批量归一化步骤中,结果并不符合预期,因为使用批量归一化训练比不使用它花费的时间更长。
我做了两次测试,默认的300个 epoch 和 3000个 epoch,结果如下:
—— 使用批量归一化和 300 个 epoch ——> 15.8秒
—— 不使用批量归一化和 300 个 epoch ——> 12.8秒
—— 使用批量归一化和 3000 个 epoch ——> 2分28秒
—— 不使用批量归一化和 3000 个 epoch ——> 1分57秒
您知道我为什么会得到这样的结果吗?另外,没有批量归一化的模型,准确率和损失曲线要平滑得多。
谢谢您,请原谅我的英语。
(额外信息) 这些测试在带有 Keras GPU 功能的 Nvidia GTX 1080 TI 上运行。
是的,鉴于标准化激活所需的计算量增加,它确实会变慢。
做得好,你发现了!
嗨,Jason,
我想在我的数据集上尝试你的代码。它有6列30,000行,并且适合内存。是否建议使用数据集中的行数作为批量大小?换句话说,既然它适合内存,为什么我们还需要批量大小呢?
查尔斯
通常小批量表现更好。也许可以尝试一下,看看哪种模型/配置/数据/学习率等的组合最适合您。
你好,非常感谢您分享您的重要技巧
我很快就会开始使用 Keras
谢谢。
嗨,jason
能稍微修改一下代码,使其与 Flickr8k 配合使用吗?因为我真的无法使用
https://machinelearning.org.cn/develop-a-deep-learning-caption-generation-model-in-python/
请帮帮我们
抱歉,我没明白。您具体遇到了什么问题?
我如何像这样分割 Flicker8k 数据集?
n_train = 30
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]
您必须将图像和文本分开。
这个可能会有帮助
https://machinelearning.org.cn/prepare-photo-caption-dataset-training-deep-learning-model/
这是哪种错误?
文件 "C:\Users\Chen Mei\Anaconda3\lib\site-packages\matplotlib\artist.py", 第 895 行, 在 _update_property 中
raise AttributeError('未知属性 %s' % k)
AttributeError: 未知属性 pad
我以前从未见过此错误,也许可以发布到stackoverflow?
我每一步的结果
批量大小:训练:0.822,测试:0.792
学习率调度:训练:0.838,测试:0.846
批量归一化:训练:0.836,测试:0.858
权重正则化:训练:0.967,测试:0.814
添加噪声:训练:0.967,测试:0.771
提前停止:训练:0.967,测试:0.829
干得好!
第01课
1) 来自小型训练数据集或不完善数据集的学习问题
2) 来自两极化数据集或不完整数据集的泛化
3) 来自由相关元素组成的训练集或输入数据应随机化的预测
干得好!
我用的不是完全相同的代码,而是我一位同事根据不同的 epoch 数量调整过的代码。
批量大小:0.843,0.734
学习率调度:0.898,0.896
批量归一化:0.816,0.838
权重正则化:0.997,0.844
添加噪声:0.978,0.751
提前停止:0.977,0.849
我们使用 GTX 1080
干得好!
我尝试使用包含 9 个特征和 12,000 个观测值的二分类数据集来执行这些步骤。然而,我的结果似乎不太好。请问如何改进?
批量大小:训练准确率:61.56,测试准确率:60.38,训练损失:65.32,测试损失:67.01
学习率调度:训练准确率:62.63,测试准确率:60.9,训练损失:64.53,测试损失:66.86
批量归一化:训练准确率:64.75,测试准确率:61.47,训练损失:62.61,测试损失:67.26
权重正则化:训练准确率:63.32,测试准确率:61.47,训练损失:64.1,测试损失:67.22
添加噪声:训练准确率:80.34,测试准确率:62.23,训练损失:41.38,测试损失:90.38
提前停止:训练准确率:71.4,测试准确率:60.04,训练损失:53.26,测试损失:75.99
也许可以尝试改变模型。
也许可以尝试改变学习算法。
也许可以尝试转换数据。
…
更多想法在这里
https://machinelearning.org.cn/improve-deep-learning-performance/
关于批量大小训练
1. 通常准确率趋于平稳,但相关损失仍在减少:我认为这是因为准确率是分类的(上限为所有预测的数量),而损失是连续的。因此,看到损失曲线仍在减少并不一定意味着模型仍在学习。
2. 从计算能力方面:较少的 epoch 不一定意味着较少的计算。我宁愿使用反向传播次数作为衡量单位。
3. 做了几次实验,我发现最佳批量大小是模型稳定学习所需的最小批量(计算量最少),但我不会害怕使用更大的批量大小,因为反向传播的次数才是真正重要的。当然,所有内容都应该适合内存。
关于第三课
1. 惊讶于即使对于 batch_size=4(当然,也使用了动量),平台如何使学习曲线趋于平坦。
2. batch_size=16 仍然消耗更少的计算量(反向传播)。
感谢分享。
嗨,Jason,
我正在学习第三天:学习率调度。任务要求“我必须在有和没有学习率调度的情况下运行代码示例……”。所以我运行了代码
1) 使用学习率调度
....
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=300, verbose=0, callbacks=[rlrp])
....
这给了我结果
…
第 00292 纪元:ReduceLROnPlateau 将学习率降低至 9.999999682655225e-22。
第 00297 纪元:ReduceLROnPlateau 将学习率降低至 9.999999682655225e-23。
训练:0.828,测试:0.852
2) 没有学习率
....
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=300, verbose=0)
....
这给了我结果
…
第 00292 纪元:ReduceLROnPlateau 将学习率降低至 9.999999682655225e-22。
....
2020-09-07 21:15:12.704822: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor 设备 (0): 主机, 默认版本
训练:0.824,测试:0.848
我看到这两个结果似乎差不多。我方向对吗?
谢谢你。Philip Ching
注意:在2)中,以下行不应该出现。这是我的笔误。
第 00292 纪元:ReduceLROnPlateau 将学习率降低至 9.999999682655225e-22。
谢谢。
干得好!
是的,您正在正确的轨道上。
在
“第一课:更好的深度学习框架”中定义了两种类型的问题
—— 泛化问题
—— 预测问题。
泛化指的是测试集性能。
1) 那么它与预测有什么区别呢?
并且
2) “最终模型性能的方差”到底是什么?
(定义于:- 更好的预测。减少最终模型性能方差的技术。)?
泛化是指模型在新数据上的表现,例如“性能”。预测是模型的一个单一输出。模型性能是根据在新数据上的预测来估计的。
方差是模型预测的分布,或者是模型在新数据上评估时的性能分布,与模型的方差相关——它对训练数据或学习算法的随机性有多敏感。
所以,如果一个模型的最终模型性能方差很低,
它的准确率图表会很平滑吗(测试与 epoch 图上的尖峰更少)?
不,模型方差不会在学习曲线上表示。
从批量大小案例研究中我了解到
1.
批量梯度下降(Batch GD)
训练时间非常短
对于此数据集,批量梯度下降会欠拟合
损失图告诉我模型可以训练得更好
2.
随机梯度下降(Stochastic GD)
训练时间非常长
训练测试的损失和准确率看起来像是“良好拟合”
但包含极高的波动
(误差梯度中的噪声)
3.
小批量梯度下降(Mini-Batch GD)
训练时间正常。
对于我的批量大小25,它过拟合了数据
(训练损失迅速下降并收敛)
(测试损失在之前早期下降后开始增加)
(测试准确率高于训练准确率)
总结得很好!
从学习率案例研究中我了解到
1.
无 RLRP
损失需要很长时间才能收敛
图表“看起来”像一个良好拟合
2.
RLRP
损失迅速收敛并变得恒定
学习率在第 6, 11, 16, 21, 26… 纪元被 rlrp 改变。
准确率、损失图表在第 25 纪元变得恒定
测量第 26 纪元的学习率变化:1.0000000195414814e-26。
最佳学习率:1.0000000195414814e-26。
干得好!
从这个批量归一化案例研究中我了解到
没有 BN
准确率曲线很好
训练、测试损失需要很多 epoch 才能下降(训练缓慢)
有 BN
测试准确率优于训练准确率
波动很大(数据中有很多尖峰)
训练、测试损失迅速下降然后收敛(良好拟合)
BN 大大加快了训练过程,减少了 150 个 epoch
从这个权重正则化案例研究中我了解到
没有 WR
训练损失正常,但测试损失增加(严重过拟合)
测试准确率随着 epoch 减少
有 WR
测试准确率优于训练准确率
训练损失正常,但测试损失减少,但与训练损失相比仍然很高(比以前过拟合程度低)
测试准确率随着 epoch 略有增加
从这个高斯噪声案例研究中我了解到
没有 GN
训练损失正常,但测试损失增加(严重过拟合)
测试准确率随着 epoch 减少
有 GN
由于添加了 GN,尖峰过多
仔细比较图表
GN 略微减少了过拟合
干得好!
第二课:批量大小结果
批量训练数据大小 = 500 很好
随机批量大小 = 1,非常慢且训练效果不佳
小批量大小 = 250,我认为是三者中最好的,更快且训练结果更好。
小批量值:训练 = 0.838,测试 = 0.842
干得好!
第三课:学习率调度
使用 RLRP
训练:0.826,测试:0.854
不使用 TLRP
训练:0.828,测试:0.856
训练上的差异非常小
第四课:批量归一化
也许我没有理解这个函数,但使用批量归一化后,我的绘图上出现了大量的噪声,并且模型的训练速度比没有批量归一化时慢。
使用批量归一化
训练 = 0.816,测试 = 0.844
不使用批量归一化
训练 = 0.840,测试 = 0.852
干得好!
第五课:权重归一化
训练值非常相似,但两者运行时间差异巨大。
使用权重归一化
训练:0.967,测试:0.800
不使用权重归一化
训练:1.000,测试:0.771
干得漂亮!
你好 Jason,你的课程总是那么棒!!
然而,我只是对所使用的数据集大小做了一个评论
– 如果数据集大小为 (1000,2),您使用一个 50 个神经元的隐藏层(例如 model.add(Dense(50, input_dim=2, activation='relu')))
– 如果您使用大小为 (100, 2) 的数据集,您使用一个 500 个神经元的隐藏层(例如 model.add(Dense(500, input_dim=2, activation='relu')))。
对于隐藏层神经元数量的选择,有什么解释吗?
隐藏层神经元的数量是否取决于数据集的大小?
如果是,您能给我一种选择隐藏层最佳神经元数量的方法吗?
谢谢!!
谢谢!
不,节点数量是通过反复试验后选定的,更多细节请看这里
https://machinelearning.org.cn/faq/single-faq/how-many-layers-and-nodes-do-i-need-in-my-neural-network
谢谢你的答复!!
不客气。
第01课
更好的训练:定义良好的数据集,最小化噪声,训练样本数量,学习率。
更好的泛化:增加/减少层数(复杂度),丢弃层。
更好的预测:来自相同分布的数据,批量归一化。
感谢您提供的优质内容!
干得好!
第二课:批量大小
超参数:学习率=0.01,纪元数=1000,训练样本数=500。
批量梯度下降:我们计算所有训练样本上的误差函数。损失正在减少,但需要更多的纪元,因为我们只在每个纪元后才找到误差。所以我们只改变了权重1000次。由于我们在整个训练集之后更新权重,因此权重是通过考虑所有训练样本来改变的,所以曲线是平滑的。如果增加纪元数,我们将获得更好的结果。
随机梯度下降:我们更新每个训练样本后的权重。因此,有1000*1000次权重更新。曲线看起来有噪声,因为我们更新的权重可能不适合下一个训练样本。由于权重更新频繁,模型训练所需时间较长。
小批量梯度下降:我们在小批量后更新权重。它兼具前两种方法的优点。我们(某种程度上)频繁更新权重。曲线比随机梯度下降更平滑,因为权重不是针对1个样本训练,而是针对一个迷你批量(通常是2的n次方个样本)进行训练。训练更快,曲线也更平滑。
干得漂亮!
第二课
训练:0.834,测试:0.816 批量梯度下降
训练:0.816,测试:0.798 随机梯度下降
训练:0.844,测试:0.850 小批量大小=100
训练:0.842,测试:0.846 小批量大小=250
训练:0.814,测试:0.834 小批量大小=500
训练:0.828,测试:0.856 批量梯度下降,纪元数=5000
我观察到了与 Nitin 相同的行为:使用随机梯度下降时,权重更新次数更多,算法变慢,但训练集和验证集上的准确率迅速收敛到有噪声的饱和水平。引入不同大小的批量可以加速训练过程,平滑曲线,并导致逐渐收敛到0.8左右的饱和水平。然而,即使使用5000个纪元和全梯度下降,仅改变批量大小并不能使准确率超过90%。
嗨,Jason,
不确定这是否正确,但是
第1课
更好的训练:用更多数据集训练,多样化输入数据,使输入数据的顺序随机或打乱
更好的泛化:添加更多隐藏层,训练更多次(增加纪元?),重新缩放数据
更好的预测:不太确定,但我知道的是模型会取概率,然后使用该数字作为索引来访问数组进行分类作为输出。
干得好!
学习率调度
我以为 Adam 这样的优化器会自动调整学习率。Adam 和 ReduceLROnPlateau 的工作方式不同吗?