MOOC北大tensorflow笔记二

一. 神经网络(NN)的复杂度

NN复杂度:多个NN层数和NN参数的个数表示。

1.空间复杂度

层数=隐藏层层数+一个输出层

总参数=总w+总b

2.时间复杂度

乘加运算次数

 二.指数衰减学习率

在神经网络的参数更新过程中,学习率不能太大也不能太小,太大可能会导致参数在最优值两侧来回移动,太小会大大降低优化速度,为了解决学习率的问题,TensorFlow 提供了一种灵活的学习率设置方法,即指数衰减法。

可以用较大的学习率,快速得到较优解,然后逐步减小学习率,使模型在训练后期稳定。

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

import tensorflow as tf
import matplotlib.pyplot as plt
epoch=1000#定义迭代轮数
LR_BASE=0.2#当前学习率
LR_DECAY=0.99#学习率衰减率
LR_STEP=1#一轮更新一次学习率
w=tf.Variable(tf.constant(5,dtype=tf.float32))

lr_epoch=[]
for epoch in range(epoch):

    lr=LR_BASE * LR_DECAY ** (epoch/LR_STEP)
    lr_epoch.append(lr)
    with tf.GradientTape() as tape:
        loss=tf.square(w+1)
    grads=tape.gradient(loss,w)

    w.assign_sub(lr*grads)
    print("After %s epoch w is %f,loss is %f,lr is %f" %(epoch,w,loss,lr))
#将学习率用二维图像表示
plt.figure(num=1)

plt.plot(range(epoch+1),lr_epoch)
plt.xlabel('lr')
plt.ylabel('epoch')
plt.show()

 运行结果:随着迭代次数,学习率在指数衰减

 三.激活函数

优秀的激活函数:
非线性:激活函数非线性时,多层神经网络可逼近所有函数
可微性:优化器大多用梯度下降更新参数
单调性:当激活函数是单调的,能保证单层网络的损失函数是凸函数
近似恒等性:F(X)~x当参数初始化为随机小值时,神经网络更稳定
激活函数输出值的范围:
激活函数输出为有限值时,基于梯度的优化方法更稳定
激活函数输出为无限值时,建议调小学习率

1.sigmoid函数的导数的输出使是0到0.25之间的小数,链式求导需要层导数连续相乘,会出现多个0到0.25之间的连续相乘,结果将趋于0产生梯度消失,使得参数无法继续更新。

 2.输出的非零均值,sigmoid激活函数后的数据都是正数,回事收敛变慢

3.存在幂运算计算复杂度大,训练时间长。

对于初学者的建议: 
首选relu激活函数; 
R学习率设置较小值;
输入特征标准化,即让输入特征满足以0为均值,
1为标准差的正态分布; 
初始参数中心化,即让随机生成的参数满足以0 为均值,sqrt{(2/当前输入的特征值)} 为标准差的正态分布。

四.损失函数

损失函数就是与测试y与已知答案y_的差距

NN优化目标有三种使loss最小----1.mse(平均均方误差),2.自定义损失函数,3.ce((Cross Entropy) (交叉熵))

1.mse(平均均方误差)

 tensorflow表示:

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

 举个例子:

预测酸奶日销量y, x1、 x2是影响日销量的因素。建模前,应预先采集的数据有:每日x1、 x2和销量y_ (即已知答案, 最佳情况:产量=销量)拟造数据集X,Y_ : y_ =x1 + x2
噪声: -0.05~ +0.05拟合 可以预测销量的函数。

其实就是通过梯度下降,使w1的两个数与制造数据集的公式y=x1+x2+-0.05一致,也就是使两个数接近于1.

代码:

numpy.random.RandomState(seed=?)是一个伪随机数生成器, 此命令将会产生一个随机状态种子,在该状态下生成的随机序列(正态分布)一定会有相同的模式。伪随机数是用确定性的算法计算出来的似来自[0,1]均匀分布的随机数序列,作用同np.random.seed(n)
import tensorflow as tf
import numpy as np

