实际应用效果不佳?来看看提升深度神经网络泛化能力的核心技术(附代码)

news2025/2/23 19:30:38

目录

数据增强

📌 技术介绍

📌 手动数据处理&增强

📌 基于 TensorFlow 的数据增强

Dropout 随机失活

📌 技术介绍

📌 基于TensorFlow应用Dropout

💡 L1 和 L2 正则化

📌 技术介绍

基于TensorFlow应用正则化

 Early Stopping / 早停止

技术介绍

基于TensorFlow应用Early stopping

总结


神经网络是一种由神经元、层、权重和偏差组合而成的特殊机器学习模型,随着近些年深度学习的高速发展,神经网络已被广泛用于进行预测和商业决策并大放异彩。

神经网络之所以广受追捧,是因为它们能够在学习能力和性能方面远远超过任何传统的机器学习算法。 现代包含大量层和数十亿参数的网络可以轻松学习掌握互联网海量数据下的模式和规律,并精准预测。

随着AI生态和各种神经网络工具库(Keras、Tensorflow 和 Pytorch 等)的发展,搭建神经网络拟合数据变得非常容易。但很多时候,在用于学习的训练数据上表现良好的模型,在新的数据上却效果不佳,这是模型陷入了『过拟合』的问题中了,在本篇内容中,ShowMeAI将给大家梳理帮助深度神经网络缓解过拟合提高泛化能力的方法。

数据增强

📌 技术介绍

缓解过拟合最直接的方法是增加数据量,在数据量有限的情况下可以采用数据增强技术。 数据增强是从现有训练样本中构建新样本的过程,例如在计算机视觉中,我们会为卷积神经网络扩增训练图像。

具体体现在计算机视觉中,我们可以对图像进行变换处理得到新突破,例如位置和颜色调整是常见的转换技术,常见的图像处理还包括——缩放、裁剪、翻转、填充、旋转和平移。

📌 手动数据处理&增强

我们可以基于PIL库手动对图像处理得到新图像以扩增样本量

