uniform分布_PyTorch入门笔记创建已知分布的张量

6d71d7f489907bdeb7523a7e6f758e29.png 关注"AI机器学习与深度学习算法"公众号 选择" 星标 "公众号,原创干货,第一时间送达

创建已知分布的张量

正态分布(Normal Distribution)和均匀分布(Uniform Distribution)是最常见的分布之一,创建采样自这 2 个分布的张量非常有用,「比如在卷积神经网络中,卷积核张量 初始化为正态分布有利于网络的训练;在对抗生成网络中,隐藏变量 一般采样自均匀分布。」

通过torch.normal(mean,std,generator=None,out=None)可以创建均值为 mean,标准差为 std 的正态分布 ,先来简单看一看这些参数:

  • mean(Tensor) - 传入参数 mean 的张量中的每个元素都是对应输出元素的正态分布的均值;
  • std(Tensor) - 传入参数 std 的张量中的每个元素都是对应输出元素的正态分布的标准差;
  • generator = None(torch.Generator, optional) - 用于采样的伪随机数,可以暂时不用关注;
  • out = None(Tensor, optional) - 指定输出的张量。比如执行torch.normal(mean = torch.tensor(0.), std = torch.tensor(1.), out = tensor_a),相当于执行tensor_a = torch.normal(mean = torch.tensor(0.), std = torch.tensor(1.))

torch.normal(mean,std,generator=None,out=None)函数传入的 mean 和 std 参数的两个张量的形状不一定要匹配,但是这两个张量中的元素总个数必须相等,「这里需要注意此时两个张量中的元素总个数必须相等不仅仅包括显式的相等,还包含隐式的相等。」

  • 显式相等非常好理解,简单来说就是传入张量的元素总个数相等。比如传入参数 mean 的张量形状为 [1, 4],那么传入参数 std 的张量形状必须是  [1, 4]、[2, 2]、[4, 1] 中的任意一个,必须满足 mean.numel() == std.numel()(tensor.numel() 函数返回 tensor 中的元素个数);
  • 隐式相等其实就是 PyTorch 中的广播机制,PyTorch 中的广播机制和 TensorFlow 以及 Numpy 中的广播机制类似。比如传入参数 mean 的张量形状为 [1, 2],而传入参数 std 的张量形状为 [2, 2],PyTorch 会根据广播机制的规则将传入 mean 参数的张量形状广播成 [2, 2]。「虽然传入的两个张量元素总个数不相等,但是通过 PyTorch 中的广播机制可以将符合广播机制的张量扩展成相同元素总个数的两个张量;」
>>> import torch
>>> # 传入mean和std的两个张量:
>>> #   1. 形状不匹配
>>> #   2. 两个张量中的元素个数显式相等
>>> normal_a = torch.normal(mean = torch.full([1, 4], 0.),std = torch.full([2, 2], 1.))
>>> print(normal_a.size())
torch.Size([1, 4])

>>> print(normal_a)
tensor([[-1.7489, -1.4797,  1.1246,  0.4521]])

>>> # 传入mean和std的两个张量:
>>> #   1. 形状不匹配
>>> #   2. 两个张量中的元素个数显式不相等,但是符合广播机制的规则
>>> normal_b = torch.normal(mean = torch.full([1, 2], 0.),std = torch.full([2, 2], 1.))
>>> print(normal_b.size())
torch.Size([2, 2])

>>> print(normal_b)
tensor([[-1.1370, -1.1644],
        [-1.5242, -0.9315]])

>>> # 传入mean和std的两个张量:
>>> #   1. 形状不匹配
>>> #   2. 两个张量中的元素个数显式不相等,且不符合广播机制的规则
>>> #   程序会报错error
>>> # normal_c = torch.normal(mean = torch.full([1, 3], 0.),
>>> #                         std = torch.full([2, 2], 1.))

PyTorch 的官方文档中强调:"当输入参数 mean 和 std 的张量形状不匹配的时候,输出张量的形状由传入 mean 参数的张量形状所决定。"通过前面的介绍后这句话非常好理解,因为不管传入 mean 和 std 参数的张量形状如何,只要代码正确,最终都会被转换为相同的形状。

