政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(五)—— Dropout和批归一化

政安晨的个人主页政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏政安晨的机器学习笔记

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!

Dropout和批归一化是深度学习领域中常用的正则化技术,旨在提高模型的泛化能力和防止过拟合。

Dropout是由Hinton等人在2012年提出的一种正则化技术。它通过在训练过程中随机地将一部分神经元的输出设置为零,来减少神经网络中神经元之间的依赖关系。具体来说,对于每个训练样本,每个神经元都有一定的概率被丢弃,这样可以防止某些特定的神经元过于依赖于其他神经元,从而使得整个网络的泛化能力更强。在测试时,不再进行随机丢弃,而是将所有神经元的输出都保留下来,但要乘上一个与训练时丢弃概率成反比的因子,以保持输出值的期望不变。

批归一化是由Ioffe和Szegedy在2015年提出的一种归一化技术。它主要解决深度神经网络中的内部协变量转移问题,即前一层的参数更新会影响到后一层的输入分布,使得训练过程变得复杂。批归一化通过在每一层的输入上进行归一化操作,将每一层的输入都尽量保持在较小的范围内,可以加快训练速度并提高模型的泛化能力。具体来说,批归一化将每个特征维度的输入都减去其均值,并除以其标准差,然后再乘以一个可学习的缩放系数和位移系数。

总之,Dropout和批归一化是深度学习领域中常用的正则化技术

Dropout在训练过程中随机丢弃神经元的输出,减少网络的依赖关系,提高泛化能力;

批归一化通过归一化每层的输入,解决内部协变量转移问题,加快训练速度并提高模型的泛化能力。

Dropout和批归一化的作用添加这些特殊的层来防止过拟合并稳定训练。


前言

深度学习的世界远不止稠密层(dense layer)。您可以在模型中添加几十种不同类型的层(layer)。(尝试浏览一下Keras文档来了解一些示例!)有些层类似于稠密层,用于定义神经元之间的连接,而其他类型的层则可以进行预处理或其他形式的转换操作。

在本文中,我们将学习两种特殊的层,它们本身不包含任何神经元,但可以为模型添加一些功能,有时可以以各种方式受益这两种层在现代架构中经常使用。

Dropout

其中一种层是“dropout层”,它可以帮助纠正过拟合。

在上一篇文章中,我们讨论了过拟合是由网络在训练数据中学习到的虚假模式引起的。为了识别这些虚假模式,网络通常会依赖于非常特定的权重组合,一种“诱骗”权重。由于非常特定,它们往往很脆弱:去除其中一个,“诱骗”就会瓦解。

这就是Dropout的理念。为了打破这些诱骗,我们在训练的每一步中随机丢弃一部分层的输入单元,使网络更难学习训练数据中的那些虚假模式。相反,它必须搜索广泛、普遍的模式,这些模式的权重模式往往更加稳定。

在这里,在两个隐藏层之间添加了50%的Dropout。

你也可以将dropout看作是创建了一种网络集合

预测不再由一个大网络完成,而是由一组较小的网络委员会完成。委员会中的个体往往会犯不同类型的错误,但同时也会做出正确的判断,使得整个委员会的性能比任何一个个体网络都要好。(如果你熟悉随机森林作为决策树的集合,那就是相同的思想。)

增加 Dropout

在Keras中,dropout率参数rate定义了要关闭的输入单元的百分比。

将Dropout层放在希望应用dropout的层之前

keras.Sequential([# ...layers.Dropout(rate=0.3), # apply 30% dropout to the next layerlayers.Dense(16),# ...
])

批归一化

下一个我们要看的特殊层是执行“批量归一化”(或“batchnorm”)的层,它可以帮助纠正训练过程中的缓慢或不稳定的问题

在神经网络中,通常将所有数据放在一个共同的尺度上是一个好主意,例如使用scikit-learn的StandardScaler或MinMaxScaler。原因是SGD会按照数据产生的激活大小的比例来调整网络权重。产生非常不同大小激活的特征可能导致训练不稳定。

现在,如果在数据进入网络之前归一化是好的,那么在网络内部也进行归一化可能会更好!事实上,我们有一种特殊的层可以实现这一点,即批量归一化层。批量归一化层在每个批次进来时,首先使用自己的均值和标准差对批次进行归一化,然后还用两个可训练的重新缩放参数将数据放在一个新的尺度上。批量归一化实际上执行了一种协调的输入尺度调整。

