目录
在OpenAI联合创始人Andrej Karpathy的教程<The spelled-out intro to language modeling: building makemore>中,提到了函数torch.multinomial()。这个函数形式如下:
torch.multinomial(input, num_samples, replacement=False, *, generator=None, out=None)
参数解释
input
input是一个tensor,我们用下面的例子解释input的意义:
想象n个小球,排成一行。小球按照排列次序,依次编号为0,1,2...n-1。我们随机从中取一个小球,取到i号小球的几率是p(i)。那么p(i)可以排成一个数列。p(0),p(1),p(2)......p(n-1)
把input的任一行想象成n个小球,元素i表示i号小球被取到的概率。假如有很多行这样的小球排成阵列,则input也就变成了一个tensor。
num_samples
我们可以把一行里所有的n个小球取出来,也可以只取一部分。取小球的数量等于num_samples
replacement
replacement是布尔型,可以是True或者False。默认值false
true含义
我们把一个小球取出后,可以再放回去,下次还可能再摸出来。
true的情况下,num_sample的取值可以大于input的列数,因为同一个球可以被重复抓取。
false含义
取出小球后,不再放回去。
注意,假如replacement=false,那么num_samples必须小于等于input的列数。原因如下:既然在false情况下,每抓一次小球就少一个,那么抓取的小球数num_samples肯定不能超过input的列数,因为input列数就是一行的小球总数。
generator与out--略
返回值
返回一个tensor。tensor的行数与input的行数相同--有多少行小球,返回值就有多少行。返回值的列数等于num_samples。返回值的每一行描述对该行小球进行num_samples 次抓取的结果:抓取的第一个球是几号、第二号球是几号、....直到抓完第num_samples个小球是几号。返回值的每一行的抓取结果,遵循input对应行的概率分布。
显然,每一次抓取的结果是随机的,所以调用一次multinomial函数的结果也是随机的。但是大量重复调用multinomial函数之后,统计其返回值,你会发现统计规律。
示例
示例1 replacement=True
返回值r的各个元素,表示被抓的小球的编号。比如[3,2,2]表示第一次抓取3号球,第二次抓取2号,第三次还是抓2号。
我们仔细看一下最后一次抓取的结果:抓取30次,共出现3次0,这正与0号球的被抓概率10%相符(p=[1,0,5,4] 故0号元素的概率是1/(1+0+5+4)=10%)。
2出现16次,16/30 = 53.3% 2号球概率是p[2]/(1+0+5+4)=50% 两者基本相符
3出现11次,11/30=36.7% 3号球概率是p[3]/(1+0+5+4)=40% 基本相符
示例2 replacement=False
可见,在replacement=false时,抓取次数不能超过input的列数。其实在num_samples=4时,就已经不对了:r=torch.multinomial(p,4,False)
既然p[1]=0,说明1号球根本不可能被抓到。但是因为抓取次数必须是4,所以在2号,0号,3号抓完之后,只剩1号球可抓。所以返回了[2,0,3,1]