【TensorFlow学习笔记:神经网络优化(6讲)】

目录

  • 【1】NN复杂度
  • 【2】指数衰减学习率
  • 【3】激活函数
    • 优秀激活函数所具有的特点
    • 常见的激活函数
    • 对于初学者的建议
  • 【4】损失函数
  • 【5】缓解过拟合——正则化
  • 【6】参数优化器
    • 【1】SGD
    • 【2】SGDM(SGD基础上增加了一阶动量)
    • 【3】Adagrade(SGD基础上增加了二阶动量)
    • 【4】RMSProp(SGD基础上增加了二阶动量)
    • 【5】Adam(同时结合SGDM一阶动量和RMSProp的二节动量)
    • 优化器对比总结

【1】NN复杂度

空间复杂度:
层数:隐藏层层数+输出层
总参数:总w+总b
时间复杂度:
乘加运算次数
以下图为例:总参数=3x4+4(第一层) +4x2+2(第二层)=26
乘加运算次数=3x4+4x2=20

【2】指数衰减学习率

已知:学习率过小,收敛速度慢。学习率过大导致不收敛。
可以先用较大的学习率,快速得到较优解,然后逐步减小学习率,使模型在训练后期稳定,例如指数衰减学习率。

指数衰减学习率=初始学习率*学习率衰减率^(当前轮数/多少轮衰减一次)

epoch = 40
LR_BASE = 0.2  # 最初学习率
LR_DECAY = 0.99  # 学习率衰减率
LR_STEP = 1  # 喂入多少轮BATCH_SIZE后,更新一次学习率
for epoch in range(epoch):  # for epoch 定义顶层循环,表示对数据集循环epoch次,此例数据集数据仅有1个w,初始化时候constant赋值为5,循环100次迭代。lr = LR_BASE * LR_DECAY ** (epoch / LR_STEP)

【3】激活函数

对于线性函数,即使有多个神经元首尾相接构成深层神经网络,依旧是线性组合,模型表达力不够。

MP模型比简化模型多了一个激活函数,它的加入加强了模型的表达力,使得深层网络不再是输入x的线性组合,而且随着层数增加提升表达力。

优秀激活函数所具有的特点

非线性:激活函数非线性时,多层神经网络可以逼近所有函数
可微性:优化器大多用梯度下降更新参数
单调性:当激活函数是单调的,能保证单层网络的损失函数是凸函数
近似恒等性:f(x)约等于x,当参数初始化为随机小值时,神经网络更稳定

激活函数输出值的范围:
1、激活函数输出为有限值时,权重对于特征的影响会更显著,基于梯度的优化方法更稳定
2、激活函数输出为无限值时,参数的初始值对模型的影响特别大,要使用更小的学习率

常见的激活函数

1、sigmoid函数:
函数公式、函数图像与导数图像:

调用方法:tf.nn.sigmoid(x)
特点:
1、易造成梯度消失(输入的值较大时,梯度就约等于0了)
2、输出非0均值,收敛慢(我们希望输入每层网络的特征是以0为均值的小数)
3、幂运算复杂,训练时间长

神经网络最初兴起的时候,sigmoid函数作为激活函数用的很多,但是近年来用sigmoid函数的网络已经很少了。
因为,深层神经网络更新参数时,需要从输出层到输入层逐层进行链式求导,而sigmoid函数导数的输出范围是(0,0.25],链式求导需要多层导数连续相乘,这样最终导致输出为0,造成梯度消失,参数无法继续更新。

2、Tanh函数:
调用方法:tf.math.tanh(x)
特点:
1、易造成梯度消失
2、输出0均值
3、幂运算复杂,训练时间长
函数公式、函数图像与导数图像:

3、Relu函数:
函数公式、函数图像与导数图像:

调用方法:tf.nn.relu(x) 优点: 1、在正区间解决了梯度消失的问题 2、只需要判断输入是否大于0,计算速度快 3、收敛速度远快于sigmoid和tanh 4、具备近似恒等性 缺点: 1、输出非0均值,瘦收敛慢 2、Dead ReIU问题,某些神经元可能永远无法被激活,导致相应的参数永远无法更新