大多数情况下,批量归一化被添加为优化过程的辅助手段(尽管它有时也可以帮助预测性能)具有批量归一化的模型通常需要更少的轮次来完成训练。此外,批量归一化还可以修复导致训练“陷入困境”的各种问题。如果在训练过程中遇到问题,考虑将批量归一化添加到您的模型中。

增加批量归一化

批量标准化似乎可以在网络的几乎任何位置使用。

可以将其放在一个层之后...

layers.Dense(16, activation='relu'),
layers.BatchNormalization(),

...或者在一层和其激活函数之间:

layers.Dense(16),
layers.BatchNormalization(),
layers.Activation('relu'),

如果你将它添加为网络的第一层,它可以充当一种自适应的预处理器,类似于Sci-Kit Learn的StandardScaler。

示例 - 使用Dropout和批归一化

在看TensorFlow和Keras的例子之前,我们先对比看一下pyTorch的例子:

import torch
import torch.nn as nn
import torch.optim as optim# 定义神经网络模型
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.fc1 = nn.Linear(10, 20)self.dropout = nn.Dropout(0.2)self.fc2 = nn.Linear(20, 10)self.bn = nn.BatchNorm1d(10)self.fc3 = nn.Linear(10, 1)def forward(self, x):x = self.fc1(x)x = self.dropout(x)x = self.fc2(x)x = self.bn(x)x = self.fc3(x)return x# 定义训练和测试数据
train_data = torch.randn(100, 10)
train_labels = torch.randn(100, 1)test_data = torch.randn(10, 10)
test_labels = torch.randn(10, 1)# 初始化模型和优化器
model = Net()
optimizer = optim.SGD(model.parameters(), lr=0.01)# 训练模型
model.train()
for epoch in range(100):optimizer.zero_grad()output = model(train_data)loss = nn.MSELoss()(output, train_labels)loss.backward()optimizer.step()# 测试模型
model.eval()
with torch.no_grad():test_output = model(test_data)test_loss = nn.MSELoss()(test_output, test_labels)print("Test Loss:", test_loss.item())

在上面这个示例中,我们定义了一个简单的神经网络模型。在模型的定义中,我们添加了一个Dropout层和一个批归一化层。在训练过程中,我们使用了随机梯度下降优化器和均方误差损失函数对模型进行训练。在测试过程中,我们使用了带有梯度的测试数据来评估模型的性能。

通过使用Dropout和批归一化,我们可以有效地避免过拟合和梯度消失问题,提高模型的性能和泛化能力。在实际应用中,可以根据具体情况调整Dropout和批归一化的参数以获得更好的效果。

接下来,我正式看一下TF与Keras的例子

我们继续开发前面文章的红酒模型。现在我们将进一步增加容量,但添加丢弃以控制过拟合,并添加批归一化来加速优化。这次,我们还将不标准化数据,以展示批归一化如何稳定训练。

# Setup plotting
import matplotlib.pyplot as pltplt.style.use('seaborn-whitegrid')
# Set Matplotlib defaults
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)import pandas as pd
red_wine = pd.read_csv('../input/dl-course-data/red-wine.csv')# Create training and validation splits
df_train = red_wine.sample(frac=0.7, random_state=0)
df_valid = red_wine.drop(df_train.index)# Split features and target
X_train = df_train.drop('quality', axis=1)
X_valid = df_valid.drop('quality', axis=1)
y_train = df_train['quality']
y_valid = df_valid['quality']

当添加dropout时,可能需要增加密集层中的神经元数量。

from tensorflow import keras
from tensorflow.keras import layersmodel = keras.Sequential([layers.Dense(1024, activation='relu', input_shape=[11]),layers.Dropout(0.3),layers.BatchNormalization(),layers.Dense(1024, activation='relu'),layers.Dropout(0.3),layers.BatchNormalization(),layers.Dense(1024, activation='relu'),layers.Dropout(0.3),layers.BatchNormalization(),layers.Dense(1),
])

这次我们在训练设置上没有任何改变。

model.compile(optimizer='adam',loss='mae',
)history = model.fit(X_train, y_train,validation_data=(X_valid, y_valid),batch_size=256,epochs=100,verbose=0,
)# Show the learning curves
history_df = pd.DataFrame(history.history)
history_df.loc[:, ['loss', 'val_loss']].plot();

如果在训练之前对数据进行标准化,通常可以获得更好的性能。然而,我们能够使用原始数据,显示了批量归一化在更困难的数据集上的有效性。

