『PyTorch x TensorFlow』第八彈_基本nn.Module層函數


『TensorFlow』網絡操作API_上  

『TensorFlow』網絡操作API_中

『TensorFlow』網絡操作API_下

之前也說過,tf 和 t 的層本質區別就是 tf 的是層函數,調用即可,t 的是類,需要初始化后再調用實例(實例都是callable的)

 

卷積

tensorflow.nn.conv2d

import tensorflow as tf

sess = tf.Session()
input = tf.Variable(tf.random_normal([1,3,3,5]))

# 卷積核尺寸*2,輸入通道,輸出通道,
filter = tf.Variable(tf.random_normal([1,1,5,1])) # 《-----卷積核初始化

conv = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')

sess.run(tf.global_variables_initializer())
print(sess.run(conv).shape)
(1, 3, 3, 1)

torch.nn.Conv2d

troch集成了初始化核的部分,所以自行初始化時需要直接修改變量的data

本篇很多例子中都對module的屬性直接操作,其大多數是可學習參數,一般會隨着學習的進行而不斷改變。實際使用中除非需要使用特殊的初始化,應盡量不要直接修改這些參數。

import torch as t
input = t.normal(means=t.zeros([1,5,3,3]), std=t.Tensor([0.1]).expand([1,5,3,3]))
input = t.autograd.Variable(input)

# 輸入通道,輸出通道,卷積核尺寸,步長,是否偏執
conv = t.nn.Conv2d(5, 1, (1, 1), 1, bias=False)

# 輸出通道,輸入通道,卷積核尺寸*2
print([n for n,p in conv.named_parameters()])
conv.weight.data = t.ones([1,5,1,1]) # 《-----卷積核初始化,可有可無

out = conv(input)
print(out.size())
['weight']
torch.Size([1, 1, 3, 3])

 

池化

tensorflow.nn.avg_pool

torch.nn.AvgPool2d

可以驗證沒有學習參數

pool = nn.AvgPool2d(2,2)
list(pool.parameters())
[]

 

線性

torch.nn.Linear

# 輸入 batch_size=2,維度3
input = V(t.randn(2, 3))
linear = nn.Linear(3, 4)
h = linear(input)
print(h)
Variable containing:
-1.4189 -0.2045  1.2143 -1.5404
 0.8471 -0.3154 -0.5855  0.0153
[torch.FloatTensor of size 2x4]

 

BatchNorm

『TensorFlow』批處理類

torch.nn.BatchNorm1d

BatchNorm:批規范化層,分為1D、2D和3D。除了標准的BatchNorm之外,還有在風格遷移中常用到的InstanceNorm層。

# 4 channel,初始化標准差為4,均值為0
bn = nn.BatchNorm1d(4)
print([n for n,p in bn.named_parameters()])
bn.weight.data = t.ones(4) * 4
bn.bias.data = t.zeros(4)

bn_out = bn(h)
# 注意輸出的均值和方差
# 方差是標准差的平方,計算無偏方差分母會減1
# 使用unbiased=False 分母不減1
bn_out.size(), bn_out.mean(0), bn_out.var(0, unbiased=False)
['weight', 'bias']
(torch.Size([2, 4]), 

Variable containing: 1.00000e-06 * 0.0000 -1.0729 0.0000 0.1192 [torch.FloatTensor of size 4],

Variable containing: 15.9999 15.9481 15.9998 15.9997 [torch.FloatTensor of size 4])

 

Dropout

tensorflow.nn.dropout

torch.nn.Dropout

dropout層,用來防止過擬合,同樣分為1D、2D和3D。 下面通過例子來說明它們的使用。

 # 每個元素以0.5的概率舍棄
dropout = nn.Dropout(0.5)
o = dropout(bn_out)
o # 有一半左右的數變為0
Variable containing:
-7.9895 -7.9931  7.9991  7.9973
 0.0000  0.0000 -7.9991 -7.9973
[torch.FloatTensor of size 2x4]

 

激活函數

PyTorch實現了常見的激活函數,其具體的接口信息可參見官方文檔^3,這些激活函數可作為獨立的layer使用。這里將介紹最常用的激活函數ReLU,其數學表達式為:

relu = nn.ReLU(inplace=True)
input = V(t.randn(2, 3))
print(input)
output = relu(input)
print(output) # 小於0的都被截斷為0
# 等價於input.clamp(min=0)
Variable containing:
-0.8472  1.0046  0.7245
 0.3567  0.0032 -0.5200
[torch.FloatTensor of size 2x3]

Variable containing:
 0.0000  1.0046  0.7245
 0.3567  0.0032  0.0000
[torch.FloatTensor of size 2x3]

有關inplace:

ReLU函數有個inplace參數,如果設為True,它會把輸出直接覆蓋到輸入中,這樣可以節省內存/顯存。之所以可以覆蓋是因為在計算ReLU的反向傳播時,只需根據輸出就能夠推算出反向傳播的梯度。但是只有少數的autograd操作支持inplace操作(如variable.sigmoid_()),除非你明確地知道自己在做什么,否則一般不要使用inplace操作。

 

交叉熵

import torch as t
from torch.autograd import Variable as V

score = V(t.randn(3,2))
label = V(t.Tensor([1,0,1])).long()
loss_fn = t.nn.CrossEntropyLoss()
loss = loss_fn(score,label)
print(loss)

Variable containing:
 1.3535
[torch.FloatTensor of size 1]

損失函數和nn.Module的其他class沒什么不同,不過實際使用時往往單獨提取出來(書上語)。

 

ReLU(x)=max(0,x)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM