tensorflow中的常用函数与API 2

tensorflow中的常用函数与API 2

1.学习率策略

指数衰减

TensorFlow API: tf.keras.optimizers.schedules.ExponentialDecay

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

# 手动实现
w = tf.Variable(tf.constant(5, dtype=tf.float32))

epoch = 40
LR_BASE = 0.2  # 最初学习率
LR_DECAY = 0.99  # 学习率衰减率
LR_STEP = 1  # 喂入多少轮BATCH_SIZE后,更新一次学习率

for epoch in range(epoch):  
    lr = LR_BASE * LR_DECAY ** (epoch / LR_STEP)
    # 其他代码

分段常数衰减

TensorFlow API:tf.optimizers.schedules.PiecewiseConstantDecay

2.激活函数

优秀的激活函数应满足:

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

激活函数输出值的范围:

  • 激活函数输出为有限值时,基于梯度的优化方法更稳定
  • 激活函数输出为无限值时,建议调小学习率

2.1 sigmoid

TensorFlow API:tf.math.sigmoid

优点:

  1. 输出映射在(0,1)之间,单调连续,输出范围有限,优化稳定,可用作输出层;
  2. 求导容易。

缺点:

  1. 易造成梯度消失;
  2. 输出非0均值,收敛慢;
  3. 幂运算复杂,训练时间长。

2.2 tanh

TensorFlow API:tf.math.tanh

优点:

  1. 比sigmoid函数收敛速度更快。
  2. 相比sigmoid函数,其输出以0为中心。

缺点:

  1. 易造成梯度消失;
  2. 幂运算复杂,训练时间长。

2.3 ReLU

TensorFlow API:tf.nn.relu

优点:

  1. 解决了梯度消失问题(在正区间);
  2. 只需判断输入是否大于0,计算速度快;
  3. 收敛速度远快于sigmoid和tanh,因为sigmoid和tanh涉及很多expensive的操作;
  4. 提供了神经网络的稀疏表达能力。

缺点:

  1. 输出非0均值,收敛慢;
  2. Dead ReLU问题:某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。

2.4 Leaky ReLU

TensorFlow API:tf.nn.leaky_relu

image-20220308093825138

理论上来讲,Leaky ReLU有ReLU的所有优点,外加不会有Dead ReLU问题,但是在实际操作当 中,并没有完全证明Leaky ReLU总是好于ReLU。

2.5 softmax

TensorFlow API:tf.nn.softmax

建议

  1. 首选ReLU激活函数;
  2. 学习率设置较小值;
  3. 输入特征标准化,即让输入特征满足以0为均值,1为标准差的正态分布;
  4. 初始化问题:当激活函数使用ReLU时,一般推荐使用ReLU专用的初始值,也称为“He初始值”。当前一层的节点数为n时,He初始值使用标准差为(2/n)1/2的高斯分布

3.损失函数

3.1均方误差损失函数MSE

TensorFlow API:tf.keras.losses.MSE

3.2交叉熵损失函数

TensorFlow API:tf.keras.losses.categorical_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0)

y_true: 真实值.

y_pred: 预测值.

from_logits: y_pred是否为logits张量.

label_smoothing: [0,1]之间的小数.


TensorFlow API:tf.nn.softmax_cross_entropy_with_logits(labels, logits, axis=-1, name=None)

softmax与交叉熵结合使用

logits经过softmax后,与labels进行交叉熵计算.。


TensorFlow API:tf.nn.sparse_softmax_cross_entropy_with_logits(labels, logits, name=None)

labels先进行one-hot编码,logits先进行softmax,之后两者进行交叉熵计算。

自定义损失函数

均方误差损失函数MSE认为 “y比y_大1” 和 “y比y_小1” 这两种情况的误差相同,然而实际情况往往不是这样,例如比销售量多生产一件商品损失的是生产成本,而比销售量少生产一件商品损失的是一件商品的利润。因此,可以根据实际情况自定义损失函数。

4.优化器

4.1优化方法

定义:待优化参数w, 损失函数loss,学习率lr,每次迭代一个batch,t表示当前batch迭代的总次数:

image-20220308095447465

一阶动量:与梯度相关的函数

二阶动量:与梯度平方相关的函数

在上面的四个步骤中,3,4基本上是不变的,不同的优化器定义了不同的一阶动量mt和二阶动量vt

4.2SGD

TensorFlow API: tf.keras.optimizers.SGD

4.2.1 vanilla SGD

原始的SGD

一阶动量mt=梯度gt

二阶动量vt=1

所以:::::::::::

η = lr * mt / 1 = lr * gt

w = w - lr * gt

w1.assign_sub(learning_rate * grads[0])
b1.assign_sub(learning_rate * grads[1])
4.2.2 SGD with Momentum

引入了动量的SGD