练习:Dropout与批量归一化

介绍

在这个练习中,你将给咱们前面文章练习中的Spotify模型添加dropout,并看看批量归一化如何使你能够成功地训练困难的数据集上的模型。

前面文章:
政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(四)—— 过拟合和欠拟合icon-default.png?t=N7T8https://blog.csdn.net/snowdenkeke/article/details/136919080小伙们拉到最后来看示例代码。

现在,我们继续:
 

# Setup plotting
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
# Set Matplotlib defaults
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)
plt.rc('animation', html='html5')# Setup feedback system
from learntools.core import binder
binder.bind(globals())
from learntools.deep_learning_intro.ex5 import *

首先加载Spotify数据集。

import pandas as pd
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import make_column_transformer
from sklearn.model_selection import GroupShuffleSplitfrom tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras import callbacksspotify = pd.read_csv('../input/dl-course-data/spotify.csv')X = spotify.copy().dropna()
y = X.pop('track_popularity')
artists = X['track_artist']features_num = ['danceability', 'energy', 'key', 'loudness', 'mode','speechiness', 'acousticness', 'instrumentalness','liveness', 'valence', 'tempo', 'duration_ms']
features_cat = ['playlist_genre']preprocessor = make_column_transformer((StandardScaler(), features_num),(OneHotEncoder(), features_cat),
)def group_split(X, y, group, train_size=0.75):splitter = GroupShuffleSplit(train_size=train_size)train, test = next(splitter.split(X, y, groups=group))return (X.iloc[train], X.iloc[test], y.iloc[train], y.iloc[test])X_train, X_valid, y_train, y_valid = group_split(X, y, artists)X_train = preprocessor.fit_transform(X_train)
X_valid = preprocessor.transform(X_valid)
y_train = y_train / 100
y_valid = y_valid / 100input_shape = [X_train.shape[1]]
print("Input shape: {}".format(input_shape))

1. 为Spotify Model增加Dropout

这是上篇文章练习中的最后一个模型。在具有128个单元的Dense层之后添加一个dropout层,并在具有64个单元的Dense层之后再添加一个dropout层。将两个dropout层的丢弃率都设为0.3。

# YOUR CODE HERE: Add two 30% dropout layers, one after 128 and one after 64
model = keras.Sequential([layers.Dense(128, activation='relu', input_shape=input_shape),layers.Dense(64, activation='relu'),layers.Dense(1)
])# Check your answer
q_1.check()
# Lines below will give you a hint or solution code
#q_1.hint()
#q_1.solution()

现在您可以运行下一个代码来训练模型并观察添加dropout的效果。

model.compile(optimizer='adam',loss='mae',
)
history = model.fit(X_train, y_train,validation_data=(X_valid, y_valid),batch_size=512,epochs=50,verbose=0,
)
history_df = pd.DataFrame(history.history)
history_df.loc[:, ['loss', 'val_loss']].plot()
print("Minimum Validation Loss: {:0.4f}".format(history_df['val_loss'].min()))

2.评估Dropout

再次回顾一下上篇文章的练习,这个模型在第5个epoch附近容易过拟合数据。这次添加dropout似乎有助于防止过拟合吗?

# View the solution (Run this cell to receive credit!)
q_2.check()

现在,我们将切换话题,探讨批标准化如何解决训练中的问题。

加载混凝土数据集。这次我们不进行任何标准化处理。这将使批标准化的效果更加明显。

import pandas as pdconcrete = pd.read_csv('../input/dl-course-data/concrete.csv')
df = concrete.copy()df_train = df.sample(frac=0.7, random_state=0)
df_valid = df.drop(df_train.index)X_train = df_train.drop('CompressiveStrength', axis=1)
X_valid = df_valid.drop('CompressiveStrength', axis=1)
y_train = df_train['CompressiveStrength']
y_valid = df_valid['CompressiveStrength']input_shape = [X_train.shape[1]]

运行以下代码来对非标准化的混凝土数据进行网络训练。

model = keras.Sequential([layers.Dense(512, activation='relu', input_shape=input_shape),layers.Dense(512, activation='relu'),    layers.Dense(512, activation='relu'),layers.Dense(1),
])
model.compile(optimizer='sgd', # SGD is more sensitive to differences of scaleloss='mae',metrics=['mae'],
)
history = model.fit(X_train, y_train,validation_data=(X_valid, y_valid),batch_size=64,epochs=100,verbose=0,
)history_df = pd.DataFrame(history.history)
history_df.loc[0:, ['loss', 'val_loss']].plot()
print(("Minimum Validation Loss: {:0.4f}").format(history_df['val_loss'].min()))

你最后得到了一张空白图吗?试图在这个数据集上训练这个网络通常会失败。即使它收敛了(因为有了幸运的权重初始化),它也倾向于收敛到一个非常大的数值。

3. 添加批归一化层

批量归一化可以帮助纠正这类问题。

在每个全连接层之前添加四个批量归一化层。(记得将input_shape参数移到新的第一层。)

# YOUR CODE HERE: Add a BatchNormalization layer before each Dense layer
model = keras.Sequential([layers.Dense(512, activation='relu', input_shape=input_shape),layers.Dense(512, activation='relu'),layers.Dense(512, activation='relu'),layers.Dense(1),
])# Check your answer
q_3.check()
# Lines below will give you a hint or solution code
#q_3.hint()
#q_3.solution()

运行一下代码,看看批量归一化是否能让我们训练模型。

model.compile(optimizer='sgd',loss='mae',metrics=['mae'],
)
EPOCHS = 100
history = model.fit(X_train, y_train,validation_data=(X_valid, y_valid),batch_size=64,epochs=EPOCHS,verbose=0,
)history_df = pd.DataFrame(history.history)
history_df.loc[0:, ['loss', 'val_loss']].plot()
print(("Minimum Validation Loss: {:0.4f}").format(history_df['val_loss'].min()))

4. 评估批量归一化

您可以通过反复对比,观察批量归一化对您的模型改善是否有用。

# View the solution (Run this cell to receive credit!)
q_4.check()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/283026.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用人工智能和ChatGPT来优化营销转化率

人工智能 (AI) 和营销的交集正在彻底改变企业与客户互动的方式,最终改变营销转化率。人工智能能够分析大量数据、理解模式和自动执行任务,它不仅是一项创新技术,而且是营销领域的根本性转变。这种转变允许更加个性化、…

OCR研究背景及相关论文分享

光学字符识别(Optical Character Recognition,OCR)是指使用光学方法将图像中的文字转换为机器可编辑的文本的技术。OCR技术的研究和应用已有数十年的历史,其背景和发展受到多方面因素的影响。 技术需求背景 1.自动化文档处理&am…

SQLiteC/C++接口详细介绍sqlite3_stmt类(十)

返回:SQLite—系列文章目录 上一篇:SQLiteC/C接口详细介绍sqlite3_stmt类(九) 下一篇: SQLiteC/C接口详细介绍sqlite3_stmt类(十一) 38、sqlite3_column_value sqlite3_column_valu…

2023年蓝桥杯省赛——分糖果

目录 题目链接:12.分糖果 - 蓝桥云课 (lanqiao.cn) 思路 DFS解法 实现思路 代码实现 Java C 总结 题目链接:12.分糖果 - 蓝桥云课 (lanqiao.cn) 思路 第一眼是茫然的,第二眼是想枚举的,第三眼是发现要DFS 的,第…

python的stone音乐播放器的设计与实现flask-django-php-nodejs

该系统利用python语言、MySQL数据库,flask框架,结合目前流行的 B/S架构,将stone音乐播放器的各个方面都集中到数据库中,以便于用户的需要。该系统在确保系统稳定的前提下,能够实现多功能模块的设计和应用。该系统由管理…

ChatGPT无法登录,提示我们检测到可疑的登录行为?如何解决?

OnlyFans 订阅教程移步:【保姆级】2024年最新Onlyfans订阅教程 Midjourney 订阅教程移步: 【一看就会】五分钟完成MidJourney订阅 GPT-4.0 升级教程移步:五分钟开通GPT4.0 如果你需要使用Wildcard开通GPT4、Midjourney或是Onlyfans的话&am…

深度学习基础之《TensorFlow框架(10)—案例:实现线性回归(2)》

增加其他功能 一、增加变量显示 1、目的:在TensorBoard当中观察模型的参数、损失值等变量值的变化 2、收集变量 不同的变量要用不同的方式收集 (1)tf.summary.scalar(name, tensor) 收集对于损失函数和准确率等单值变量,name为…

macOS下Java应用的打包和安装程序制作