送入激活函数的输入特征是负数时,激活函数输出是0,反向传输梯度是0,经过relu函数的负数特征过多导致神经元死亡,我们可以改进随机初始化,避免过多负数特征传入,也可以通过设置更小的学习率,减少参数分布的巨大变化,避免训练中产生过多负数特征

4、Leaky Relu函数:
函数公式、函数图像与导数图像:

调用方法:tf.nn.leaky_relu(x)
理论上来说,leaky relu具有relu的所有优点,外加不会有deadrelu问题,但是在实际操作中,并没有完全证明leaky relu总好于relu

对于初学者的建议

1、首选relu激活函数
2、学习率设置较小值
3、输入特征标准化,让输入特征满足以0为均值,1为标准差的正态分布
4、初始参数中心化,让随机生成的参数满足0位均值,sqrt(2/当前层输入特征个数)为标准差的正态分布

【4】损失函数

NN优化目标:loss最小
常用三种损失函数:1、mse(均方差)2、自定义3、ce(交叉熵)
1、mse(均方差)
mse调用方式:

loss_mse =tf.reduce_mean(tf.square(y_-y))

预测酸奶代码:

import tensorflow as tf
import numpy as npSEED = 23455rdm = np.random.RandomState(seed=SEED)  # 生成[0,1)之间的随机数
x = rdm.rand(32, 2)
y_ = [[x1 + x2 + (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x]  # 生成噪声[0,1)/10=[0,0.1); [0,0.1)-0.05=[-0.05,0.05)
x = tf.cast(x, dtype=tf.float32)w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))epoch = 15000
lr = 0.002for epoch in range(epoch):with tf.GradientTape() as tape:y = tf.matmul(x, w1)loss_mse = tf.reduce_mean(tf.square(y_ - y))grads = tape.gradient(loss_mse, w1)w1.assign_sub(lr * grads)if epoch % 500 == 0:print("After %d training steps,w1 is " % (epoch))print(w1.numpy(), "\n")
print("Final w1 is: ", w1.numpy())

生成的系数确实约等于1
2、自定义损失函数
以销量预测为例:
均方误差损失函数默认认为销量预测多了、少了,造成的损失是一样的,其实不然。
预测多了:损失成本
预测少了:损失利润
若利润不等于成本,则mse产生的loss无法利益最大化!
可以把损失定义为一个分段函数
在这里插入图片描述
loss_zdy=tf,reduce_sum(tf.where(tf.greater(y,y_),COST(y-y_),PROFIT(y_-y)))
如:预测酸奶销量,酸奶成本(COST)1元,酸奶利润(PROFIT)99元。
预测少了损失利润99元,大于预测多了损失成本1元。
预测少了损失大,希望生成的预测函数往多了预测。
预测酸奶代码:(修改损失函数)

import tensorflow as tf
import numpy as npSEED = 23455
COST = 1
PROFIT = 99rdm = np.random.RandomState(SEED)
x = rdm.rand(32, 2)
y_ = [[x1 + x2 + (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x]  # 生成噪声[0,1)/10=[0,0.1); [0,0.1)-0.05=[-0.05,0.05)
x = tf.cast(x, dtype=tf.float32)w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))epoch = 10000
lr = 0.002for epoch in range(epoch):with tf.GradientTape() as tape:y = tf.matmul(x, w1)loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * COST, (y_ - y) * PROFIT))grads = tape.gradient(loss, w1)w1.assign_sub(lr * grads)if epoch % 500 == 0:print("After %d training steps,w1 is " % (epoch))print(w1.numpy(), "\n")
print("Final w1 is: ", w1.numpy())# 自定义损失函数
# 酸奶成本1元, 酸奶利润99元
# 成本很低,利润很高,人们希望多预测些,生成模型系数大于1,往多了预测

生成的系数确实都大于1
3、ce(交叉熵)
调用方式:tf.losses.categorical_crossentropy(y_, y)

