模型优化和调整(2)

接模型优化和调整(1)

调整反向传播

梯度消失和梯度爆炸

梯度消失和梯度爆炸都和计算出来的“delta”有关。理想的delta应该是逐渐减小的。如果delta一直太小,则会导致下降太慢,甚至对于权重没有改变,此时形成了梯度消失。如果delta一直很大,则会出现波浪式(choppy)学习过程,实际没有任何下降,此时形成了梯度爆炸。下图给出了梯度消失和梯度爆炸的示意。

解决方案有

  • 权重初始化。初始化时选择较优的权重
  • 激活函数。激活函数可以影响梯度下降,因此应该选择合适的激活函数
  • 批规范化(Batch normalization)。这个概念在GANs和Diffusion模型(2)中提到过,本文稍后会给出一些讲解

批规范化

批规范化是一项处理梯度消失和梯度爆炸的重要技术。具体如下:

  • 在每一个隐藏层之前,对输入进行规范化
  • 这里的规范化是指:对权重和偏好进行中心化和定标(Center and Scale),或者称为StandardScaler
  • 在计算平均值和标准差的时候,会考虑隐藏层输出的值,使得规范化后的输入数据具有相同的规格(scale)。即使delta更新了、激活函数改变了数据的规格,这个步骤也能保持每个隐藏层的输入数据具有相同的规格。
  • 有助于通过更少的期数获得更高的准确度。
  • 需要额外的计算,因而会增加对计算资源的使用、以及执行时间。

试验程序

试验程序仍然基于模型优化和调整(1)中的基础模型。

#Initialize the measures
accuracy_measures = {}normalization_list = ['none', 'batch']for normalization in normalization_list:#Load default configurationmodel_config = base_model_config()#Acquire and process input dataX,Y = get_data()model_config["NORMALIZATION"] = normalizationmodel_name = "Normalization-" + normalizationhistory = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Batch Normalization")

运行程序后,可以得到如下结果

可以看到,使用了批规范化后,模型的准确度提高了

优化因子(Optimizer)

优化因子是帮助快速梯度下降的关键工具。可用的优化因子有

  • SGD(Stochastic Gradient Descent)
  • RMSprop
  • Adam
  • Adagrad

本文不会对每种优化因子的数学原理展开陈述,有兴趣可以搜索相关资料

试验程序

#Initialize the measures
accuracy_measures = {}optimizer_list = ['sgd', 'rmsprop', 'adam', 'adagrad']for optimizer in optimizer_list:#Load default configurationmodel_config = base_model_config()#Acquire and process input dataX,Y = get_data()model_config["OPTIMIZER"] = optimizermodel_name = "Optimizer-" + optimizerhistory = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Optimizers")

学习率(Learning Rate)

和优化因子相关的另一个超参数是学习率。学习率是

  • 权重改变和其对应的估计误差之间的比值
  • 和优化因子一起协同工作。在误差估计之后,优化因子会根据学习率调整delta。
  • 学习率是一个一个小于1的小数。

学习率的选择

  • 较大的值
    • 学习更快,需要的期数更少
    • 增加梯度爆炸的风险
  • 较小的值
    • 学习更慢,但更稳定
    • 增加梯度消失的风险

试验程序

#Initialize the measures
accuracy_measures = {}learning_rate_list = [0.001, 0.005, 0.01, 0.1, 0.5]for learning_rate in learning_rate_list:#Load default configurationmodel_config = base_model_config()#Acquire and process input dataX,Y = get_data()model_config["LEARNING_RATE"] = learning_ratemodel_name = "Learning_Rate-" + str(learning_rate)history = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Learning Rates")

过拟合处理

过拟合就是对训练集中的数据有着非常高的拟合度,然而对于训练集之外的独立数据准确度相对较低。应对过拟合的方法有:

  • 简化模型
    • 减少层数和层中的结点数
  • 训练中使用更小的期和批大小
  • 增加训练数据的规模和多样性
  • 正则化(Regularization)
  • 丢弃(Dropout)

正则化

正则化

  • 控制模型训练中的过拟合
  • 在模型参数更新后,给模型参数提供一个调整量,防止其过拟合
  • 当过拟合增加时,提供一个惩罚(penalty),以减少模型的偏差
  • 多种可用的正则化方法
    • L1,L2,L1和L2的组合

试验程序

