在学习tensorflow的过程中,可能会有一些参数需要调整,对应不同的任务需要调整不同的参数,本篇介绍tensorflow构建model过程中可以自行调节的参数。
# 目的:学会神经网络优化过程,使用正则化减少过拟合,使用优化器更新网络参数 # 预备知识 # 神经网络复杂度 # 指数衰减学习率 # 激活函数 # 损失函数 # 欠拟合与过拟合 # 正则化减少过拟合 # 优化器更新网络参数
下面直接用代码来讲解需要了解的知识点
import tensorflow as tf
# tf.where 条件语句真返回A,条件语句假返回B
# tf.where(条件语句,真返回A,假返回B)
a = tf.constant([1,2,3,1,1])
b = tf.constant([0,1,3,4,5])
# tf.greater比较大小
gre = tf.greater(a,b)
print(gre)
# 第一个元素1>0,返回1,2>1,返回2,3=3,返回3,1<4,返回4,1<5,返回5 (如果a>b,返回a,如果a<b,返回b,总体来看就是取较大值)
c = tf.where(tf.greater(a,b),a,b)
print(c)
print('-'*20)
运行结果如下
首先创建了两个常量数组a和b
用tf.greater比较a和b大小,第一个元素a[0]=1>b[0]=0,返回True,第二个元素a[1]=2>b[1]=1,返回True,第三个元素a[2]=3等于b[2]=3,返回False,后面元素都是b大于a,所以后面两个元素返回False
c的运算过程稍微复杂,首先用tf.greater(a,b)来生成一个boolen数组,然后对数组中每一个bool类型元素进行tf.where运算,第一个元素为True,真,返回a[0],也就是1,第二个元素为True,真,返回a[1]=2,a,b中第三个元素都是3,所以不做讨论,第四个元素为False,返回b[3]=4,第五个元素为Fasle,返回b[4]=5,所以c为[1,2,3,4,5]
下面一个知识点:
# 返回一个[0,1)之间的随机数np.random.RandomState.rand(维度) 维度为空,返回标量
import numpy as np
rdm = np.random.RandomState(seed=1)
a = rdm.rand()
b = rdm.rand(2,3)
print('a:',a)
print('b:',b)
print('-'*20)
这个函数有点类似于python自带的random.randint函数,都是生成0-1之间的一个随机数,这里rand可以指定维度,rand(2,3)代表生成两行三列的一个随机数数组
下一个知识点:
# np.vstack 将两个数组按垂直方向叠加np.vstack(数组1,数组2)
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.vstack((a,b))
print('c:\n',c)
print('-'*20)
注意叠加的元素需要是同维度的,叠加不是相加,只是单纯把两个数组上下拼接在一起
下一个知识点:
# np.mgrid .ravel() np.c_[]
# np.mgrid[起始值:结束值:步长,起始值:结束值:步长,......]
# x.ravel() 把x变成一维数组
# np.c_[]使返回的间隔数值点配对
x,y = np.mgrid[1:3:1,2:4:0.5]
grid = np.c_[x.ravel(),y.ravel()]
print('x:',x)
print('y:',y)
print('grid:\n',grid)
print('-'*20)
mgrid函数返回多维结构 ret = np.mgrid[第1维,第2维,第3维,…] 一维的表示是np.mgrid[起点:终点:步长] 二维的表示是np.mgrid[起点:终点:步长,起点:终点:步长] 其中x.ravel()和y.ravel()的结果如下
将这两个数组按照对应位置来匹配,上面第一个元素1对应下面第一个元素2,生成一个[1,2]数组,上面第二个元素1对应下面第二个元素2.5,生成[1,2.5]数组,同理后面每个上下元素一一对应,生成相应的数组,并且这些一个个单独的一维数组合并成一个二维数组,即c所显示的二维数组
下一个知识点:
神经网络复杂度,先上图
# 空间复杂度:
# 层数=隐藏层的层数+1(1为输出层)
# 总参数=总w+总b
# 3x4+4 + 4x2+2 = 26
# 第一层 第二层
# 输入层3个神经元,图中隐藏层有4个神经元,输入层每个神经元都要给隐藏层每个神经元传递参数,
# 即3x4,每个隐藏层有多少个神经元,该层偏置项就有几个,所以该图中偏置项b有4个,该层w+b为
# 12+4=16,同理隐藏层到输出层有4x2个连接,输出层有两个神经元,偏置b有两个,w+b=10
#
# 时间复杂度:
# 乘加运算次数
# 左图3x4 + 4x2 =20
# 第一层 第二层
下一个知识点(了解): 指数衰减学习率: 可以先用较大学习率,快速得较优解,然后逐步减小学习率,使模型在训练后期稳定 指数衰减学习率=初始学习率*学习率衰减率(当前轮数/多少轮衰减一次)
下一个知识点:
# sigmoid函数 值范围从0到1 x=0时y=0.5 函数为1/(1+e**(-x)) 适用于二分类,适用于在输出层 调用方法:tf.nn.sigmoid
# 特点:易造成梯度消失,输入非0均值,收敛慢,幂运算复杂,训练时间长
# relu函数 当x<0时y=0 当x>0时y=x 适用于隐藏层
# tanh函数 值从-1到1 x=0,y=0 函数为(e**(-x)-e**x)/(e**(-x)+e**x) 适用于RNN循环神经网络
# 调用为tf.math.tanh
# tf.nn.relu 优点:解决了梯度消失问题,只需判断输入是否大于0,收敛速度远快于sigmoid和tanh 缺点:有些神经元可能无法被激活
# 激活函数对于初学者建议:
# 首选relu激活函数
# 学习率设置较小值
# 输入特征标准化,即让输入特征满足以0为均值,1为标准差的正态分布
# 初始参数中心化,让随机生成的参数满足正态分布
sigmoid函数如图
relu函数如图
tanh函数如图
讲完基本的三种基本的激活函数,来看下一个知识点:
# 损失函数(loss):预测值(y)与已知答案(y_)的差距
# NN优化目标:loss最小-->可以采用均方误差损失函数mse(Mean Squared Error),自定义误差和ce交叉熵损失函数(Cross Entropy)
# 均方误差mse: loss_mse = tf.reduce_mean(tf.square(y_-y))
# 交叉熵损失函数CE(Cross Entropy):表征两个概率分布之间的距离
# softmax与交叉熵结合
# tf.nn.softmax_cross_entropy_with_logits(y_,y)
y_ = 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)
下一个知识点:
# 欠拟合与过拟合
# 欠拟合的解决办法:增加输入特征项,增加网络参数,减少正则化参数
# 过拟合的解决办法:数据清洗,增大训练集,采用正则化,增大正则化参数
# 正则化在损失函数中引入模型复杂度指标,利用给W加权重,弱化了数据的噪声(一般不正则化b)
# loss = loss(y与y_) + REGULARIZER*loss(w)
# 模型中所有参数的损失函数,如均方误差,交叉熵 用超参数给出参数w在总loss中比例,即正则化的权重
# L1正则化:w绝对值求和 大概率会使很多参数变0,该方法可以通过稀疏参数,即减少参数数量,降低复杂度
# L2正则化:w平方绝对值求和 会使参数很接近0但不为0,可以减小参数值大小降低复杂度
# 神经网络优化器
# 待优化参数w,损失函数loss,学习率lr,每次迭代一个batch,t代表当前batch迭代总次数
# 1.计算t时刻损失函数关于当前参数的梯度gt
# 2.计算t时刻一阶动量mt和二阶动量vt
# 3.计算t时刻下降参数
# 4.计算t+1时刻参数
# 一阶动量:与梯度相关的函数
# 二阶动量:与梯度平方相关的函数
# 优化器有
# SGD,常用梯度下降法
# SGDM,在SGD基础上增加一阶动量
# Adagrad 在SGD基础上增加二阶动量
# RMSProp 在SGD基础上增加二阶动量