from PIL import Image
import matplotlib.pyplot as plt
img = Image.open("/content/drive/MyDrive/cat.jpg")
flipped_img = img.transpose(Image.FLIP_LEFT_RIGHT) ### 翻转
roated_img = img.transpose(Image.ROTATE_90) ## 旋转
scaled_img = img.resize((400, 400))  ### 图像缩放
cropped_img = img.crop((100,50,400,200)) # 裁剪
# 颜色变换
width, height = img.size
pad_pixel = 20
canvas = Image.new(img.mode, (width+pad_pixel, height+pad_pixel), 'blue')
canvas.paste(img, (pad_pixel//2,pad_pixel//2))

 

颜色增强处理通过改变图像的像素值来改变图像的颜色属性。更细一点讲,可以通过改变亮度、对比度、饱和度、色调、灰度、膨胀等来处理。

from PIL import Image, ImageEnhance
import matplotlib.pyplot as plt
img = Image.open("/content/drive/MyDrive/cat.jpg")
enhancer = ImageEnhance.Brightness(img)
img2 = enhancer.enhance(1.5)  ## 更亮
img3 = enhancer.enhance(0.5)  ## 更暗 
imageenhancer = ImageEnhance.Contrast(img)
img4 = enhancer.enhance(1.5) ## 提升对比度
img5 = enhancer.enhance(0.5) ## 降低对比度
enhancer = ImageEnhance.Sharpness(img)
img6 = enhancer.enhance(5) ## 锐化

 

虽然可以通过使用像 pillow 和 OpenCV 这样的图像处理库来手动执行图像增强,但更简单且耗时更少的方法是使用 API 来完成。

Keras 是一个用 Python 编写的深度学习 API,可以运行在机器学习平台 Tensorflow 之上。 Keras 有许多可提高实验速度的内置方法和类。 在 Keras 中,我们有一个 类,它为图像增强提供了多个选项。

keras.preprocessing.image.ImageDataGenerator()

  • featurewise_center: 布尔值。将输入数据的均值设置为 0,逐特征进行。
  • samplewise_center: 布尔值。将每个样本的均值设置为 0。
  • featurewise_std_normalization: Boolean. 布尔值。将输入除以数据标准差,逐特征进行。
  • samplewise_std_normalization: 布尔值。将每个输入除以其标准差。
  • zca_epsilon: ZCA 白化的 epsilon 值,默认为 1e-6。
  • zca_whitening: 布尔值。是否应用 ZCA 白化。
  • rotation_range: 整数。随机旋转的度数范围。
  • width_shift_range: 浮点数、一维数组或整数
    • float: 如果 <1,则是除以总宽度的值,或者如果 >=1,则为像素值。
    • 1-D 数组: 数组中的随机元素。
    • int: 来自间隔 (-width_shift_range, +width_shift_range) 之间的整数个像素。
    • width_shift_range=2 时,可能值是整数 [-1, 0, +1],与 width_shift_range=[-1, 0, +1] 相同;而 width_shift_range=1.0 时,可能值是 [-1.0, +1.0) 之间的浮点数。
  • height_shift_range: 浮点数、一维数组或整数
    • float: 如果 <1,则是除以总宽度的值,或者如果 >=1,则为像素值。
    • 1-D array-like: 数组中的随机元素。
    • int: 来自间隔 (-height_shift_range, +height_shift_range) 之间的整数个像素。
    • height_shift_range=2 时,可能值是整数 [-1, 0, +1],与 height_shift_range=[-1, 0, +1] 相同;而 height_shift_range=1.0 时,可能值是 [-1.0, +1.0) 之间的浮点数。
  • shear_range: 浮点数。剪切强度(以弧度逆时针方向剪切角度)。
  • zoom_range: 浮点数 或 [lower, upper]。随机缩放范围。如果是浮点数,[lower, upper] = [1-zoom_range, 1+zoom_range]
  • channel_shift_range: 浮点数。随机通道转换的范围。
  • fill_mode: {"constant", "nearest", "reflect" or "wrap"} 之一。默认为 'nearest'。输入边界以外的点根据给定的模式填充。
  • cval: 浮点数或整数。用于边界之外的点的值,当 fill_mode = "constant" 时。
  • horizontal_flip: 布尔值。随机水平翻转。
  • vertical_flip: 布尔值。随机垂直翻转。
  • rescale: 重缩放因子。默认为 None。如果是 None 或 0,不进行缩放,否则将数据乘以所提供的值(在应用任何其他转换之前)。
  • preprocessing_function: 应用于每个输入的函数。这个函数会在任何其他改变之前运行。这个函数需要一个参数:一张图像(秩为 3 的 Numpy 张量),并且应该输出一个同尺寸的 Numpy 张量。
  • data_format: 图像数据格式,{"channels_first", "channels_last"} 之一。"channels_last" 模式表示图像输入尺寸应该为 (samples, height, width, channels),"channels_first" 模式表示输入尺寸应该为 (samples, channels, height, width)。默认为 在 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值。如果你从未设置它,那它就是 "channels_last"。
  • validation_split: 浮点数。Float. 保留用于验证的图像的比例(严格在0和1之间)。
  • dtype: 生成数组使用的数据类型。

📌 基于 TensorFlow 的数据增强

如果要基于 TensorFlow 实现数据增强,示例代码如下:

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img

datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        brightness_range= [0.5, 1.5],
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.4,
        horizontal_flip=True,
        fill_mode='nearest',
        zca_epsilon=True)

path = '/content/drive/MyDrive/cat.jpg' ## Image Path
img = load_img(f"{path}")
x = img_to_array(img)
x = x.reshape((1,) + x.shape)
i = 0

### 基于数据增强构建25张图片并存入aug_img文件夹
for batch in datagen.flow(x, batch_size=1, save_to_dir="/content/drive/MyDrive/aug_imgs", save_prefix='img', save_format='jpeg'):
    i += 1
    if i > 25:
        break 

 

Dropout 随机失活

📌 技术介绍

Dropout 层是解决深度神经网络中过度拟合的最常用方法。 它通过动态调整网络来减少过拟合的概率。

Dropout 层 随机 在训练阶段以概率rate随机将输入单元丢弃(可以认为是对输入置0),未置0的输入按 1/(1 - rate) 放大,以使所有输入的总和保持不变。

丢弃率rate 是主要参数,范围从 0 到 1。0.5 的rate取值意味着 50% 的神经元在训练阶段从网络中随机丢弃。

 

TensorFlow中的dropout使用方式如下

tf.keras.layers.Dropout(rate, noise_shape=None, seed=None)
  • rate: 在 0 和 1 之间浮动,丢弃概率。
  • noise_shape:1D 整数张量,表示将与输入相乘的二进制 dropout 掩码的形状。
  • seed: 随机种子。

📌 基于TensorFlow应用Dropout

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Reshape
from tensorflow.keras.layers import Dropout

def create_model():
  model = Sequential()
  model.add(Dense(60, input_shape=(60,), activation='relu'))
  model.add(Dropout(0.2))
  model.add(Dense(30, activation='relu'))
  model.add(Dropout(0.2))
  model.add(Dense(1, activation='sigmoid'))
  return model
  
adam = tf.keras.optimizers.Adam()
model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])