不过有可能会有 UserWarning 的警告(我的 PyTorch 为 1.5),这个警告因为 torch.normal(mean = torch.full((1, 4), 0.),std = torch.full((2, 2), 1.)) 代码段,「这是因为当传入的两个张量形状不匹配,但是元素总个数相等的情况下,PyTorch 会使用 reshape 函数将传入参数 std 的张量形状改变成和传入 mean 参数张量相同的形状,这可能会引发一些问题,所以在 PyTorch 1.6 以后的版本这种方法将会舍弃,这里只需要注意一下即可。」

通过torch.randint(low=0,high,size,generator=None,out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False)函数能够创建采样自 [low, high) 区间(包左不包右)的均匀分布的张量,函数中的很多参数都介绍过,这里不再赘述,这里只关注 low 和 high 两个参数。

  • low(int, optional) - 从均匀分布中采样的最小整数,默认为 0;
  • high(int) - 从均匀分布中采样的最大整数,不包括最大整数;
>>> import torch
>>> # 创建采样自[1, 10)均匀分布的0D张量
>>> scalar_a = torch.randint(1, 10, ())
>>> print(scalar_a.size())
torch.Size([])

>>> print(scalar_a)
tensor(4)

>>> # 创建采样自[2, 5)均匀分布的1D张量
>>> vec_b = torch.randint(2, 5, (3, ))
>>> print(vec_b.size())
torch.Size([3])

>>> print(vec_b)
tensor([2, 2, 2])

>>> # 创建采样自[0, 10)均匀分布的2D张量
>>> mat_c = torch.randint(10, (2, 2))
>>> print(mat_c.size())
torch.Size([2, 2])

>>> print(mat_c)
tensor([[3, 8],
        [4, 2]])

通过torch.randint(low,high,size)函数创建采样自 [low, high) 均匀分布的 0D 张量、1D 张量和 2D 张量,创建 nD 张量与之类似,这里不再赘述。*size 参数指定创建张量的形状。

torch.normal() 函数相对比较复杂,而 torch.randint() 函数和前面介绍的函数类似,只不过需要指定采样的区间范围。针对比较常见的标准正态分布和采样自 [0, 1)区间的均匀分布,PyTorch 又提供了torch.randn(*size,out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False)torch.rand(*size,out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False)两个函数。

>>> import torch
>>> # 创建采样自均值0.标准差1.正态分布的2D张量
>>> # 等价torch.normal(mean = torch.full([2, 2], 0.)
>>> #                 std = torch.full([2, 2], 1.))
>>> normal_a = torch.randn([2, 2])
>>> print(normal_a)
tensor([[-0.4471, -0.2377],
        [ 0.6442, -0.1024]])

>>> # 创建采样自[0, 1)均匀分布的2D张量
>>> # !不等价torch.randint(0, 1, [2, 2])
>>> uniform_b = torch.rand([2, 2])
>>> print(uniform_b)
tensor([[0.9690, 0.6938],
        [0.1431, 0.4861]])

还有一点需要注意:「torch.randint() 函数只能采样指定范围均匀分布的整数,而 torch.rand() 函数能够采样 [0, 1) 范围内均匀分布的浮点数,如果你想要采样自指定范围内的浮点数,可以使用 torch.rand() 函数进行改造,不过最简单的方法就是使用torch.nn.init.uniform_(tensor,a=0.0,b=1.0)函数。」

比如创建一个采样自 [2, 10) 范围均匀分布且形状为 [2, 2] 的 2D 张量。

>>> import torch
>>> uniform_c = torch.FloatTensor(2, 2).uniform_(2, 10)
>>> print(uniform_c)
tensor([[8.9692, 6.4037],
        [4.4121, 7.0056]])

aca4a6ee4a36e23ae8397dc646d7ff5a.png

Tips:

  1. 增添了自己的理解与看法 

  2. 龙良曲深度学习与PyTorch入门实战:https://study.163.com/course/introduction/1208894818.htm

a64274d0c77965b9d350fd227ffb3414.png

5f627b1a4cdc047c92c220f2aa1fb45d.png

【PyTorch入门笔记】简单回归案例实战

【PyTorch入门笔记】手写数字问题

【PyTorch入门笔记】基本数据类型

【PyTorch入门笔记】从数组、列表对象中创建Tensor

【Numpy模块】Numpy中常用随机函数的总结

【机器学习入门笔记】什么是决策树?

2c19d4b15dc091fa40c44f4eee655456.png

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值