TensorFlow2.0笔记(二)——神经网络优化

北大MOOC——TF2.0笔记

以下是我的听课笔记,供以后回忆(大多内容来自ppt)

一.神经网络优化

1.常用函数讲解

np.mgrid函数: 

import numpy as np
import tensorflow as tf

# 生成等间隔数值点
x,y= np.mgrid[1:2:0.5,2:3.5:0.5]
# 将x, y拉直,并合并配对为二维张量,生成二维坐标点
grid = np.c_[x.ravel(), y.ravel()]
print("x:\n", x)
print("y:\n", y)
print("x.ravel():\n", x.ravel())
print("y.ravel():\n", y.ravel())
print('grid:\n', grid)


 输出:

此例子[1:2)以0.5为间隔,有1,1.5,有两个元素

[2:3.5)以0.5为间隔,有2,2.5,3,有三个元素

则输出的x,y的格式为2行三列

(x中每一列为一个完整的数列,y中每一行为一个完整的数列)

2.神经网络(NN)复杂度

NN的层数:只统计具有运算能力的层,即隐藏层+输出层(输入层不具有计算能力,因此不纳入统计)

隐藏层:输入层与输出层之间的所有层都叫隐藏层。

3.衰减学习率

import tensorflow as tf

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):  # for epoch 定义顶层循环,表示对数据集循环epoch次,此例数据集数据仅有1个w,初始化时候constant赋值为5,循环100次迭代。
    lr = LR_BASE * LR_DECAY ** (epoch / LR_STEP)
    with tf.GradientTape() as tape:  # with结构到grads框起了梯度的计算过程。
        loss = tf.square(w + 1)
    grads = tape.gradient(loss, w)  # .gradient函数告知谁对谁求导

    w.assign_sub(lr * grads)  # .assign_sub 对变量做自减 即:w -= lr*grads 即 w = w - lr*grads
    print("After %s epoch,w is %f,loss is %f,lr is %f" % (epoch, w.numpy(), loss, lr))

输出:

4.激活函数

Sigmoid激活函数:

把输入值变为[0,1]之间的数值输出。若输入是绝对值很大的复数,则输出为0;若输入是很大的正数,则输出是1。

由于深层神经网络更新参数时,需要从输入层到输出层逐层链式求导,Sigmoid函数的导是[0,0.25]的小数,多次乘法运算后,结果趋近于0。产生梯度消失,使得参数无法更新。因此Sigmoid激活函数现在并不常用。

Tanh激活函数:

Relu激活函数:

缺点:若送入激活函数的输入值是负数,激活函数输出是0,反向传播得到的梯度是0,导致参数无法更新,造成神经元死亡

实际情况中还是使用Relu较多。

5.损失函数

均方误差MSE:

自定义损失函数:

交叉熵损失函数SE:

import tensorflow as tf
import numpy as np

SEED = 23455
COST = 1  #成本
PROFIT = 99    #利润
#x(32,2) w1(2,1)  预测值y= matmul(x, w1)是(32,1)32行1列的
rdm = 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.002

for epoch in range(epoch):
    with tf.GradientTape() as tape:
        y = tf.matmul(x, w1)  #y是预测的值
        loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * COST, (y_ - y) * PROFIT)) #32组的差之和
    grads = tape.gradient(loss, w1)  #先用loss对w1求导,之后再将w1的值带入
    #loss是关于w1的函数???
    w1.assign_sub(lr * grads)

    if epoch % 500 == 0:
        print("After %d training steps,w1 is " % (epoch))
        print(w1.numpy(), "\n")
        print("y_",y_)   #y_是列表形式
        print("y", y)
        print("loss", loss)
        print("grads", grads)
print("Final w1 is: ", w1.numpy())

# 自定义损失函数
# 酸奶成本1元, 酸奶利润99元
# 成本很低,利润很高,人们希望多预测些,生成模型系数大于1,往多了预测

对于代码我很好奇,loss不是关于w1的函数呀,loss对w1求偏导的操作是什么呢?下图是其他博主的解答:

欠拟合:是对现有数据集学习的不够彻底

过拟合:是模型对当前数据拟合的太好了,但对从未见过的新数据不能做出正确的判断。

数据噪声:数据中存在的错误或异常的数据,对模型有误导作用的数据。

过拟合。就是拟合函数顾忌的点太多,函数在小范围内波动很大。这就代表着函数在小范围内的斜率很大(即导数的绝对值很大),由于自变量值可大可小,所以只有系数足够大,才能保证导数值很大。而正则化是通过约束参数的范数使其不要太大,所以可以在一定程度上减少过拟合情况。

正则化的目的是限制参数过多或者过大,避免模型更加复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值