model = create_model()
model.summary()

 

在向神经网络添加 dropout 层时,有一些技巧大家可以了解一下:

  • 一般会使用 20%-50% 的小的 dropout 值,太大的 dropout 值可能会降低模型性能,同时选择非常小的值不会对网络产生太大影响。
  • 一般在大型网络中会使用dropout层以获得最大性能。
  • 输入层和隐层上都可以使用 dropout,表现都良好。

💡 L1 和 L2 正则化

📌 技术介绍

正则化是一种通过惩罚损失函数来降低网络复杂性的技术。 它为损失函数添加了一个额外的权重约束部分,它在模型过于复杂的时候会进行惩罚(高loss),简单地说,正则化限制权重幅度过大。

L1 正则化的公式如下:

 L2 正则化公式如下:

 

基于TensorFlow应用正则化

在TensorFlow搭建神经网络时,我们可以直接在添加对应的层次时,通过参数设置添加正则化项。

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Reshape
from tensorflow.keras.layers import Dropout

def create_model():
  # 构建模型
  model = Sequential()
  # 添加正则化
  model.add(Dense(60, input_shape=(60,), activation='relu',  kernel_regularizer=keras.regularizers.l1(0.01)))
  model.add(Dropout(0.2))
  # 添加正则化
  model.add(Dense(30, activation='relu',  kernel_regularizer=keras.regularizers.l2(0.001)))
  model.add(Dropout(0.2))
  model.add(Dense(1, activation='sigmoid'))
  return model


adam = tf.keras.optimizers.Adam()
model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])

model = create_model()
model.summary()

 Early Stopping / 早停止

技术介绍

在深度学习中,一个 epoch指的是完整训练数据进行一轮的训练。迭代轮次epoch的多少对于模型的状态影响很大:如果我们的 epoch 设置太大,训练时间越长,也更可能导致模型过拟合;但过少的epoch可能会导致模型欠拟合。

Early stopping早停止是一种判断迭代轮次的技术,它会观察验证集上的模型效果,一旦模型性能在验证集上停止改进,就会停止训练过程,它也经常被使用来缓解模型过拟合。

 

基于TensorFlow应用Early stopping

Keras 有一个回调函数,可以直接完成early stopping。

from tensorflow.keras.callbacks import EarlyStopping
early_stopping = EarlyStopping(
    monitor='val_loss',
    min_delta=0,
    patience=0,
    verbose=0,
    mode='auto',
    baseline=None,
    restore_best_weights=False
)
  • monitor: 被监测的数据。
  • min_delta: 在被监测的数据中被认为是提升的最小变化, 例如,小于 min_delta 的绝对变化会被认为没有提升。
  • patience: 没有进步的训练轮数,在这之后训练就会被停止。
  • verbose: 详细信息模式。
  • mode: {auto, min, max} 其中之一。 在 min 模式中, 当被监测的数据停止下降,训练就会停止;在 max 模式中,当被监测的数据停止上升,训练就会停止;在 auto 模式中,方向会自动从被监测的数据的名字中判断出来。
  • baseline: 要监控的数量的基准值。 如果模型没有显示基准的改善,训练将停止。
  • restore_best_weights: 是否从具有监测数量的最佳值的时期恢复模型权重。 如果为 False,则使用在训练的最后一步获得的模型权重。