#Initialize the measures
accuracy_measures = {}regularizer_list = ['l1', 'l2', 'l1_l2']for regularizer in regularizer_list:#Load default configurationmodel_config = base_model_config()#Acquire and process input dataX,Y = get_data()model_config["REGULARIZER"] = regularizermodel_config["EPOCHS"] = 25model_name = "Regularizer-" + regularizerhistory = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Regularization")

丢弃(Dropout)

dropout是减少过拟合的一种非常流行的方法。dropout

  • 在前向传播过程中随机丢弃一些结点
  • 给定一个百分比数,按照这个百分比随机丢弃一些结点
  • drop的选取,应该使得训练数据集和测试数据集的准确度相似

试验程序

#Initialize the measures
accuracy_measures = {}dropout_list = [0.0, 0.1, 0.2, 0.5]for dropout in dropout_list:#Load default configurationmodel_config = base_model_config()#Acquire and process input dataX,Y = get_data()model_config["DROPOUT_RATE"] = dropoutmodel_config["EPOCHS"] = 25model_name = "dropout-" + str(dropout)history = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Dropouts")

模型优化练习

在这个练习中,需要从以下几个方面对模型进行优化

  • 模型
    • 模型的层数
    • 每一层的结点数(基于优化后的层数)
  • 反向传播
    • 优化因子
    • 学习率(基于已选定的优化因子)
  • 过拟合
    • 正则化
    • 丢弃率(基于已经选定的正则化算法)
  • 最终模型
    • 组装所有的优化参数
    • 和默认设置对比

环境准备

使用google colab的开发环境,需要作以下准备工作

  • 在google colab的drive中创建一个自己的工作路径:Colab Notebooks/DeepLearning/tuning
  • 将数据文件root_cause_analysis.csv上传到这个路径下
  • 将模型优化和调整(1)中的“程序公共函数”代码封装为一个单独的文件:CommonFunctions.ipynb,准备重用

因为使用了google drive的本地文件,所以需要先导入自己的google drive

# mount my drive in google colab
from google.colab import drive
drive.mount('/content/drive')# change to my working directory, all sources are in this folder
%cd /content/drive/My Drive/Colab Notebooks/DeepLearning/tuning

同时,由于需要重用公共函数,所以运行以下代码

%run CommonFunctions.ipynb

获取并准备数据

将这一个动作封装为一个函数get_rca_data(),以便后续使用。

程序对类别做了独热编码(one-hot-encoding)的处理,这个处理在我之前的很多博文中都有讲解。具体来说,laber_encoder.fit_transform会将字符类别转换为"1, 2, 3"这样的数字标签;然后再调用to_categorical(),将"1, 2, 3"这样的数字标签转化为只含有0和1的向量。比如2转化为[0, 1, 0],3转化为[0, 0, 1]。

import pandas as pd
import os
import tensorflow as tfdef get_rca_data():#Load the data file into a Pandas Dataframesymptom_data = pd.read_csv("root_cause_analysis.csv")#Explore the data loadedprint(symptom_data.dtypes)symptom_data.head()from sklearn import preprocessingfrom sklearn.model_selection import train_test_splitlaber_encoder = preprocessing.LabelEncoder()symptom_data['ROOT_CAUSE'] = laber_encoder.fit_transform(symptom_data['ROOT_CAUSE'])print(symptom_data['ROOT_CAUSE'][:5])#Convert Pandas Dataframe into a numpy vectornp_symptom = symptom_data.to_numpy().astype(float)#Extract the features (X), from 2nd column ~ 8th column (column B~H)X_data = np_symptom[:,1:8]#Extract the targets (Y), convert to one-hot-encoding the 9th column (column G)Y_data = np_symptom[:,8]Y_data = tf.keras.utils.to_categorical(Y_data, 3)return X_data, Y_data

调整网络参数

先优化层数,基本参考了模型优化和调整(1)中的程序

#Initialize the measures
accuracy_measures = {}
layer_list = []
for layer_count in range(1, 6):#32 nodes in each layerlayer_list.append(32)#Load default configurationmodel_config = base_model_config()#Acquire and process input dataX,Y = get_rca_data()#"HIDDEN_NODES" includes all nodes in layers from input layer to the last hidden layermodel_config["HIDDEN_NODES"] = layer_listmodel_name = "Layer-" + str(layer_count)history = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Layers")

