第二篇:自动微分
🔥本文 GitHub https://github.com/kzbkzb/Python-AI已收錄
Autograd: 自動微分
這里理解起來會比較費(fèi)勁,如果一遍不能理解,建議多讀幾遍反復(fù)推敲一下。
autograd 包是 PyTorch 中所有神經(jīng)網(wǎng)絡(luò)的核心。首先讓我們簡要地介紹它,然后我們將會去訓(xùn)練我們的第一個神經(jīng)網(wǎng)絡(luò)。該 autograd 軟件包為 Tensors 上的所有操作提供自動微分。它是一個由運(yùn)行定義的框架,這意味著以代碼運(yùn)行方式定義你的后向傳播,并且每次迭代都可以不同。我們從 tensor 和 gradients 來舉一些例子。
Tensor(張量)
torch.Tensor 是包的核心類。如果將其屬性 .requires_grad 設(shè)置為 True,則會開始跟蹤針對 tensor 的所有操作。完成計(jì)算后,您可以調(diào)用 .backward() 來自動計(jì)算所有梯度。該張量的梯度將累積到 .grad 屬性中。
要停止 tensor 歷史記錄的跟蹤,您可以調(diào)用 .detach(),它將其與計(jì)算歷史記錄分離,并防止將來的計(jì)算被跟蹤。
要停止跟蹤歷史記錄(和使用內(nèi)存),您還可以將代碼塊使用 with torch.no_grad(): 包裝起來。在評估模型時,這是特別有用,因?yàn)槟P驮谟?xùn)練階段具有 requires_grad = True 的可訓(xùn)練參數(shù)有利于調(diào)參,但在評估階段我們不需要梯度。
還有一個類對于 autograd 實(shí)現(xiàn)非常重要那就是 Function。Tensor 和 Function 互相連接并構(gòu)建一個非循環(huán)圖,它保存整個完整的計(jì)算過程的歷史信息。每個張量都有一個 .grad_fn 屬性保存著創(chuàng)建了張量的 Function 的引用,(如果用戶自己創(chuàng)建張量,則g rad_fn 是 None )。
如果你想計(jì)算導(dǎo)數(shù),你可以調(diào)用 Tensor.backward()。如果 Tensor 是標(biāo)量(即它包含一個元素?cái)?shù)據(jù)),則不需要指定任何參數(shù) backward(),但是如果它有更多元素,則需要指定一個 gradient 參數(shù)來指定張量的形狀。
import torch創(chuàng)建一個張量,設(shè)置 requires_grad=True 來跟蹤與它相關(guān)的計(jì)算
x = torch.ones(2, 2, requires_grad=True) print(x) tensor([[1., 1.],[1., 1.]], requires_grad=True)針對張量做一個操作
y = x + 2 print(y) tensor([[3., 3.],[3., 3.]], grad_fn=<AddBackward0>)y 作為操作的結(jié)果被創(chuàng)建,所以它有 grad_fn 。
print(y.grad_fn) <AddBackward0 object at 0x000001787ADEDE80>針對 y 做更多的操作:
z = y * y * 3 out = z.mean()print(z, out) tensor([[27., 27.],[27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>).requires_grad_( … ) 會改變張量的 requires_grad 標(biāo)記。輸入的標(biāo)記默認(rèn)為 False 。
a = torch.randn(2, 2) a = ((a * 3) / (a - 1)) print(a.requires_grad)a.requires_grad_(True) print(a.requires_grad)b = (a * a).sum() print(b.grad_fn) False True <SumBackward0 object at 0x00000178757355B0>Gradients(梯度)
我們現(xiàn)在后向傳播,因?yàn)閛ut包含了一個標(biāo)量,out.backward() 等同于 out.backward(torch.tensor(1.)) 。
out.backward()打印梯度 d(out)/dx
print(x.grad) tensor([[4.5000, 4.5000],[4.5000, 4.5000]])You should have got a matrix of 4.5. 我們把 out
Tensor 的值定為:“ooo”.
將會得到這樣的計(jì)算公式 o=14∑izio = \frac{1}{4}\sum_i z_io=41?∑i?zi?,
zi=3(xi+2)2z_i = 3(x_i+2)^2zi?=3(xi?+2)2 and zi∣xi=1=27z_i\bigr\rvert_{x_i=1} = 27zi?∣∣?xi?=1?=27.
Therefore,
?o?xi=32(xi+2)\frac{\partial o}{\partial x_i} = \frac{3}{2}(x_i+2)?xi??o?=23?(xi?+2), hence
?o?xi∣xi=1=92=4.5\frac{\partial o}{\partial x_i}\bigr\rvert_{x_i=1} = \frac{9}{2} = 4.5?xi??o?∣∣?xi?=1?=29?=4.5.
還可以用 autograd 做很事情
x = torch.randn(3, requires_grad=True)y = x * 2 while y.data.norm() < 1000:y = y * 2print(y) tensor([ 786.6164, 1688.7915, 530.0458], grad_fn=<MulBackward0>) gradients = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float) y.backward(gradients)print(x.grad) tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])你可以通過將代碼放在 with torch.no_grad(),來停止對從跟蹤歷史中的 .requires_grad=True 的張量自動求導(dǎo)。
print(x.requires_grad) print((x ** 2).requires_grad)with torch.no_grad():print((x ** 2).requires_grad) True True False總結(jié)
- 上一篇: 深度学习100例 | 第53天:用YOL
- 下一篇: 如何快将数据集划分为train、val(