from tensorflow.keras.callbacks import EarlyStoppingearly_stopping = EarlyStopping(monitor='loss', patience=2)history = model.fit(
    X_train,
    y_train,
    epochs= 100,
    validation_split= 0.20,
    batch_size= 50,
    verbose= "auto",
    callbacks= [early_stopping]
)

 

总结

在本篇内容中,对缓解过拟合的技术做了介绍和应用讲解,大家可以在实践中选择和使用。『数据增强』技术将通过构建和扩增样本集来缓解模型过拟合,dropout 层通过随机丢弃一些神经元来降低网络复杂性,正则化技术将惩罚网络训练得到的大幅度的权重,early stopping 会防止网络过度训练和学习。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis日志框架

文章目录一、 用日志打印代替sout1、sout有什么问题①问题1&#xff1a;I/O影响性能②问题2&#xff1a;无法统一管理③问题3&#xff1a;显得你很low2、使用日志框架的好处①设定级别&#xff0c;统一管理②灵活指定输出位置③自定义日志格式④基于日志分析问题二、最佳用法1、…

设计模式之【单例模式】全解,单例模式实现方式,暴力打破单例模式与解决方案,你真的认识单例模式吗?

文章目录什么是单例模式单例模式的应用场景处理有线程冲突的资源表示全局唯一类单例模式的实现方式1、饿汉式之静态常量2、饿汉式之静态代码块3、懒汉式之线程不安全方式&#xff08;不推荐&#xff09;4、懒汉式之加锁方式&#xff08;不推荐&#xff09;5、懒汉式之双重锁检查…

波司登的高端化后遗症

&#xff08;题图&#xff09; 文|螳螂观察 作者| 青月 受“三重”拉尼娜现象的影响&#xff0c;2022年冬天可能会因为阶段性冷空气的影响出现阶段性低温&#xff0c;且极端寒潮爆发的可能性大。 极端天气越来越多&#xff0c;年年冷冬&#xff0c;有望催化以羽绒服为代表的…

【uni-app从入门到实战】打包

小程序打包发布 1、小程序的打包发布很简单&#xff0c;只需要将程序运行到微信开发者工具中&#xff0c;然后点击右上角的上传按钮即可 我们这里的上传按钮不能点击是因为没有配置微信小程序AppID 打开项目的 manifest.json&#xff0c;选中微信小程序配置&#xff0c;填入微…

Java并发编程——线程间通信

线程间通信一、volatile 关键字二、等待/通知机制三、管道通信四、Thread.join一、volatile 关键字 为什么volatile关键字可以&#xff1f;因为之前说过了&#xff0c;此关键字能保证变量的可见性&#xff0c;也就是说变量一旦被修改&#xff0c;立马能被其他线程所感知 例子如…

拓端tecdat|R语言代做泰坦尼克号随机森林模型案例数据分析

全文链接&#xff1a;http://tecdat.cn/?p4281 原文出处&#xff1a;拓端数据部落公众号 视频&#xff1a;从决策树到随机森林&#xff1a;R语言信用卡违约分析信贷数据实例 从决策树到随机森林&#xff1a;R语言信用卡违约分析信贷数据实例&#xff0c;时长10:11 如果我们对…

Linux:环境变量

基本概念 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。 环境变量通常具有某些特殊用途&#xff0c;通常具有全局特性&#xff0c;可以被子进程继承下去 常见的环境变量 PATH : 指定命令的搜索路径 HOME : 指定用户的主工作目录(即用户登陆到Linux系统中…

[Linux]----文件操作(复习C语言+文件描述符)

文章目录前言一、基础概念二、回顾C语言2.1 对文件进行写操作2.2 追加写文件2.3 读文件2.4 简易cat功能总结stdin&stdout&stderr打开文件的方式三、系统文件I/O接口介绍open介绍使用open接口closewriteread四、文件描述符先验证0,1,2就是标准的IO标准输入流标准输出流标…

基于寄生-捕食算法的函数寻优算法

文章目录一、理论基础1、寄生-捕食算法&#xff08;1&#xff09;初始化&#xff08;2&#xff09;筑巢阶段(鸟窝)&#xff08;3&#xff09;寄生阶段(乌鸦-布谷鸟)&#xff08;4&#xff09;捕食阶段(乌鸦-猫)2、PPA算法伪代码二、仿真实验与结果分析三、参考文献一、理论基础…