结果如下:

可以看出2层具有较好的性能,因此选择层数为2

#2 layers seem to provide the highest accuracy level at lower epoch counts
LAYERS = 2

然后固定选择的层数,优化结点数

 参考模型优化和调整(1)中的程序

#Initialize the measures
accuracy_measures = {}for node_count in range(8, 40, 8):#have a fixed number of 2 hidden layerslayer_list = []for layer_count in range(LAYERS):layer_list.append(node_count)#Load default configurationmodel_config = base_model_config()#Acquire and process input dataX,Y = get_rca_data()#"HIDDEN_NODES" includes all nodes in layers from input layer to the last hidden layermodel_config["HIDDEN_NODES"] = layer_listmodel_name = "Nodes-" + str(node_count)history = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Nodes")

可以看出,32具有较好的性能

#32 nodes seem to be best
NODES = 32

调整反向传播

调整优化因子

#Initialize the measures
accuracy_measures = {}optimizer_list = ['sgd', 'rmsprop', 'adam', 'adagrad']for optimizer in optimizer_list:#Load default configurationmodel_config = base_model_config()#apply the chosen configmodel_config["HIDDEN_NODES"] = []for i in range(LAYERS):model_config["HIDDEN_NODES"].append(NODES)#Acquire and process input dataX,Y = get_rca_data()model_config["OPTIMIZER"] = optimizermodel_name = "Optimizer-" + optimizerhistory = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Optimizers")

运行结果如下

应该选择'rmsprop'

#rmsprop seem to be best
OPTIMIZER = 'rmsprop'

调整学习率

#Initialize the measures
accuracy_measures = {}learning_rate_list = [0.001, 0.005, 0.01, 0.1, 0.5]for learning_rate in learning_rate_list:#Load default configurationmodel_config = base_model_config()#apply the chosen configmodel_config["HIDDEN_NODES"] = []for i in range(LAYERS):model_config["HIDDEN_NODES"].append(NODES)model_config["OPTIMIZER"] = OPTIMIZER#Acquire and process input dataX,Y = get_rca_data()model_config["LEARNING_RATE"] = learning_ratemodel_name = "Learning_Rate-" + str(learning_rate)history = create_and_run_model(model_config, X, Y, model_name)accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Learning Rates")

运行结果如下:

这个多次运行后结果不太稳定,原因是数据量太小。最终选择了0.001

#All seems to be OK, choose 0.001
LEARNING_RATE = 0.001

避免过拟合

调整正则化

#Initialize the measures
accuracy_measures = {}regularizer_list = [None, 'l1', 'l2', 'l1_l2']for regularizer in regularizer_list:#Load default configurationmodel_config = base_model_config()#apply the chosen configmodel_config["HIDDEN_NODES"] = []for i in range(LAYERS):model_config["HIDDEN_NODES"].append(NODES)model_config["OPTIMIZER"] = OPTIMIZERmodel_config["LEARNING_RATE"] = LEARNING_RATE#Acquire and process input dataX,Y = get_rca_data()model_config["REGULARIZER"] = regularizermodel_config["EPOCHS"] = 25model_name = "Regularizer-" + str(regularizer)history = create_and_run_model(model_config, X, Y, model_name)# as considering overfitting, we choose valication accuracy as metricaccuracy_measures[model_name] = history.history["val_accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Regularization")

结果如下:

None和'l2'具有接近的性能,多次运行后,最终选择了None

# None & l2 has simliar performance, after run with serveral times, choose None
REGULARIZER = None

调整丢弃率

#Initialize the measures
accuracy_measures = {}dropout_list = [0.0, 0.1, 0.2, 0.5]for dropout in dropout_list:#Load default configurationmodel_config = base_model_config()#apply the chosen configmodel_config["HIDDEN_NODES"] = []for i in range(LAYERS):model_config["HIDDEN_NODES"].append(NODES)model_config["OPTIMIZER"] = OPTIMIZERmodel_config["LEARNING_RATE"] = LEARNING_RATEmodel_config["REGULARIZER"] = REGULARIZER#Acquire and process input dataX,Y = get_rca_data()model_config["DROPOUT_RATE"] = dropoutmodel_name = "dropout-" + str(dropout)history = create_and_run_model(model_config, X, Y, model_name)# as considering overfitting, we choose valication accuracy as metricaccuracy_measures[model_name] = history.history["val_accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Dropouts")