#设置随机种子
seed=23455
#numpy.random.RandomState(seed=?)是一个伪随机数生成器, 此命令将会产生一个随机状态种子,在该状态下生成的随机序列(正态分布)一定会有相同的模式。
#伪随机数是用确定性的算法计算出来的似来自[0,1]均匀分布的随机数序列
#起作用同np.random.seed(n)
rdm = np.random.RandomState(seed=seed)
x=rdm.rand(32,2)#生成x1,x2
#rdm.rand() 生成0-1之间的随机数
#取出x中的两列数,输入前面再加上噪声+-0.05
y_=[[x1+x2+(rdm.rand()/10.0-0.05)] for (x1,x2) in x]

x=tf.cast(x,dtype=tf.float32)
#生成两行一列的生态分布随机数
w1=tf.Variable(tf.random.normal([2,1],stddev=1,seed=1))

epoch=15000
lr=0.002
for epoch in range(epoch):
    with tf.GradientTape() as type:
        y=tf.matmul(x,w1)
        loss=tf.reduce_mean(tf.square(y_-y))

    grads=type.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,说明拟合成功。

 2.自定义损失函数

如上述的商品销量中,预测多了,损失的是成本,少了损失的是利润。用mse的loss无法实现利益的最大化,所以可以自定义loss

 

 如酸奶销量,成本COST为1元,利润PROFIT为99元,如何实现利益的最大化呢

代码如下:

 tf.greater(y,y_)比较大小
 tf.where(condition,a,b)相当于三目运算,如果condition成立输出a,否则输出b

import tensorflow as tf
import numpy as np

#设置随机种子
seed=23455

rdm = np.random.RandomState(seed=seed)
x=rdm.rand(32,2)#生成x1,x2
#rdm.rand() 生成0-1之间的随机数
#取出x中的两列数,输入前面再加上噪声+-0.05
y_=[[x1+x2+(rdm.rand()/10.0-0.05)] for (x1,x2) in x]

x=tf.cast(x,dtype=tf.float32)
#生成两行一列的生态分布随机数
w1=tf.Variable(tf.random.normal([2,1],stddev=1,seed=1))

Cost=1
Profit=99
epoch=15000
lr=0.002
for epoch in range(epoch):
    with tf.GradientTape() as type:
        y=tf.matmul(x,w1)
        #tf.greater(y,y_)比较大小
        #tf.where(condition,a,b)相当于三目运算,如果condition成立输出a,否则输出b
        loss=tf.reduce_sum(tf.where(tf.greater(y,y_),(y-y_)*Cost,(y_-y)*Profit))

    grads=type.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())

 结果是如果cost小,profit大,那么w1的值就会比1大,因为利润大,尽可能多预测。

 3.交叉熵

Softmax于交叉熵结合

 

五.正则化缓解过拟合

详见L2正则化缓解过拟合实例

六.优化器

 

 1.SGD

 代码表示:

 

 # w1 = w1 - lr * w1_grad
 w1.assign_sub(lr * grads[0])

 2.SGDM

m_w,m_b=0,0
beta=0.9

  grads = tape.gradient(loss, [w1, b1])
        m_w=beta*m_w+(1-beta)*grads[0]
        m_b=beta*m_b+(1-beta)*grads[1]


        # 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_grad
        w1.assign_sub(lr * m_w)  # 参数w1自更新
        b1.assign_sub(lr * m_b)  # 参数b自更新

 3.Adagrad 

代码:

v_w,v_b=0,0
 grads = tape.gradient(loss, [w1, b1])
        v_w+=tf.square(grads[0])
        v_b+=tf.square(grads[1])

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

 

 4.RMSProp

 

v_w,v_b=0,0
beta=0.9       
 grads = tape.gradient(loss, [w1, b1])
        v_w=beta*v_w+(1-beta)*tf.square(grads[0])
        v_b=beta*v_b+(1-beta)*tf.square(grads[1])


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

 5.Adam

 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#存放总batch数


# 训练部分
for epoch in range(epoch):  #数据集级别的循环,每个epoch循环一次数据集
    for step, (x_train, y_train) in enumerate(train_db):  #batch级别的循环 ,每个step循环一个batch
        global_step+=1
        ................
        ................

 
  grads = tape.gradient(loss, [w1, b1])
        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))

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值