文章目录 macOS应用程序结构Java应用打包JavaAppLauncherjpackage其它相关JDK命令附录JavaAppLauncher源码链接macOS应用程序结构 macOS通常以dmg或pkg作为软件发行包,安装到/Applications下后,结构比较统一。 info.plist里的CFBundleExecutable字段可以指定入口,如果不指定…

Karmada 管理有状态应用 Xline 的早期探索与实践

背景与动机 目前随着云原生技术和云市场的不断成熟,越来越多的 IT 厂商开始投入到跨云多集群的怀抱当中。以下是 flexera 在 2023 年中关于云原生市场对多云多集群管理的接受程度的调查报告(http://info.flexera.com) 从 flexera 的报告中可…

Flutter Widget:StatefulWidgetStatelessWidgetState

Widget 概念 Widget 将是构建Flutter应用的基石,在Flutter开发中几乎所有的对象都是一个 Widget 。 在Flutter中的widget 不仅表示UI元素,也表示一些功能性的组件,如:手势 、主题Theme 等。而原生开发中的控件通常只是指UI元素。…

Microsoft Edge 中的 Internet Explorer 模式解决ie禁止跳转到edge问题

作为网工,网络中存在很老的设备只能用ie浏览器访问打开,但是win10后打开Internet Explorer 会强制跳转到Edge 浏览器,且有人反馈不会关,为此找到了微软官方的Microsoft Edge 中的 Internet Explorer 模式,可以直接在Mi…

【C语言】自定义类型:结构体

1、结构体类型的声明 struct tag { member - list; //成员 } variable-list; //变量列表 例如描述一本书&#xff1a; struct Book {char name[20];char author[20];float price;char id[13]; }; //分号不能丢 1.1 结构体变量的创建和初始化 #include <stdio.h&…

Orbit 使用指南 08 | 登记注册环境 | Isaac Sim | Omniverse

如是我闻&#xff1a; 在上一个指南中&#xff0c;我们学习了如何创建一个自定义的车杆环境。我们通过导入环境类及其配置类来手动创建了一个环境实例 # create environment configurationenv_cfg CartpoleEnvCfg()env_cfg.scene.num_envs args_cli.num_envs# setup RL envir…

Llama 2 模型

非常清楚&#xff01;&#xff01;&#xff01;Llama 2详解 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/649756898?utm_campaignshareopn&utm_mediumsocial&utm_psn1754103877518098432&utm_sourcewechat_session一些补充理解&#xff1a; 序列化&#xff…

活用 C语言之union的精妙之用

一、union的基本定义 Union的中文叫法又被称为共用体、联合或者联合体。它的定义方式与结构体相同,但意义却与结构体完全不同。下面是union的定义格式: union 共用体名 {成员列表}共用体变量名;它与结构体的定义方式相同,但区别在于共用体中的成员的起始地址都是相同的,…

备考ICA----Istio实验7---故障注入 Fault Injection 实验

备考ICA----Istio实验7—故障注入 Fault Injection 实验 Istio 的故障注入用于模拟应用程序中的故障现象&#xff0c;以测试应用程序的故障恢复能力。故障注入有两种: 1.delay延迟注入 2.abort中止注入 1. 环境准备 kubectl apply -f istio/samples/bookinfo/platform/kube/…

Flask 与小程序 的图片数据交互 过程及探讨研究学习

今天不知道怎么的&#xff0c;之前拿编程浪子地作品抄过来粘上用好好的&#xff0c;昨天开始照片突的就不显示了。 今天不妨再耐味地细细探究一下微信小程序wxml 和flask服务器端是怎么jpg图片数据交互的。 mina/pages/food/index.wxml <!--index.wxml--> <!--1px …

学习添加03(优惠卷)

1.优化卷模块的介绍 整体流程&#xff1a; 优惠卷表设计&#xff1a; 优惠卷范围表设计&#xff1a; 兑换码表设计&#xff1a;

Python核心编程 --- 高级数据类型

Python核心编程 — 高级数据类型 字符串 列表 元组 字典 1.序列 序列&#xff1a;一组按顺序排列的数据集合。 在Python中存在三种内置的序列类型&#xff1a;字符串、列表、元组 优点&#xff1a;可支持索引和切片操作 特点&#xff1a;第一个正索引为0&#xff0c;指…

【vue3.0】实现导出的PDF文件内容是红头文件格式

效果图: 编写文件里面的主要内容 <main><div id"report-box"><p>线索描述</p><p class"label"><span>线索发现时间:</span> <span>{{ detailInfoVal?.problem.createdDate }}</span></p><…