一阶动量mt=βmt-1 + (1-β)gt

二阶动量vt=1

所以:::::::::::

η = lr * mt / 1 = lr * (βmt-1 + (1-β)gt)

w = w - lr * (βmt-1 + (1-β)gt)

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

4.3AdaGrad

TensorFlow API:tf.keras.optimizers.Adagrad

此引入二阶动量:所有梯度值的平方和

一阶动量mt=gt

二阶动量vt=∑gt2

所以:::::::::::

η = lr * gt / (∑gt2)0.5

w = w - lr * gt / (∑gt2)0.5

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

4.4RMSProp

TensorFlow API: tf.keras.optimizers.RMSprop

由于 AdaGrad 的学习率衰减太过激进,考虑改变二阶动量的计算策略:不 累计全部梯度,只关注过去某一窗口内的梯度。

一阶动量mt=gt

二阶动量vt=β2vt-1 + (1-β2)gt2

所以:::::::::::

η = lr * gt / (β2vt-1 + (1-β2)gt2)0.5

w = w - lr * gt / (β2vt-1 + (1-β2)gt2)0.5

beta = 0.9
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(learning_rate * grads[0] / tf.sqrt(v_w))
b1.assign_sub(learning_rate * grads[1] / tf.sqrt(v_b))

4.5Adam

TensorFlow API: tf.keras.optimizers.Adam

Adam将Momentum和RMSProp结合起来,既有一阶动量又有二阶动量。

一阶动量mt=βmt-1 + (1-β)gt

二阶动量vt2vt-1 + (1-β2)gt2

一阶动量和二阶动量都是按照指数移动平均值进行计算的。初始化m0=0,v0=0 ,在初期,迭代得到的会接近于0。我们可以通过对mt,vt进行偏差修正来解决这一问题。

image-20220308101238004

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(learning_rate * m_w_correction / tf.sqrt(v_w_correction))
b1.assign_sub(learning_rate * m_b_correction / tf.sqrt(v_b_correction))

总结

优化器一阶动量mt二阶动量vtη = lr * mt / vt2/1w = w - η
vanilla SGDgt1lr * gtw = w - lr *gt
SGD with Momentumβmt-1 + (1-β)gt1lr * βmt-1 + (1-β)gtw = w - lr * βmt-1 + (1-β)gt
AdaGradgt∑gt2lr * gt / (∑gt2)0.5w = w - lr * gt / (∑gt2)0.5
RMSPropgtβ2vt-1 + (1-β2)gt2lr * gt / (β2vt-1 + (1-β2)gt2)0.5w = w - lr * gt / (β2vt-1 + (1-β2)gt2)0.5
Adamβmt-1 + (1-β)gtβ2vt-1 + (1-β2)gt2加入偏差修正

5.其他常用函数

  1. tf.where(condition, x, y) 根据condition,取x或y中的值。如果condition为True,对应位置取x的值;如果condition为 False,对应位置取y的值。很类似于c语言中的三元运算符:condition?x,y

  2. np.random.RandomState.rand(维度) 返回一个[0,1)之间的随机数

  3. np.vstack()将两个数组按垂直方向叠加

    a = np.array([1, 2, 3])
    b = np.array([4, 5, 6])
    c = np.vstack((a, b))
    print("c:\n", c)
    #c:
    #[[1 2 3]
    # [4 5 6]]
    
  4. np.mgrid[起始值:结束值:步长 ,起始值:结束值:步长 , ],这个函数不太该理解,结合着例子看

    x, y = np.mgrid[1:3:1, 2:4:0.5]
    print("x:\n", x)
    print("y:\n", y)
    # x:
    #  [[1. 1. 1. 1.]
    #  [2. 2. 2. 2.]]
    # y:
    #  [[2.  2.5 3.  3.5]
    #  [2.  2.5 3.  3.5]]
    

    要保证返回的两个(多个数组维度相同),第一个参数(1:3:1)决定行数为2,第二个参数(2:4:0.5)决定列数为4。

  5. x.ravel() 将x变为一维数组,“把x变量拉直”

    #接上一段代码
    x1=x.ravel()
    y1=y.ravel()
    # x1:
    #  [1. 1. 1. 1. 2. 2. 2. 2.]
    # y1:
    #  [2.  2.5 3.  3.5 2.  2.5 3.  3.5]
    
  6. np.c_[ ] 使返回的间隔数值点配对 np.c_[ 数组1,数组2, … ]

    #接上一段代码
    grid = np.c_[x1, y1]
    print('grid:\n', grid)
    # grid:
    #  [[1.  2. ]
    #  [1.  2.5]
    #  [1.  3. ]
    #  [1.  3.5]
    #  [2.  2. ]
    #  [2.  2.5]
    #  [2.  3. ]
    #  [2.  3.5]]
    

    两个数组的值一一配对。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值