import tensorflow as tfloss_ce1 = tf.losses.categorical_crossentropy([1, 0], [0.6, 0.4])
loss_ce2 = tf.losses.categorical_crossentropy([1, 0], [0.8, 0.2])
print("loss_ce1:", loss_ce1)
print("loss_ce2:", loss_ce2)# 交叉熵损失函数

一般来说,输出先通过softmax函数使之符合概率分布,再计算y与y_的交叉熵损失函数,TensorFlow提供了同时计算的函数
tf.nn.softmax_cross_entropy_with_logits(y_, y)

# softmax与交叉熵损失函数的结合
import tensorflow as tf
import numpy as npy_ = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 0], [0, 1, 0]])
y = np.array([[12, 3, 2], [3, 10, 1], [1, 2, 5], [4, 6.5, 1.2], [3, 6, 1]])
y_pro = tf.nn.softmax(y)
loss_ce1 = tf.losses.categorical_crossentropy(y_,y_pro)
loss_ce2 = tf.nn.softmax_cross_entropy_with_logits(y_, y)print('分步计算的结果:\n', loss_ce1)
print('结合计算的结果:\n', loss_ce2)

【5】缓解过拟合——正则化

为什么正则化可以化解过拟合,先看看下面两个视频和讲解吧:
过拟合
正则化如何运行
正则化不舍弃特征,而是减少了特征变量的量级,从而简化假设模型。由于变量过多,我们事先并不知晓每个变量对结果的相关程度,也就是说我们不知道该缩小哪些参数,我们选择缩小所有参数,也就是给所有参数加上惩罚项(除了theta0变量)。
在这里插入图片描述
正则化参数λ用来控制两个不同目标之间的取舍:
1、更好地拟合训练数据
2、保持参数尽量地小
λ过大同样也会造成欠拟合的现象。

欠拟合解决方法:
1、增加输入特征项
2、增加网络参数
3、减少正则化参数
过拟合的解决方法:
1、数据清洗
2、增大训练集
3、采用正则化
4、增大正则化参数

在这里插入图片描述
示例:利用神经网络区分蓝色点和红色点
在这里插入图片描述

思路:
1、先用神经网络拟合出数据x1,x2,y_c的函数关系
2、生成网格覆盖这些点
3、将网格中坐标送入训练好的神经网络
4、网络为每个坐标输出一个预测值
5、将神经网络输出为0.5的预测值的线标出颜色,这线就是区分线
分别输出不正则化和正则化的效果,观察效果

左侧是正则化之前的,右侧是正则化之后的。

1层隐藏层,4个神经元
1层隐藏层,4个神经元
1层隐藏层,22个神经元
1层隐藏层,22个神经元
1层隐藏层,40个神经元
1层隐藏层,40个神经元

很明显地可以看出,加入L2正则化后的曲线更加平缓。有效缓解了过拟合。

【6】参数优化器

推荐链接
【基础算法】神经网络参数优化器https://zhuanlan.zhihu.com/p/97873519
MOOC神经网络参数优化器
参数优化器总体公式:
在这里插入图片描述

【1】SGD

公式:在这里插入图片描述
code:

# 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_grad
w1.assign_sub(lr * grads[0])  # 参数w1自更新
b1.assign_sub(lr * grads[1])  # 参数b自更新

【2】SGDM(SGD基础上增加了一阶动量)

公式:
在这里插入图片描述
mt表示各时刻梯度方向的指数滑动平均值,表征了过去一段时间的平均值。β是接近1的超参数,一般等于0.9
code:

m_w, m_b = 0, 0
beta = 0.9# sgd-momentun  
m_w = beta * m_w + (1 - beta) * grads[0]
m_b = beta * m_b + (1 - beta) * grads[1]
w1.assign_sub(lr * m_w)
b1.assign_sub(lr * m_b)

【3】Adagrade(SGD基础上增加了二阶动量)

公式:
在这里插入图片描述
code:

v_w, v_b = 0, 0
# adagrad
v_w += tf.square(grads[0])
v_b += tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))

【4】RMSProp(SGD基础上增加了二阶动量)

公式:
在这里插入图片描述

