Tensorflow学习笔记----损失函数、链式法则、反向传播

本文深入探讨了深度学习中的损失函数概念,包括MSE和交叉熵,并详细解析了链式法则和多层感知机反向传播算法,帮助读者理解如何通过梯度下降优化模型参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.损失函数(LossFunction)

MSE:loss = 1/NΣ( y - out )2

#MSE
y = tf.constant([1,2,3,0,2])
y = tf.one_hot(y,depth=4)#独热编码指的是在分类问题中,将存在数据类别的那一类用X表示,不存在的用Y表示,这里的X常常是1, Y常常是0。
y = tf.cast(y,dtype = tf.float32)
out = tf.random.normal([5,4])

#以下三种方式是求loss的不同方式
print("loss1:",loss1 = tf.reduce_mean(tf.square(y-out)))#最基本的方式
print("loss2:",loss2 = tf.square(tf.norm(y-out))/(5*4))
print("loss3:",loss3 = tf.reduce_mean(tf.losses.MSE(y,out)))#tf.MSE提供现成的
# loss1: tf.Tensor(1.1543081, shape=(), dtype=float32)
# loss2: tf.Tensor(1.1543081, shape=(), dtype=float32)
# loss3: tf.Tensor(1.1543081, shape=(), dtype=float32)

针对分类问题误差loss:交叉熵Cross Entropy

  • 熵Entropy = -ΣP(i)*logP(i) 交叉熵Cross Entropy :H(p,q)= -ΣP(x)*logq(x)

先理解熵Entropy = -ΣP(i)*logP(i):熵越大,精细度越低,之前概率越均等,这样的分类学习器越差;熵越小说明之前的分类概率差距越大,分类学习器越好;

a = tf.fill([4],0.25)
print(a*tf.math.log(a)/tf.math.log(2.))
#tf.Tensor([-0.5 -0.5 -0.5 -0.5], shape=(4,), dtype=float32)
print(-tf.reduce_sum(a*tf.math.log(a)/tf.math.log(2.)))#输出熵,熵越大,精细度越低,熵越小,学习器越好
#tf.Tensor(2.0, shape=(), dtype=float32)

a = tf.constant([0.1,0.1,0.1,0.7])
print(-tf.reduce_sum(a*tf.math.log(a)/tf.math.log(2.)))
#tf.Tensor(1.3567797, shape=(), dtype=float32)
a = tf.constant([0.01,0.01,0.01,0.97])
print(-tf.reduce_sum(a*tf.math.log(a)/tf.math.log(2.)))
tf.Tensor(0.24194068, shape=(), dtype=tf.float32)

交叉熵Cross Entropy :H(p,q)= -ΣP(x)*logQ(x)

  • 假如:有一个分类器,在五张图片中输出分别是狗的概率,其中我们肉眼可得知第一张为狗,则P1 = [1,0,0,0,0],分类器输出测试数据Q1 = [0.4, 0.3, 0.05, 0.05, 0.2]:
    H(P1,Q1) = -ΣP(i)*logQ(i) = - (1log0.4 + 0log0.3 + 0log0.05 + 0log0.05 + 0log0.2)= - log0.4 ≈ 0.916 这样的交叉熵就表示分类器的结果并不好,输出的Q中预测概率太过均等;
    若Q1 = [0.98, 0.01, 0, 0, 0.01]:
    H(P1,Q1) = -ΣP(i)*logQ(i) = - (1log0.98 + 0log0.01 + 0log0 + 0log0 + 0log0.01)
    = - log0.98 ≈ 0.02 这样的交叉熵就表示分类器的结果比较好,输出的Q中的概率差距明显较大,分类明确;

tf.losses.categorical_crossentropy([……],[……]):tf提供的计算交叉熵的函数,前一个参数是P,即正确的分类,后一个参数是Q,即预测的分类

print(tf.losses.categorical_crossentropy([0,1,0,0],[0.25,0.25,0.25,0.25]))
#tf.Tensor(1.3862944, shape=(), dtype=float32)
print(tf.losses.categorical_crossentropy([0,1,0,0],[0.1,0.1,0.8,0.1]))
#tf.Tensor(2.3978953, shape=(), dtype=float32)
print(tf.losses.categorical_crossentropy([0,1,0,0],[0.01,0.97,0.01,0.01]))
#tf.Tensor(0.030459179, shape=(), dtype=float32)
print(tf.losses.binary_crossentropy([1],[0.1])) #二分类计算
#tf.Tensor(2.3025842, shape=(), dtype=float32)

二.链式法则(ChainRule)

使用链式法则可以把最后一层的误差一层一层的输出到中间层的权值上去,从而得到中间层的梯度信息,由梯度信息可以很好地更新权值,从而达到最优化的效果。

公式:dy/dx = dy/du * du/dx,借助中间变量求得导数。如:
y1 = xw1 + b1; y2 = y1w2 + b2;
则∂y2 / ∂w1 = ∂f(y1) / ∂w = ∂f(y1) / ∂y1 * ∂y1 / ∂w1 = w2 * x

x = tf.constant(1.)
w1 = tf.constant(2.)
b1 = tf.constant(1.)
w2 = tf.constant(2.)
b2 = tf.constant(1.)

with tf.GradientTape(persistent=True) as tape:
    tape.watch([w1,b1,w2,b2])
    y1 = x*w1 + b1
    y2 = y1*w2 + b2

dy2_dy1 = tape.gradient(y2,[y1])[0]
dy1_dw1 = tape.gradient(y1,[w1])[0]
dy2_dw1 = tape.gradient(y2,[w1])[0]
print("dy2_dy1=",dy2_dy1,"\ndy1_dw1=",dy1_dw1,"\ndy2_dw1=",dy2_dw1)
# dy2_dy1= tf.Tensor(2.0, shape=(), dtype=float32)
# dy1_dw1= tf.Tensor(1.0, shape=(), dtype=float32)
# dy2_dw1= tf.Tensor(2.0, shape=(), dtype=float32)

三.多层感知机反向传播算法(BackPropagation,BP)

在梯度下降那里我们曾经学过多输出感知机及其梯度,它的loss以及导数为:
Loss = 1/2 Σ(O1i - ti)2;对其j层求导:(Ok - tk) Ok (1 - Ok)xj0;

loss函数的目的就是计算出当前神经网络建模出来输出的数据和理想数据之间的距离。根据反向传播算法就可以更新网络中的各种参数以此使loss不断下降,即可使输出的数据更加理想。该方法对网络中所有权重计算损失函数的梯度。这个梯度会反馈给最优化方法,用来更新权值以最小化损失函数。(误差的反向传播)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值