文章目录
PyTorch 中的 dropout
1. Pytoch 说明文档官网 PyTorch documentation 链接
1.1. torch.nn
中的 dropout
1.1.1. torch.nn.Dropout (Python class, in Dropout)
将输入的每个数值按(伯努利分布)概率赋值为0。即部分数值赋值为0。
import torch
import torch.nn as nn
import torch.nn.functional as F
def run1nn():
input_ = torch.randn(4, 2)
m = nn.Dropout(p=0.5)
# m = nn.AlphaDropout(p=0.5)
output = m(input_)
print("input_ = \n", input_)
print("output = \n", output)
输出如下(部分数值赋值为0):
input_ =
tensor([[-1.1293, -1.2553],
[-0.7586, 0.3034],
[ 1.6672, -0.6755],
[-1.8980, 1.1677]])
output = # 部分数值赋值为0。
tensor([[-0.0000, -0.0000],
[-1.5172, 0.6068],
[ 0.0000, -0.0000],
[-3.7961, 0.0000]])
1.1.2. torch.nn.AlphaDropout (Python class, in AlphaDropout)
当输入数据满足均值为 0 的正太分布时,在将部分数值按(伯努利分布)概率赋值为0的同时,保持输出数据的概率分布与输入数据的概率分一致。即先将部分数值赋值为0,再调整所有数值的值来保证分布不变。
def run1nn():
input_ = torch.randn(4, 2)
# m = nn.Dropout(p=0.5)
m = nn.AlphaDropout(p=0.5)
output = m(input_)
print("input_ = \n", input_)
print("output = \n", output)
输出如下(先将部分数值赋值为0,再调整所有数值的值来保证分布不变):
input_ =
tensor([[-3.1806, 0.2888],
[ 0.1620, -0.0531],
[ 0.2369, 1.2116],
[-0.7322, 0.5835]])
output = # 先将部分数值赋值为0,再调整所有数值的值来保证分布不变。
tensor([[-0.7792, 1.0352],
[ 0.9227, -0.7792],
[-0.7792, -0.7792],
[-0.7792, -0.7792]])
1.1.3. torch.nn.Dropout2d (Python class, in Dropout2d)
Dropout2d
的赋值对象是彩色的图像数据(batch N,通道 C,高度 H,宽 W)的一个通道里的每一个数据,即输入为 Input: (N, C, H, W)
时,对每一个通道维度 C 按概率赋值为 0。
def run_2d():
input_ = torch.randn(2, 3, 2, 4)
m = nn.Dropout2d(p=0.5, inplace=False)
output = m(input_)
print("input_ = \n", input_)
print("output = \n", output)
输出结果如下(对每一个通道维度 C 按概率赋值为 0。):
input_ =
tensor([[[[ 0.4218, -0.6617, 1.0745, 1.2412],
[ 0.2484, 0.6037, 0.3462, -0.4551]],
[[-0.9153, 0.8769, -0.7610, -0.7405],
[ 0.1170, -0.8503, -1.0089, -0.5192]],
[[-0.6971, -0.9892, 0.1342, 0.1211],
[-0.3756, 1.9225, -1.0594, 0.1419]]],
[[[-1.2856, -0.3241, 0.2331, -1.5565],
[ 0.6961, 1.0746, -0.9719, 0.5585]],
[[-0.1059, -0.7259, -0.4028, 0.1968],
[ 0.8201, -0.0833, -1.2811, 0.1915]],
[[-0.2207, 0.3850, 1.4132, 0.8216],
[-0.1313, 0.2915, 0.1996, 0.0021]]]])
output =
tensor([[[[ 0.8436, -1.3234, 2.1489, 2.4825],
[ 0.4968, 1.2073, 0.6924, -0.9101]],
[[-1.8305, 1.7537, -1.5219, -1.4810],
[ 0.2340, -1.7006, -2.0178, -1.0385]],
[[-0.0000, -0.0000, 0.0000, 0.0000],
[-0.0000, 0.0000, -0.0000, 0.0000]]],
[[[-0.0000, -0.0000, 0.0000, -0.0000],
[ 0.0000, 0.0000, -0.0000, 0.0000]],
[[-0.2118, -1.4518, -0.8056, 0.3935],
[ 1.6401, -0.1667, -2.5622, 0.3830]],
[[-0.0000, 0.0000, 0.0000, 0.0000],
[-0.0000, 0.0000, 0.0000, 0.0000]]]])
1.1.4. torch.nn.Dropout3d (Python class, in Dropout3d)
Dropout2d
的赋值对象是彩色的点云数据(batch N,通道 C,深度 D,高度 H,宽 W)的一个通道里的每一个数据,即输入为 Input: (N, C, D, H, W) 时,对每一个通道维度 C 按概率赋值为 0。。
Dropout3d
和 Dropout2d
的效果相似,都是对通道维度上按概率将整个通道中的所有数值赋值为 0。
def run_3d():
input_ = torch.randn(2, 2, 2, 4)
m = nn.Dropout3d(p=0.1, inplace=False)
output = m(input_)
# print("input_ = \n", input_)
print("output = \n", output)
输出结果如下:
output =
tensor([[[[ 1.1761, 1.1794, 0.1044, -2.9451],
[-1.0795, 0.1167, 0.8323, 0.0750]],
[[ 0.0000, -0.0000, 0.0000, -0.0000],
[-0.0000, 0.0000, 0.0000, -0.0000]]],
[[[-1.8938, -1.9509, 2.2817, 2.7738],
[-0.0378, 3.2422, -1.0612, -0.7103]],
[[ 0.0319, -1.9631, -0.5589, -0.5544],
[ 0.0643, 0.5834, 1.8123, 0.2383]]]])
1.2. torch.nn
和 torch.nn.functional
中的 dropout
功能相同。
torch.nn.functional.dropout (Python function, in torch.nn.functional)
torch.nn.functional.alpha_dropout (Python function, in torch.nn.functional)
torch.nn.functional.dropout2d (Python function, in torch.nn.functional)
torch.nn.functional.dropout3d (Python function, in torch.nn.functional)
torch.nn.functional.feature_alpha_dropout (Python function, in torch.nn.functional)
2. [知乎:PyTorch 中,nn 与 nn.functional 有什么区别?] (https://www.zhihu.com/question/66782101)
详细区别见上面的知乎链接,这里用一个简单的例子说明:
nn
里的nn.dropout()
是类(先传参实例化,后传入数据使用),nn.functional
里的nn.functional.dropout()
是函数(直接传入数据使用)。
下面是两种 dropout
的使用方法,具体使用区别见知乎:https://www.zhihu.com/question/66782101
import torch
import torch.nn as nn
import torch.nn.functional as F
def run1nn():
input_ = torch.randn(2, 3)
m = nn.Dropout(p=0.5)
output = m(input_)
print("input_ = \n", input_)
print("output = \n", output)
def run2F():
input_ = torch.randn(2, 3)
output = F.dropout(input_, p=0.5)
print("input_ = \n", input_)
print("output = \n", output)
if __name__ == "__main__":
run1nn()
run2F()