动手学深度学习 | 自动求导 | 05
目錄自動求導(dǎo)自動求導(dǎo)實(shí)現(xiàn)QA
自動求導(dǎo)
鏈?zhǔn)椒▌t,如果擴(kuò)展到向量,最最重要的還是看形狀。
<x,w>這是內(nèi)積的寫法。
自動求導(dǎo)涉及到一個計(jì)算圖的概念,雖然Pytorch不用要求大家理解計(jì)算圖,但是理解了對使用TensorFlow等都是有好處的。
計(jì)算圖其實(shí)本質(zhì)上就和剛剛求導(dǎo)鏈?zhǔn)椒▌t的過程。
顯示構(gòu)造,就是先構(gòu)造好這個公式,然后再帶入數(shù)值計(jì)算,一般數(shù)學(xué)上都是屬于顯示構(gòu)造。
正向累積就是正常計(jì)算,反向傳播是從結(jié)果不停的反向進(jìn)行求導(dǎo)。
反向從根節(jié)點(diǎn)向下掃,可以保證每個節(jié)點(diǎn)只掃一次;
正向從葉節(jié)點(diǎn)向上掃,會導(dǎo)致上層節(jié)點(diǎn)可能需要被重復(fù)掃多次(正向中子節(jié)點(diǎn)比父節(jié)點(diǎn)先計(jì)算,因此也無法像反向那樣把本節(jié)點(diǎn)的計(jì)算結(jié)果傳給每一個子節(jié)點(diǎn))
自動求導(dǎo)實(shí)現(xiàn)
操作總結(jié)
import torch
x = torch.arange(4.)
# 等價于 x = torch.arange(4.,requires_grad=True)
x.requires_grad_(True) # 需要存儲中間結(jié)果
print(x.grad) # 查看x的梯度,默認(rèn)為None
y = 2*torch.dot(x,x) # 點(diǎn)稱
y # tensor(28., grad_fn=<MulBackward0>)
y.backward() # 對y進(jìn)行反向傳播
x.grad # 查看BP得到的梯度
# y=2x^2 y'=2x,可以判斷BP得到的梯度是否是對的
4*x == x.grad
x.grad_zero_() # Pytorch的梯度會累積,這里是將0寫入梯度中
y = x.sum() # sum() 相當(dāng)于點(diǎn)乘一個全為1的向量
y.backward()
x.grad
x.grad_zero_()
y = x*x
# x*x == sum(y·y)
y.sum().backward()
x.grad
# 將計(jì)算移動到計(jì)算圖之外
x.grad_zero_()
y = x*x
u = y.detach()
z = u*x
z.sum().backward()
x.grad,x.gard==u
# 及時構(gòu)建函數(shù)的計(jì)算圖需要通過Python控制流,我們?nèi)匀豢梢杂?jì)算得到變量的梯度
def f(a):
b = a * 2
while b.norm() < 1000:
b = b * 2
if b.sum() > 0:
c = b
else:
c = 100 * b
return c
# size=() 標(biāo)量
# a是一個隨機(jī)變量,并且需要記錄梯度
a = torch.randn(size=(), requires_grad=True)
d = f(a)
d.backward()
# f()可以理解成是一個計(jì)算圖的流程,最終得到d
# 因?yàn)槭菢?biāo)量,所以可以用斜率來驗(yàn)證得到的梯度是否是正確的
a.grad == d / a
QA
PPT上的顯示構(gòu)造和隱式構(gòu)造為什么看起來差不多?
顯示構(gòu)造:把整個計(jì)算圖都先設(shè)計(jì)完成,然后再給值
隱式構(gòu)造:就直接寫程序流程,然后框架會在后臺進(jìn)行計(jì)算圖的構(gòu)建
實(shí)際使用過程中,顯示構(gòu)造計(jì)算圖會麻煩很多!
為什么深度學(xué)習(xí)中一般對標(biāo)量求導(dǎo)而不是對矩陣求導(dǎo)或者向量?如果我的loss是包含向量或者矩陣,那求導(dǎo)之前是不是要把他們變成標(biāo)量?
loss通常是一個標(biāo)量,精度也好,很多機(jī)器學(xué)習(xí)的loss都是一個標(biāo)量,如果loss是一個向量的loss的話,那就會變得很麻煩。向量向下走就是就是矩陣,矩陣往下走四維矩陣,網(wǎng)絡(luò)程度一深,那么就會成為一個非常大的張量。
多個loss分別反向的時候是不是需要累積梯度?
是的,如果后面你的神經(jīng)網(wǎng)絡(luò)有多個損失函數(shù)的話,你是需要做梯度累加的,這也是Pytorch默認(rèn)累加梯度的一個理由。
總結(jié)
以上是生活随笔為你收集整理的动手学深度学习 | 自动求导 | 05的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: console高级用法
- 下一篇: 罗汉果怎么泡水(罗汉果泡水要去壳吗)