这个运行结果也不太稳定,多次运行后,选择了0.1

# 0.1 is the best
DROPOUT = 0.1

构建最终的模型

通过使用默认配置和优化后的配置,对比二者的效果

#Initialize the measures
accuracy_measures = {}#Base model with default configurations
model_config = base_model_config()
model_config["HIDDEN_NODES"] = [16]
model_config["NORMALIZATION"] = None
model_config["OPTIMIZER"] = 'rmsprop'
model_config["LEARNING_RATE"] = 0.001
model_config["REGULARIZER"] = None
model_config["DROPOUT_RATE"] = 0.0#Acquire and process input data
X,Y = get_rca_data()model_name = "Base-Model"
history = create_and_run_model(model_config, X, Y, model_name)
accuracy_measures[model_name] = history.history["accuracy"]#Optimized model
#apply the chosen config
model_config["HIDDEN_NODES"] = []
for i in range(LAYERS):model_config["HIDDEN_NODES"].append(NODES)
model_config["NORMALIZATION"] = 'batch'
model_config["OPTIMIZER"] = OPTIMIZER
model_config["LEARNING_RATE"] = LEARNING_RATE
model_config["REGULARIZER"] = REGULARIZER
model_config["DROPOUT_RATE"] = DROPOUT#Acquire and process input data
X,Y = get_rca_data()model_name = "Optimized-Model"
history = create_and_run_model(model_config, X, Y, model_name)
accuracy_measures[model_name] = history.history["accuracy"]#Plot
plot_graph(accuracy_measures, "Compare Base and Optimized Model")

这个运行结果也不是很稳定,多次运行后,总体来说,优化后模型的性能是更好的。

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

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

相关文章

深入C语言内存:数据在内存中的存储

一、数据类型 1. unsigned:无符号数类型 当一个数是无符号类型时,那么其最高位的1或0,和其它位一样,用来表示该数的大小。 2.signed:有符号数类型 当一个数是有符号类型时,最高数称为“符号位”。符号位为1…

绝地求生:第29赛季第1轮更新公告

正式服维护日期 ※ 下列时间可能会视维护情况而变化。 北京时间4月9日上午8:00 – 下午4:30 地图轮换 ※ 地图轮换将于北京时间每周三上午10点进行。 日期 正式服 – 普通比赛 可自主选择地图的地区 - 亚洲、东南亚 可自主选择地图的地区 – 韩国/日本、KAKAO 随机选择地…

【随笔】Git 基础篇 -- 分支与合并 git merge(九)

💌 所属专栏:【Git】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! 💖 欢迎大…

重生奇迹MU玛雅宝石功能

玛雅宝石是重生奇迹mu游戏中的重要合成材料,玩家可以使用玛雅宝石合成属性果实、副本门票等道具。不过玛雅宝石的获取不易,所以使用起来一个都不能浪费。今天就给大家分享一些玛雅宝石使用效益最大化的经验。 获取与使用 在游戏中,玛雅宝石…

有人吐槽:低代码平台自带可视化报表,你定制化设计有啥市场?

类似这种评论,我见过的太多了。photoshop触手可及,设计高手又有几人呢? 工具毕竟就是工具,能不能用好,完全在于个体。 实不相瞒,我们接过N多可视化报表的美化业务,这就好比天猫有默认的店铺模…

JAVA面试八股文之Redis相关

Redis相关 Redis6.0为什么要用多线程?在Redis中存一个list集合怎么实现排序?Redis的5大基本类型的底层原理?缓存穿透?缓存击穿?缓存雪崩?redis做为缓存怎么保持和mysql数据进行同步?&#xff08…

Spring声明式事务(Spring学习笔记十三)

不推荐使用编程式事务 在Spring-dao.xml中配置声明式事务 <!--配置声明式事务 --><!--获得transactionManager然后把他丢给他的构造器 constructor-arg --><bean id"transactionManager" class"org.springframework.jdbc.datasource.Data…

ENSP 防火墙配置IPSecVPN点到多点

建议关闭物理机系统防火墙 应用场景 总部与分支机构通信&#xff1a;企业总部可以与遍布不同地理位置的分支机构建立安全的通信通道。远程用户访问&#xff1a;远程用户可以通过IPSec VPN隧道安全地访问公司内部网络资源&#xff0c;就像他们直接连接到公司网络一样。数据共享和…

