requires_gard 是tensor變數的乙個屬性,一般預設為false。另外,0.4.0版本的 pytorch 將 variable 和 tensor 合併,統稱為 tensor,在過去的版本中,requires_grad屬性是variable封裝的屬性按照以下格式實驗:
w1 = torch.tensor([2
])#認為w1 與 w2 是函式f1 與 f2的引數
w1 = variable(w1,requires_grad=
true
)w2 = torch.tensor([2
])w2 = variable(w2,requires_grad=
true
)x2 = torch.rand(1)
x2 = variable(x2,requires_grad=
true
)y2 = x2**w1 # f1 運算
z2 = w2*y2+
1# f2 運算
z2.backward(
)print
(x2.grad)
print
(y2.grad)
print
(w1.grad)
print
(w2.grad)
發現 x2.grad,w1.grad,w2.grad 是個值 ,但是 y2.grad 卻是 none, 說明x2,w1,w2的梯度保留了,y2 的梯度獲取不到。實際上,仔細想一想會發現,x2,w1,w2均為葉節點。在這棵計算樹中 ,x2 與w1 是同一深度(底層)的葉節點,y2與w2 是同一深度,w2 是單獨的葉節點,而y2 是x2 與 w1 的父節點,所以只有y2沒有保留梯度值, 印證了之前的說法。同樣這也說明,計算圖本質就是乙個類似二叉樹的結構。
那麼對於 兩個網路,會是怎麼樣呢?我使用pytorch 的cifar10 例程,稍作改動做了實驗。把例程中使用的乙個 alexnet 拆成了兩個net ------ net1 和 net2 。
optimizer = torch.optim.sgd(itertools.chain(net1.parameters(
), net2.parameters())
,lr=
0.001
, momentum=
0.9)
# 這裡 net1 和net2 優化的先後沒有區別 !!
#optimizer.zero_grad(
)#將引數的grad值初始化為0
## forward + backward + optimize
outputs1 = net1(inputs)
#input 未置requires_grad為true,但不影響
outputs2 = net2(outputs1)
loss = criterion(outputs2, labels)
#計算損失
loss.backward(
)#反向傳播
#print
("inputs.requires_grad:"
)print
(inputs.requires_grad)
# false
print
("the grad of inputs:"
)print
(inputs.grad)
# none
print
("outputs1.requires_grad:"
)print
(outputs1.requires_grad)
# true
print
("the grad of outputs1:"
)print
(outputs1.grad)
# none
#print
("the grad of net1:"
)print
(net1.conv1.bias.grad)
# no-none
print
("the grad of net2:"
)print
(net2.fc3.bias.grad)
# no-none
#optimizer.step(
)#用sgd更新引數
字尾注釋就是列印的結果。可以看出,只有網路引數的grad是直接可獲取的。而且是兩個網路都可以獲取grad 值,獲取grad後,當然就可以更新網路的引數了,兩個網路都是可以更新的。
模擬上邊例子的解釋,兩個網路其實就是處在葉節點的位置,只不過深度不同。同理,網路內部的運算,每一層網路權重引數其實也是處在葉節點上,只不過在樹中的深度不同罷了,前向運算時按照二叉樹的結構,不斷生成父節點。
事實上,原先是以為 網路 與 普通函式不同,因為它具有register_xx_hook()這個類函式工具,所以認為它可以預設儲存權重引數的grad來用於更新,後來才明白,本質上與普通函式的引數一樣,都是處在葉節點,就可以儲存引數的grad,至於register_xx_hook(),看來是另做它用,或者說用register_xx_hook()可以記錄甚至更改中間節點的grad值。
如果想把網路某一部分引數固定,不讓其被訓練,可以使用requires_grad.
for p in sub_module.parameters():
p.requires_grad =
false
可以這樣理解,因為是葉節點(而不是中間節點),所以不求grad(grad為』none』),也不會影響網路的正常反向傳播 關於熵的一些理解
對於理工科學生來說,熵 並不是乙個陌生的名詞。在諸如 大學物理 熱力學 和 資訊理論 等課程中都會有所介紹。但同時 熵 又是乙個顯得有點神秘的概念,看不見也摸不著。我最早是在高中物理課中聽說的,大概是在介紹 熱力學第二定律 時提到的。熱力學第二定律的內容是 熱力學過程是不可逆的 孤立系統自發地朝著熱...
關於float的一些理解
float是否脫離文件流,乙個父元素不設定overflow的話,子元素float,就不會把父元素撐開,換句話說,他就不會有高度,但是做個demo 父元素overflow hidden 子元素前兩個float,第三個不float,結果是第三個沒有clear浮動的元素,跟float的元素出現在同乙個位置...
關於android layout的一些理解
1 wrap content view的尺寸根據它的內容確定 match parent view的尺寸盡量和它的parent view group一樣大 2 獲得view的位置 position getleft gettop getright getleft getwidth getwidth 3 ...