v_w, v_b = 0, 0
beta = 0.9
# rmsprop
v_w = beta * v_w + (1 - beta) * tf.square(grads[0])
v_b = beta * v_b + (1 - beta) * tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))

【5】Adam(同时结合SGDM一阶动量和RMSProp的二节动量)

公式:
在这里插入图片描述
code:

m_w, m_b = 0, 0
v_w, v_b = 0, 0
beta1, beta2 = 0.9, 0.999
delta_w, delta_b = 0, 0
global_step = 0
# adam
m_w = beta1 * m_w + (1 - beta1) * grads[0]
m_b = beta1 * m_b + (1 - beta1) * grads[1]
v_w = beta2 * v_w + (1 - beta2) * tf.square(grads[0])
v_b = beta2 * v_b + (1 - beta2) * tf.square(grads[1])m_w_correction = m_w / (1 - tf.pow(beta1, int(global_step)))
m_b_correction = m_b / (1 - tf.pow(beta1, int(global_step)))
v_w_correction = v_w / (1 - tf.pow(beta2, int(global_step)))
v_b_correction = v_b / (1 - tf.pow(beta2, int(global_step)))w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))
b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction))

优化器对比总结

							                            优化器对比(lr=0.1    epoch=500    batch=32)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

第十章 开箱即用

第十章 开箱即用 “开箱即用”(batteries included)最初是由Frank Stajano提出的,指的是Python丰富的标准库。 模块 使用import将函数从外部模块导入到程序中。 import math math.sin(0)#结果为:0.0模块就是程序 在文件夹中创…

Openmv通过串口接收数据、发送数据与stm32通信

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。 目录 参考接线星瞳教程openmv传送数据STM32解码程序参考 接线 星瞳教程

c语言尹宝林答案,c程序设计导引 尹宝林

《C程序设计导引》特别适合作为计算机和非计算机专业学生学习高级语言程序设计的教材,也可供计算机等级考试者和其他各类学习者使用参考。17.40定价:44.75(3.89折)/2013-05-01《大学计算机优秀教材系列:C程序设计导引》是一本讲解C程序设计的…

第十一章 文件

第十一章 文件 打开文件 当前目录中有一个名为beyond.txt的文本文件,打开该文件 调用open时,原本可以不指定模式,因为其默认值就是’r’。 import io f open(beyond.txt)文件模式 值描述‘r’读取模式(默认值)‘w…

【TensorFlow学习笔记:神经网络八股】(实现MNIST数据集手写数字识别分类以及FASHION数据集衣裤识别分类)

课程来源:人工智能实践:Tensorflow笔记2 文章目录前言一、搭建网络八股sequential1.函数介绍2.6步法实现鸢尾花分类二、搭建网络八股class1.创建自己的神经网络模板:2.调用自己创建的model对象三、MNIST数据集1.用sequential搭建网络实现手写数字识别2.用…

第十二章 图形用户界面

第十二章 图形用户界面 GUI就是包含按钮、文本框等控件的窗口 Tkinter是事实上的Python标准GUI工具包 创建GUI示例应用程序 初探 导入tkinter import tkinter as tk也可导入这个模块的所有内容 from tkinter import *要创建GUI,可创建一个将充当主窗口的顶级组…

Sqlserver 2005 配置 数据库镜像:数据库镜像期间可能出现的故障:镜像超时机制

数据库镜像期间可能出现的故障 SQL Server 2005其他版本更新日期: 2006 年 7 月 17 日 物理故障、操作系统故障或 SQL Server 故障都可能导致数据库镜像会话失败。数据库镜像不会定期检查 Sqlservr.exe 所依赖的组件来验证组件是在正常运行还是已出现故障。但对于某…

【神经网络八股扩展】:自制数据集

课程来源:人工智能实践:Tensorflow笔记2 文章目录前言1、文件一览2、将load_data()函数替换掉2、调用generateds函数4、效果总结前言 本讲目标:自制数据集,解决本领域应用 将我们手中的图片和标签信息制作为可以直接导入的npy文件。 1、文件一览 首先看…