【MySQL学习】MySQL的慢查询日志和错误日志

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

鸿蒙OS开发实战:【自动化测试框架】使用指南

概述 为支撑HarmonyOS操作系统的自动化测试活动开展&#xff0c;我们提供了支持JS/TS语言的单元及UI测试框架&#xff0c;支持开发者针对应用接口进行单元测试&#xff0c;并且可基于UI操作进行UI自动化脚本的编写。 本指南重点介绍自动化测试框架的主要功能&#xff0c;同时…

【Spring Security】2.实现最简单的身份验证

文章目录 一、找到官网的身份认证&#xff08;authentication&#xff09;示例代码二、实现最简单的身份验证1、创建Spring Boot项目2、创建IndexController3、创建index.html4、启动项目测试Controller 三、{/logout}的作用四、页面样式无法加载的问题 一、找到官网的身份认证…

二建考试搜题软件哪个好?分享8个可以搜答案的软件 #知识分享#笔记#学习方法

积极参加社团活动和实践项目&#xff0c;可以帮助大学生拓宽人脉圈和锻炼实际操作能力。 1.白鸽搜题 这是个微信公众号 多语言查询支持&#xff0c;满足国际用户需求。全球通用&#xff0c;无障碍搜题。 下方附上一些测试的试题及答案 1、等渗性脱水时&#xff0c;体液变化…

禅道任务如何删除

背景 利用禅道任务&#xff0c;来统计项目投入工时&#xff0c;但由于录入错误&#xff0c;导致工时写错&#xff0c;想修改但工时只会增加。 问题复现 先复现一下问题&#xff1a; 举例&#xff1a;2/6号工时之前由于操作失误&#xff0c;写成8小时&#xff0c;且任务状态为…

React - 你知道useffect函数内如何模拟生命周期吗

难度级别:中级及以上 提问概率:65% 很多前端开发人员习惯了Vue或者React的组件式开发,熟知组件的周期过程包含初始化、挂载完成、修改和卸载等阶段。但是当使用Hooks做业务开发的时候,看见一个个useEffect函数,却显得有些迷茫,因为在us…

DFS:深搜+回溯+剪枝解决排列、子集问题

创作不易&#xff0c;感谢三连支持&#xff01;&#xff01; 一、全排列I . - 力扣&#xff08;LeetCode&#xff09; class Solution { public://全局变量vector<vector<int>> ret;vector<int> path;bool check[6];vector<vector<int>> perm…

Hololens2远程音视频通话与AR远程空间标注,基于OpenXR+MRTK3+WebRTC实现

Hololens2远程音视频通话与AR远程空间标注 使用Unity2021.3.21版本开发&#xff0c;基于OpenXRMRTK3.0WebRTC实现。 &#xff08;1&#xff09;通过视频获取视频帧的矩阵的方法可以参考&#xff1a;https://learn.microsoft.com/zh-cn/windows/mixed-reality/develop/advanced…

(学习日记)2024.04.09:UCOSIII第三十七节:事件函数接口

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

七燕论文可靠吗 #经验分享#经验分享

七燕论文是一个非常好用的论文写作工具&#xff0c;它不仅可以帮助学生提高写作效率&#xff0c;还能帮助他们避免抄袭和提高论文质量。七燕论文的查重降重功能非常靠谱&#xff0c;能够帮助用户检测论文中的重复内容&#xff0c;并提供相应的修改建议&#xff0c;确保论文的原…

设计模式 -- 发布订阅模式

发布订阅模式&#xff1a; 订阅者把自己想订阅的事件注册到调度中心&#xff0c;当发布者发布该事件到调度中心&#xff0c;也就是该事件触发时&#xff0c;由调度者统一调度订阅者注册到调度中心的处理代码。 在javaScript 中我们一般使用事件模型来代替传统的发布订阅模式。 …

CSS设置网页颜色

目录 前言&#xff1a; 1.颜色名字&#xff1a; 2.十六进制码&#xff1a; 3.RGB&#xff1a; 4.RGBA&#xff1a; 5.HSL&#xff1a; 1.hue&#xff1a; 2.saturation&#xff1a; 3.lightness&#xff1a; 6.HSLA&#xff1a; 前言&#xff1a; 我们在电脑显示器&…