QCC51XX---QACT用户指南

更新记录链接:QCC51XX---系统学习目录_嵌入式学习_force的博客-CSDN博客 QACT安装包不要放在有中文路径下,否则—直会安装报错。适用V7,V7.1 V7.2版本 打开QACT. 打开QACT. 点击 connection configuration 进去之后 点击1,然后点2,选择kalaccess.dll文件, workspace …

【C++】vector的模拟实现不会怎么办?看过来

&#x1f308;欢迎来到C专栏~~vector的模拟实现 (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort&#x1f393;&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句鸡汤&#x1f914;&…

MySQL是如何保证主从一致的

一&#xff1a;什么是binlog Binary log(二进制日志)&#xff0c;简称Binlog。 Binlog是记录所以数据表结构变更以及表数据修改的二进制日志&#xff0c;不会记录select和show这类操作。Binlog是以事件形式记录&#xff0c;还包括语句所执行的消耗时间。Binlog是MySql Server自…

0082 时间复杂度,冒泡排序

/* * 排序也称排序算法&#xff08;Sort Algorithm&#xff09; * 排序是将一组数据&#xff0c;依指定的顺序进行排列的过程。 * * 排序分类 * 1.内部排序&#xff1a;将需要处理的所有数据都加载到内存存储器中进行排序&#xff08;使用内存&#xff09; * 插…

Keil MDK的sct分散加载文件详解

sct 分散加载文件简介 MDK 生成一个以工程名命名的后缀为 *.sct 的分散加载文件 (Linker Control File&#xff0c;scatter loading)&#xff0c;链接器根据该文件的配置分配各个节区地址&#xff0c;生成分散加载代码&#xff0c;因此我们通过修改该文件可以定制具体节区的存…

Spring源码:Spring源码阅读环境搭建

本篇内容包括&#xff1a;Mac 环境下 gradle 的安装和配置、源码克隆、新建测试类&#xff0c;测试Spring源码 等内容&#xff01; 第一步&#xff1a;Mac 环境下 gradle 的安装和配置 1、下载安装包 # 到 GitHub 的 Spring 仓库选定 Spring 版本&#xff0c;查看对应版本 Sp…

Linux项目自动化构建工具make/makefile

1.背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计其数&#xff0c;其按类型&#xff0c;功能&#xff0c;模块分别放在若干目录中&#xff0c;makefile定义了一系列的规则来制定&#xff0c;那些文件需要先编译&a…

C艹笔记--面向对象程序设计

文章目录类与对象简介类与结构的区别定义成员函数继承继承小总结[C中::和:&#xff0c; .和->的作用和区别](https://zhuanlan.zhihu.com/p/165992745)符号::和&#xff1a;的作用和区别:::一般用来表示继承符号.和->的作用和区别#include#include""和#include…

STM32入门——基本 GPIO 的输出控制

文章目录1 什么是 GPIO &#xff1f;1.1 GPIO 简介1.2 GPIO 硬件解析1.2.1 保护二极管1.2.2 P-MOS、N-MOS 管1.2.3 数据输入输出寄存器1.2.4 复用功能输出1.2.5 模拟输入输出1.3 GPIO 的工作模式1.3.1 输入模式 (模拟/浮空/上拉/下拉)1.3.2 输出模式 (推挽/开漏)1.3.3 复用功能…

基于Nodejs+vue开发实现酒店管理系统

作者简介&#xff1a;Java、前端、Pythone开发多年&#xff0c;做过高程&#xff0c;项目经理&#xff0c;架构师 主要内容&#xff1a;Java项目开发、毕业设计开发、面试技术整理、最新技术分享 项目编号&#xff1a;BS-QD-KS-002 一&#xff0c;项目简介 本项目使用纯前端技…

mysql约束

文章目录mysql约束非空约束唯一性约束主键约束使用自增列&#xff1a;AUTO_INCREMENTFOREIGN KEY约束CHECK约束mysql约束 为什么需要约束&#xff1f;为了保证数据的完整性什么叫约束&#xff1f;对表中字段的限制约束的分类&#xff1a; 角度1&#xff1a;约束的字段个数&…