模型优化和调整(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 configuration
  model_config = base_model_config()
  #Acquire and process input data
  X,Y = get_data()

  model_config["NORMALIZATION"] = normalization

  model_name = "Normalization-" + normalization
  history = 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 configuration
  model_config = base_model_config()
  #Acquire and process input data
  X,Y = get_data()

  model_config["OPTIMIZER"] = optimizer
  model_name = "Optimizer-" + optimizer
  history = 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 configuration
  model_config = base_model_config()
  #Acquire and process input data
  X,Y = get_data()

  model_config["LEARNING_RATE"] = learning_rate
  model_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 configuration
  model_config = base_model_config()
  #Acquire and process input data
  X,Y = get_data()

  model_config["REGULARIZER"] = regularizer
  model_config["EPOCHS"] = 25
  model_name = "Regularizer-" + regularizer
  history = 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 configuration
  model_config = base_model_config()
  #Acquire and process input data
  X,Y = get_data()

  model_config["DROPOUT_RATE"] = dropout
  model_config["EPOCHS"] = 25
  model_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 tf

def get_rca_data():
  #Load the data file into a Pandas Dataframe
  symptom_data = pd.read_csv("root_cause_analysis.csv")

  #Explore the data loaded
  print(symptom_data.dtypes)
  symptom_data.head()

  from sklearn import preprocessing
  from sklearn.model_selection import train_test_split

  laber_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 vector
  np_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 layer
  layer_list.append(32)

  #Load default configuration
  model_config = base_model_config()
  #Acquire and process input data
  X,Y = get_rca_data()

  #"HIDDEN_NODES" includes all nodes in layers from input layer to the last hidden layer
  model_config["HIDDEN_NODES"] = layer_list

  model_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 layers
  layer_list = []
  for layer_count in range(LAYERS):
    layer_list.append(node_count)

  #Load default configuration
  model_config = base_model_config()
  #Acquire and process input data
  X,Y = get_rca_data()

  #"HIDDEN_NODES" includes all nodes in layers from input layer to the last hidden layer
  model_config["HIDDEN_NODES"] = layer_list

  model_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 configuration
  model_config = base_model_config()
  
  #apply the chosen config
  model_config["HIDDEN_NODES"] = []
  for i in range(LAYERS):
    model_config["HIDDEN_NODES"].append(NODES)

  #Acquire and process input data
  X,Y = get_rca_data()



  model_config["OPTIMIZER"] = optimizer
  model_name = "Optimizer-" + optimizer
  history = 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 configuration
  model_config = base_model_config()

  #apply the chosen config
  model_config["HIDDEN_NODES"] = []
  for i in range(LAYERS):
    model_config["HIDDEN_NODES"].append(NODES)
  model_config["OPTIMIZER"] = OPTIMIZER

  #Acquire and process input data
  X,Y = get_rca_data()

  model_config["LEARNING_RATE"] = learning_rate
  model_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 configuration
  model_config = base_model_config()

  #apply the chosen config
  model_config["HIDDEN_NODES"] = []
  for i in range(LAYERS):
    model_config["HIDDEN_NODES"].append(NODES)
  model_config["OPTIMIZER"] = OPTIMIZER
  model_config["LEARNING_RATE"] = LEARNING_RATE

  #Acquire and process input data
  X,Y = get_rca_data()

  model_config["REGULARIZER"] = regularizer
  model_config["EPOCHS"] = 25
  model_name = "Regularizer-" + str(regularizer)
  history = create_and_run_model(model_config, X, Y, model_name)

  # as considering overfitting, we choose valication accuracy as metric
  accuracy_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 configuration
  model_config = base_model_config()

  #apply the chosen config
  model_config["HIDDEN_NODES"] = []
  for i in range(LAYERS):
    model_config["HIDDEN_NODES"].append(NODES)
  model_config["OPTIMIZER"] = OPTIMIZER
  model_config["LEARNING_RATE"] = LEARNING_RATE
  model_config["REGULARIZER"] = REGULARIZER

  #Acquire and process input data
  X,Y = get_rca_data()

  model_config["DROPOUT_RATE"] = dropout
  model_name = "dropout-" + str(dropout)
  history = create_and_run_model(model_config, X, Y, model_name)

  # as considering overfitting, we choose valication accuracy as metric
  accuracy_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")

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

远程桌面无法连接怎么办?

远程桌面无法连接是指在尝试使用远程桌面功能时出现连接失败的情况。这种问题可能会给工作和生活带来极大的不便,因此我们需要寻找解决办法。在讨论解决方案之前,我们先来了解一下【天联】组网的优势。 【天联】组网的优势有很多。它能够解决复杂网络环境…

我自己开发的App上架了

我自己开发的App上架了 1、梦想实现 前几天,我在华为应用市场上架了我自己开发的App,心情十分激动。自从毕业后进入职场,在Android岗位上干了5年,一直想要开发一款App,为什么会有这种想法?一是能够按照自…

尝试在手机上运行google 最新开源的gpt模型 gemma

Gemma介绍 Gemma简介 Gemma是谷歌于2024年2月21日发布的一系列轻量级、最先进的开放语言模型,使用了与创建Gemini模型相同的研究和技术。由Google DeepMind和Google其他团队共同开发。 Gemma提供两种尺寸的模型权重:2B和7B。每种尺寸都带有经过预训练&a…

大话设计模式——18.策略模式(Strategy Pattern)

简介 是一系列算法的封装,即做的事情相同(方法名称相同)但是实现的方式不同,以相同方式调用所有的算法,减少算法与使用算法的耦合。直接调用方法。 UML图 应用场景 Java AWT中的LayoutManager(布局管理器&…

蓝桥杯简单模板

目录 最大公约数 两个数的最大公约数 多个数的最大公约数 最小公倍数 两个数的最小公倍数 多个数的最小公倍数 素数 ​编辑 位数分离 正写 ​编辑 反写 闰年 最大公约数 两个数的最大公约数 之前看见的是辗转相除法,例如现在让算一个49,21…

Three.js--》实现2D转3D的元素周期表

今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。 目录 项目搭建 平铺元素周期表 螺旋元素周期表 网格元素周期表 球状元素周期表 加底部交互按钮 项目…

OpenHarmony实战:瑞芯微RK3568移植案例

本文章是基于瑞芯微RK3568芯片的DAYU200开发板,进行标准系统相关功能的移植,主要包括产品配置添加,内核启动、升级,音频ADM化,Camera,TP,LCD,WIFI,BT,vibrato…

每日一题(力扣)---插入区间

官方网址:. - 力扣(LeetCode) 题目: 给你一个 无重叠的 ,按照区间起始端点排序的区间列表 intervals,其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals按照 st…

【鸿蒙开发】@State装饰器:组件内状态

1. 概述 State装饰的变量,与声明式范式中的其他被装饰变量一样,是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化。 2. 装饰器使用规则说明 State变量装饰器 说明 装饰器参数 无 同步类型 不与父组件中任何…

蚁群(ACO)算法简介

蚁群(ACO)算法简介 前言一、 ACO简介1. 起源2. 思想3. 基本概念3.1 并行3.2 禁忌表3.3 启发式信息 4. 流程 前言 生活中我们总能看到一群蚂蚁按照一条非常有规律的路线搬运食物回到巢穴,而且每只蚂蚁的路线都是近似相同且较优的,…

7-11 分段计算居民水费

题目链接&#xff1a;7-11 分段计算居民水费 一. 题目 1. 题目 2. 输入输出格式 3. 输入输出样例 4. 限制 二、代码 1. 代码实现 #include <stdio.h>static float money (unsigned int water) {if (water < 15) { // 不超过15吨时if (water) { // 不为0return wat…

教师必备工具?了解一下国产电路仿真软件的教学应用吧!

在当今信息化时代&#xff0c;科技的不断发展为教学提供了更多可能性。特别是在电子工程领域&#xff0c;教师们需要寻找更有效的方式来教授复杂的电路知识。在这个背景下&#xff0c;国产电路仿真软件的教学应用成为了备受关注的话题。本文将探讨教师使用电路仿真软件的必要性…

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

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

SpringCloudAlibaba基础使用(2024最全、最新)

一、简介二、服务注册配置Nacos2.1 下载启动2.2 服务注册2.3 服务配置2.3.1 NameSpace-GroupID-DataId 三、熔断限流 Sentinel3.1 介绍3.2 下载安装3.3 如何使用3.3.1 流控规则流控模式流控效果 3.3.2 熔断规则慢调用比例异常比例异常数 3.3.3 SentinelResource3.3.4 热点规则3…

铁山靠之数学建模-基础篇

小黑子的数模基础篇 一、什么是数学建模1.1 数学模型分类1.2 备战准备什么1.3 组队学习路线1.4 赛前准备1.5 赛题选择1.5.1 赛题类型1.5.2 ABC赛题建议 1.6 学会查询1.6.1 百度搜索技巧1.6.2 查文献1.6.3 数据预处理 1.7 建模全过程 二、数模论文2.1 论文排版2.2 标题怎么写2.3…

UE4 避免布料模拟重置后抖动

问题&#xff1a;每次设置带布料模拟的布料新位置&#xff0c;就会发生突然的抖动 解决办法&#xff1a;给“布料混合权重”或“布料最大距离缩放”K帧&#xff0c;参考数值为0.2—1&#xff08;红框内的值都试过无法解决&#xff09;

Swift 异步序列 AsyncStream 新“玩法”以及内存泄漏、死循环那些事儿(上)

概览 异步序列&#xff08;Async Sequence&#xff09;是 Swift 5.5 新并发模型中的一员“悍将”&#xff0c;系统标准库中很多类都做了重构以支持异步序列。我们还可以用 AsyncStream 辅助结构非常方便的创建自己的异步序列。 这里我们就来一起聊聊 AsyncStream 结构&#xf…

领鸡蛋游戏养鸡游戏淘宝客源码广告联盟

用户中心 用户信息&#xff1a;显示用户名、头像、鸡蛋数量、足迹等基本信息。我的足迹&#xff1a;展示用户的饲料获取记录明细&#xff0c;包括来源、数量和时间。我的好友&#xff1a;展示邀请的好友列表&#xff0c;支持好友间互动&#xff0c;如串门、偷取/赠送饲料&#…

贪心算法|135.分发糖果

力扣题目链接 class Solution { public:int candy(vector<int>& ratings) {vector<int> candyVec(ratings.size(), 1);// 从前向后for (int i 1; i < ratings.size(); i) {if (ratings[i] > ratings[i - 1]) candyVec[i] candyVec[i - 1] 1;}// 从后…

【科东软件】鸿道Intewell-Lin_V2.2.0 软件版本发布

鸿道操作系统 Intewell-Lin_V2.2.0 软件版本发布 Intewell-Lin_V2.2.0 版本号&#xff1a;V2.2.0 版本或修改说明 增加功能&#xff1a; 1、增加T3板级支持 支持硬件列表