c语言输出11258循环,c/c++内存机制(一)(转)

一:C语言中的内存机制在C语言中,内存主要分为如下5个存储区:(1)栈(Stack):位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。(2)堆(Heap):由程序员用…

【神经网络八股扩展】:数据增强

课程来源:人工智能实践:Tensorflow笔记2 文章目录前言TensorFlow2数据增强函数数据增强网络八股代码:总结前言 本讲目标:数据增强,增大数据量 关于我们为何要使用数据增强以及常用的几种数据增强的手法,可以看看下面的文章&#…

分享WCF聊天程序--WCFChat

无意中在一个国外的站点下到了一个利用WCF实现聊天的程序,作者是:Nikola Paljetak。研究了一下,自己做了测试和部分修改,感觉还不错,分享给大家。先来看下运行效果:开启服务:客户端程序&#xf…

【神经网络扩展】:断点续训和参数提取

课程来源:人工智能实践:Tensorflow笔记2 文章目录前言断点续训主要步骤参数提取主要步骤总结前言 本讲目标:断点续训,存取最优模型;保存可训练参数至文本 断点续训主要步骤 读取模型: 先定义出存放模型的路径和文件名&#xff0…

小米手环6NFC安装太空人表盘

以前看我室友峰哥、班长都有手环,一直想买个手环,不舍得,然后今年除夕的时候降价,一狠心,入手了,配上除夕的打年兽活动还有看春晚京东敲鼓领的红包和这几年攒下来的京东豆豆,原价279的小米手环6…

为什么两层3*3卷积核效果比1层5*5卷积核效果要好?

目录1、感受野2、2层3 * 3卷积与1层5 * 5卷积3、2层3 * 3卷积与1层5 * 5卷积的计算量比较4、2层3 * 3卷积与1层5 * 5卷积的非线性比较5、2层3 * 3卷积与1层5 * 5卷积的参数量比较1、感受野 感受野:卷积神经网络各输出特征像素点,在原始图片映射区域大小。…

算法正确性和复杂度分析

算法正确性——循环不变式 算法复杂度的计算 方法一 代换法 —局部代换 这里直接对n变量进行代换 —替换成对数或者指数的情形 n 2^m —整体代换 这里直接对递推项进行代换 —替换成内部递推下标的形式 T(2^n) S(n) 方法二 递归树法 —用实例说明 —分析每一层的内容 —除了…

第十五章 Python和Web

第十五章 Python和Web 本章讨论Python Web编程的一些方面。 三个重要的主题:屏幕抓取、CGI和mod_python。 屏幕抓取 屏幕抓取是通过程序下载网页并从中提取信息的过程。 下载数据并对其进行分析。 从Python Job Board(http://python.org/jobs&#x…

【数据结构基础笔记】【图】

代码参考《妙趣横生的算法.C语言实现》 文章目录前言1、图的概念2、图的存储形式1、邻接矩阵:2、邻接表3、代码定义邻接表3、图的创建4、深度优先搜索DFS5、广度优先搜索BFS6、实例分析前言 本章总结:图的概念、图的存储形式、邻接表定义、图的创建、图…

如何蹭网

引言蹭网,在普通人的眼里,是一种很高深的技术活,总觉得肯定很难,肯定很难搞。还没开始学,就已经败给了自己的心里,其实,蹭网太过于简单。我可以毫不夸张的说,只要你会windows的基本操…

android对象缓存,Android简单实现 缓存数据

前言1、每一种要缓存的数据都是有对应的versionCode,通过versionCode请求网络获取是否需要更新2、提前将要缓存的数据放入assets文件夹中,打包上线。缓存设计代码实现/*** Created by huangbo on 2017/6/19.** 主要是缓存的工具类** 缓存设计&#xff1a…

通信原理.绪论

今天刚上通信原理的第一节课,没有涉及过多的讲解,只是讲了下大概的知识框架。现记录如下: 目录1、基本概念消息、信息与信号2、通信系统模型1、信息源2、发送设备3、信道4、接收设备5、信宿6、模拟通信系统模型7、数字通信系统模型8、信源编…