[{"data":1,"prerenderedAt":3119},["ShallowReactive",2],{"content-query-rlQVOJ0oF5":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"cover":11,"type":12,"body":13,"_type":3113,"_id":3114,"_source":3115,"_file":3116,"_stem":3117,"_extension":3118},"/technology-blogs/zh/326","zh",false,"","MindSpore概率采样库系列（一）：手把手教你开发概率分布","MindSpore概率采样库系列第一篇~","2020-11-06","https://obs-mindspore-file.obs.cn-north-4.myhuaweicloud.com/file/2020/11/06/665c664a7c9d45abbfda93f2ccbd95ba.png","technology-blogs",{"type":14,"children":15,"toc":3089},"root",[16,24,30,35,40,46,51,56,100,105,116,222,228,338,363,372,436,443,518,570,581,589,600,652,663,669,685,726,747,753,809,815,910,916,964,969,997,1002,1122,1146,1154,1180,1188,1214,1222,1233,1241,1246,1272,1280,1296,1304,1341,1349,1355,1486,1491,1641,1648,1691,1699,1833,1864,1870,1965,1973,1998,2013,2021,2091,2199,2207,2211,2307,2519,2577,2588,2596,2604,2616,2624,2666,2672,2685,2758,2766,2804,2812,2841,2849,2866,2873,2878,2886,2898,2906,2912,2971,2979,2991,2999,3017,3025,3030,3038,3043,3051,3056,3067],{"type":17,"tag":18,"props":19,"children":21},"element","h1",{"id":20},"mindspore概率采样库系列一手把手教你开发概率分布",[22],{"type":23,"value":8},"text",{"type":17,"tag":25,"props":26,"children":27},"p",{},[28],{"type":23,"value":29},"MindSpore概率采样库系列共有两篇",{"type":17,"tag":25,"props":31,"children":32},{},[33],{"type":23,"value":34},"1.手把手教你开发概率分布",{"type":17,"tag":25,"props":36,"children":37},{},[38],{"type":23,"value":39},"2.手把手教你开发概率映射",{"type":17,"tag":41,"props":42,"children":44},"h2",{"id":43},"概率分布",[45],{"type":23,"value":43},{"type":17,"tag":25,"props":47,"children":48},{},[49],{"type":23,"value":50},"为了描述生活中的各种随机事件，数学家提出了随机变量的概念。随机变量的值是不确定的，但是他们取不同值的可能性满足一定的概率分布。我们可以用一些函数描述一个随机变量的不同输出值的可能性，比如概率密度函数描述这个随机变量的输出值在某个确定的取值点附近的可能性，以及累计分布函数描述这个随机变量的输出值不大于某个确定的取值点的可能性。另外，我们可以用一些统计量去描述一个随机变量的某些高度概括的概率性质，比如期望(mean)是随机变量所有可能输出值的概率乘以其结果的总和，以及众数（mode）指一组数据中出现次数最多的数据值。",{"type":17,"tag":25,"props":52,"children":53},{},[54],{"type":23,"value":55},"概率分布是一个随机变量的概率性质的数学抽象，包括我们可以对随机变量所有可以做的操作和计算，比如给定一个输出值计算对应的概率，又如从随机分布中取一个样本。概率分布是深度概率编程的基础。例如在前文中提到的变分自编码器，当从隐向量空间解码时，我们需要对一个高斯分布进行中随机采样，从而生成一个向量作为解码器的输入。而在最后做优化的时候，我们要计算两个概率分布的KL散度作为优化的目标之一。",{"type":17,"tag":25,"props":57,"children":58},{},[59,65,67,71,73,77,79,84,86,91,93,98],{"type":17,"tag":60,"props":61,"children":62},"strong",{},[63],{"type":23,"value":64},"Mindspore",{"type":23,"value":66}," 中为用户提供了概率分布采用库，其中包括了多样的基础概率分布及其基本函数计算，也为 ",{"type":17,"tag":60,"props":68,"children":69},{},[70],{"type":23,"value":64},{"type":23,"value":72}," 的贝叶斯概率网络建模能力提供了基础。今天向大家介绍 ",{"type":17,"tag":60,"props":74,"children":75},{},[76],{"type":23,"value":64},{"type":23,"value":78}," 里的概率分布基类 ",{"type":17,"tag":60,"props":80,"children":81},{},[82],{"type":23,"value":83},"Distribution",{"type":23,"value":85},", 并以 ",{"type":17,"tag":60,"props":87,"children":88},{},[89],{"type":23,"value":90},"Laplace",{"type":23,"value":92}," 分布为例，教大家如何给",{"type":17,"tag":60,"props":94,"children":95},{},[96],{"type":23,"value":97},"MindSpore",{"type":23,"value":99},"增加一个概率分布。",{"type":17,"tag":41,"props":101,"children":103},{"id":102},"前期准备",[104],{"type":23,"value":102},{"type":17,"tag":25,"props":106,"children":107},{},[108,110,114],{"type":23,"value":109},"为了开发一个概率分布，我们需要做一些前期的准备。以本文介绍的 ",{"type":17,"tag":60,"props":111,"children":112},{},[113],{"type":23,"value":90},{"type":23,"value":115}," 分布为例，开发前我们需要了解他的一些数学性质，包括：",{"type":17,"tag":117,"props":118,"children":119},"ol",{},[120,132,152,185],{"type":17,"tag":121,"props":122,"children":123},"li",{},[124,126,130],{"type":23,"value":125},"参数形式。一个概率分布可能是由多种参数形式的。例如对于一个指数分布，我们可以使用 rate 作为参数，也可以用 rate 的倒数 scale 作为参数来描述这个分布。这里我们选择 ",{"type":17,"tag":60,"props":127,"children":128},{},[129],{"type":23,"value":90},{"type":23,"value":131}," 分布的 loc 和 scale 作为参数描述这个分布的性质。",{"type":17,"tag":121,"props":133,"children":134},{},[135,137,141,143,150],{"type":23,"value":136},"分布函数。在确定了参数表达之后，我们需要了解在如此参数设定下，概率分布的相关分布函数的表达式，例如概率密度函数，累计分布函数，生存函数等等。以 ",{"type":17,"tag":60,"props":138,"children":139},{},[140],{"type":23,"value":90},{"type":23,"value":142}," 分布为例，当我们确定了他的参数为 loc 和 scale 后，我们可以确定他的概率密度函数的表达式为 ",{"type":17,"tag":144,"props":145,"children":147},"code",{"className":146},[],[148],{"type":23,"value":149},"f(x) = 1/(2 * scale) exp(-|x - loc| / scale)",{"type":23,"value":151}," 。",{"type":17,"tag":121,"props":153,"children":154},{},[155,157,161,163,167,169,175,177,183],{"type":23,"value":156},"统计量的计算。对于一些常用的统计量，例如期望和方差，我们需要了解在我们参数设定下如何去计算他们。以 ",{"type":17,"tag":60,"props":158,"children":159},{},[160],{"type":23,"value":90},{"type":23,"value":162}," 分布为例，当我们确定了他的参数为 loc 和 scale 后， ",{"type":17,"tag":60,"props":164,"children":165},{},[166],{"type":23,"value":90},{"type":23,"value":168}," 分布的期望为 ",{"type":17,"tag":144,"props":170,"children":172},{"className":171},[],[173],{"type":23,"value":174},"loc",{"type":23,"value":176},"，而方差为 ",{"type":17,"tag":144,"props":178,"children":180},{"className":179},[],[181],{"type":23,"value":182},"2*scale^2",{"type":23,"value":184}," .",{"type":17,"tag":121,"props":186,"children":187},{},[188,190,196,198,204,206,212,214,220],{"type":23,"value":189},"抽样方法。如何从一个概率分布中抽样一直是一个重要的研究课题。高效的抽样能让有效的帮助模型的训练和推理。对于连续性分布，我们可以采用如下抽样方法：假设",{"type":17,"tag":144,"props":191,"children":193},{"className":192},[],[194],{"type":23,"value":195},"F(x)",{"type":23,"value":197},"是某个分布的累计分布函数，那么如果",{"type":17,"tag":144,"props":199,"children":201},{"className":200},[],[202],{"type":23,"value":203},"u",{"type":23,"value":205},"是一个来自均匀分布",{"type":17,"tag":144,"props":207,"children":209},{"className":208},[],[210],{"type":23,"value":211},"Uniform(0, 1)",{"type":23,"value":213},"的抽样，那么",{"type":17,"tag":144,"props":215,"children":217},{"className":216},[],[218],{"type":23,"value":219},"x = F^{-1}(u)",{"type":23,"value":221},"就是该分布的一个抽样。下面我们将采用这个抽样方法。",{"type":17,"tag":41,"props":223,"children":225},{"id":224},"构建函数-constructor",[226],{"type":23,"value":227},"构建函数 (Constructor)",{"type":17,"tag":25,"props":229,"children":230},{},[231,233,237,239,244,246,251,253,257,259,264,266,271,273,278,280,285,287,291,293,297,299,304,306,310,312,317,319,323,325,330,332,336],{"type":23,"value":232},"在概率分布层中， ",{"type":17,"tag":60,"props":234,"children":235},{},[236],{"type":23,"value":83},{"type":23,"value":238}," 是所有概率分布的基类。通常来说，有两种类型的分布。第一种类型的概率分布，例如 ",{"type":17,"tag":60,"props":240,"children":241},{},[242],{"type":23,"value":243},"Normal",{"type":23,"value":245}," 和 ",{"type":17,"tag":60,"props":247,"children":248},{},[249],{"type":23,"value":250},"Uniform",{"type":23,"value":252},"， 他们直接继承 ",{"type":17,"tag":60,"props":254,"children":255},{},[256],{"type":23,"value":83},{"type":23,"value":258},"，初始化参数包括概率分布的特征参数 ",{"type":17,"tag":60,"props":260,"children":261},{},[262],{"type":23,"value":263},"dist_spec_args",{"type":23,"value":265},"，概率分布的类型 ",{"type":17,"tag":60,"props":267,"children":268},{},[269],{"type":23,"value":270},"dtype",{"type":23,"value":272}," 以及概率分布的名称 ",{"type":17,"tag":60,"props":274,"children":275},{},[276],{"type":23,"value":277},"name",{"type":23,"value":279},"。另一种概率分布继承自",{"type":17,"tag":60,"props":281,"children":282},{},[283],{"type":23,"value":284},"TransformedDistribution",{"type":23,"value":286},"。 ",{"type":17,"tag":60,"props":288,"children":289},{},[290],{"type":23,"value":284},{"type":23,"value":292}," 继承自 ",{"type":17,"tag":60,"props":294,"children":295},{},[296],{"type":23,"value":83},{"type":23,"value":298}," ，初始化参数包括一个 ",{"type":17,"tag":60,"props":300,"children":301},{},[302],{"type":23,"value":303},"Bijector",{"type":23,"value":305}," 和一个 ",{"type":17,"tag":60,"props":307,"children":308},{},[309],{"type":23,"value":83},{"type":23,"value":311},"，例如通过 ",{"type":17,"tag":60,"props":313,"children":314},{},[315],{"type":23,"value":316},"Exp",{"type":23,"value":318}," bijector 和 ",{"type":17,"tag":60,"props":320,"children":321},{},[322],{"type":23,"value":243},{"type":23,"value":324}," distribution 实现的 ",{"type":17,"tag":60,"props":326,"children":327},{},[328],{"type":23,"value":329},"LogNormal",{"type":23,"value":331}," 分布。 今天介绍的 ",{"type":17,"tag":60,"props":333,"children":334},{},[335],{"type":23,"value":90},{"type":23,"value":337}," 属于 第一种简单类型的概率分布。下面我们开始吧！",{"type":17,"tag":25,"props":339,"children":340},{},[341,343,347,349,353,355,361],{"type":23,"value":342},"首先我们新建一个继承自 ",{"type":17,"tag":60,"props":344,"children":345},{},[346],{"type":23,"value":83},{"type":23,"value":348}," 的名为 ",{"type":17,"tag":60,"props":350,"children":351},{},[352],{"type":23,"value":90},{"type":23,"value":354},"的派生类，定义 ",{"type":17,"tag":144,"props":356,"children":358},{"className":357},[],[359],{"type":23,"value":360},"__init__",{"type":23,"value":362}," 函数。",{"type":17,"tag":364,"props":365,"children":367},"pre",{"code":366},"class Laplace(Distribution):\n    def __init__(self,\n                loc=0.,\n                scale=1.,\n                dtype=mstype.float32,\n                name='Laplace'):\n",[368],{"type":17,"tag":144,"props":369,"children":370},{"__ignoreMap":7},[371],{"type":23,"value":366},{"type":17,"tag":25,"props":373,"children":374},{},[375,377,381,383,388,390,394,396,400,402,406,408,412,414,420,422,426,428,434],{"type":23,"value":376},"这里我们的参数包括 ",{"type":17,"tag":60,"props":378,"children":379},{},[380],{"type":23,"value":174},{"type":23,"value":382},", ",{"type":17,"tag":60,"props":384,"children":385},{},[386],{"type":23,"value":387},"scale",{"type":23,"value":389},", 是 ",{"type":17,"tag":60,"props":391,"children":392},{},[393],{"type":23,"value":90},{"type":23,"value":395}," 分布的特征参数 ",{"type":17,"tag":60,"props":397,"children":398},{},[399],{"type":23,"value":263},{"type":23,"value":401},"， 默认值为分别为0和1。分布类型",{"type":17,"tag":60,"props":403,"children":404},{},[405],{"type":23,"value":270},{"type":23,"value":407},"， 因为",{"type":17,"tag":60,"props":409,"children":410},{},[411],{"type":23,"value":90},{"type":23,"value":413}," 是连续分布，我们设置默认值为",{"type":17,"tag":144,"props":415,"children":417},{"className":416},[],[418],{"type":23,"value":419},"float32",{"type":23,"value":421},"。分布名称 ",{"type":17,"tag":60,"props":423,"children":424},{},[425],{"type":23,"value":277},{"type":23,"value":427}," 默认值为 ",{"type":17,"tag":144,"props":429,"children":431},{"className":430},[],[432],{"type":23,"value":433},"'Laplace'",{"type":23,"value":435},"。",{"type":17,"tag":437,"props":438,"children":440},"h4",{"id":439},"dist_spec_args-详解",[441],{"type":23,"value":442},"dist_spec_args 详解",{"type":17,"tag":25,"props":444,"children":445},{},[446,448,452,454,460,461,466,468,472,474,479,480,485,487,491,492,496,498,502,504,510,512,516],{"type":23,"value":447},"文中提到的",{"type":17,"tag":60,"props":449,"children":450},{},[451],{"type":23,"value":263},{"type":23,"value":453},"是某一分布的特征参数。例如，",{"type":17,"tag":455,"props":456,"children":457},"em",{},[458],{"type":23,"value":459},"mean",{"type":23,"value":245},{"type":17,"tag":455,"props":462,"children":463},{},[464],{"type":23,"value":465},"std",{"type":23,"value":467}," 可作为 ",{"type":17,"tag":60,"props":469,"children":470},{},[471],{"type":23,"value":243},{"type":23,"value":473}," 分布的特征参数，而 ",{"type":17,"tag":455,"props":475,"children":476},{},[477],{"type":23,"value":478},"rate",{"type":23,"value":467},{"type":17,"tag":60,"props":481,"children":482},{},[483],{"type":23,"value":484},"Expnential",{"type":23,"value":486}," 分布的特征参数。这里，",{"type":17,"tag":60,"props":488,"children":489},{},[490],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":60,"props":493,"children":494},{},[495],{"type":23,"value":387},{"type":23,"value":497}," 为 ",{"type":17,"tag":60,"props":499,"children":500},{},[501],{"type":23,"value":90},{"type":23,"value":503}," 的特征参数，他们可以是具体的数值，也可以是空值（",{"type":17,"tag":144,"props":505,"children":507},{"className":506},[],[508],{"type":23,"value":509},"None",{"type":23,"value":511},"）。 你可能有一个问题，既然 ",{"type":17,"tag":60,"props":513,"children":514},{},[515],{"type":23,"value":263},{"type":23,"value":517}," 是完整定义一个分布的必要值，为什么其值可以空呢？",{"type":17,"tag":25,"props":519,"children":520},{},[521,523,528,530,534,536,541,543,548,550,554,555,560,562,568],{"type":23,"value":522},"当一个概率分布的初始化特征某个参数为空时，此实例可理解为一个",{"type":17,"tag":60,"props":524,"children":525},{},[526],{"type":23,"value":527},"dummy distribution",{"type":23,"value":529},"。在概率编程中，很多时候，分布的特征参数跟其他函数有关或为变量， 此时，我们希望仅初始化分布的类型。因此我们支持",{"type":17,"tag":60,"props":531,"children":532},{},[533],{"type":23,"value":263},{"type":23,"value":535},"在初始化时为 ",{"type":17,"tag":144,"props":537,"children":539},{"className":538},[],[540],{"type":23,"value":509},{"type":23,"value":542},", 在调用具体函数时传入。需强调的是，",{"type":17,"tag":60,"props":544,"children":545},{},[546],{"type":23,"value":547},"为空的",{"type":23,"value":549}," ",{"type":17,"tag":60,"props":551,"children":552},{},[553],{"type":23,"value":263},{"type":23,"value":549},{"type":17,"tag":60,"props":556,"children":557},{},[558],{"type":23,"value":559},"必须在调用具体的函数时以 args 或者 kwargs的方式传入",{"type":23,"value":561},"，否则函数将报错。具体参考后面文章中对 ",{"type":17,"tag":144,"props":563,"children":565},{"className":564},[],[566],{"type":23,"value":567},"_check_param_type",{"type":23,"value":569}," 函数的讨论。",{"type":17,"tag":25,"props":571,"children":572},{},[573,575,579],{"type":23,"value":574},"有了",{"type":17,"tag":60,"props":576,"children":577},{},[578],{"type":23,"value":90},{"type":23,"value":580},"的类型定义，我们开始处理传入的参数吧！",{"type":17,"tag":364,"props":582,"children":584},{"code":583},"class Laplace(Distribution):\n    def __init__(self, loc=None， scale=None, dtype=mstype.float32, name='Laplace'):\n        param = dict(locals())\n        param['param_dict']={\"loc\": loc, \"scale\", scale}\n        valid_type = mstype.float_type\n        Validator.check_type(type(self.__name__), dtype, valid, type)\n        super(Laplace, self).__init__(seed, dtype, name, param)\n",[585],{"type":17,"tag":144,"props":586,"children":587},{"__ignoreMap":7},[588],{"type":23,"value":583},{"type":17,"tag":25,"props":590,"children":591},{},[592,594,598],{"type":23,"value":593},"在调用基类构造函数前，即",{"type":17,"tag":60,"props":595,"children":596},{},[597],{"type":23,"value":83},{"type":23,"value":599},"类构造函数前，我们需要：",{"type":17,"tag":117,"props":601,"children":602},{},[603,623,641],{"type":17,"tag":121,"props":604,"children":605},{},[606,608,614,616,621],{"type":23,"value":607},"利用 Python build_in ",{"type":17,"tag":144,"props":609,"children":611},{"className":610},[],[612],{"type":23,"value":613},"locals",{"type":23,"value":615}," 将函数初始化时用到的参数存入 ",{"type":17,"tag":60,"props":617,"children":618},{},[619],{"type":23,"value":620},"param",{"type":23,"value":622}," 字典中。",{"type":17,"tag":121,"props":624,"children":625},{},[626,628,632,634,639],{"type":23,"value":627},"在",{"type":17,"tag":60,"props":629,"children":630},{},[631],{"type":23,"value":620},{"type":23,"value":633}," 中加入以 ",{"type":17,"tag":60,"props":635,"children":636},{},[637],{"type":23,"value":638},"'param_dict'",{"type":23,"value":640}," 为key, 值为 {“dist_spec_arg1_name” : dist_spec_arg1, ...}的元素",{"type":17,"tag":121,"props":642,"children":643},{},[644,646,650],{"type":23,"value":645},"用 Validator 检查 ",{"type":17,"tag":60,"props":647,"children":648},{},[649],{"type":23,"value":270},{"type":23,"value":651},"的正确性",{"type":17,"tag":25,"props":653,"children":654},{},[655,657,661],{"type":23,"value":656},"完成以上步骤后就我们可以调用 ",{"type":17,"tag":60,"props":658,"children":659},{},[660],{"type":23,"value":83},{"type":23,"value":662}," 基类的构造函数啦！",{"type":17,"tag":437,"props":664,"children":666},{"id":665},"distribution-基类构造函数",[667],{"type":23,"value":668},"Distribution 基类构造函数",{"type":17,"tag":25,"props":670,"children":671},{},[672,676,678,683],{"type":17,"tag":60,"props":673,"children":674},{},[675],{"type":23,"value":83},{"type":23,"value":677}," 继承",{"type":17,"tag":60,"props":679,"children":680},{},[681],{"type":23,"value":682},"Cell",{"type":23,"value":684},"，构造函数参数包括:",{"type":17,"tag":686,"props":687,"children":688},"ul",{},[689,699,708,717],{"type":17,"tag":121,"props":690,"children":691},{},[692,697],{"type":17,"tag":60,"props":693,"children":694},{},[695],{"type":23,"value":696},"seed",{"type":23,"value":698},": 随机抽样种子。",{"type":17,"tag":121,"props":700,"children":701},{},[702,706],{"type":17,"tag":60,"props":703,"children":704},{},[705],{"type":23,"value":270},{"type":23,"value":707},": 分布的数据类型。",{"type":17,"tag":121,"props":709,"children":710},{},[711,715],{"type":17,"tag":60,"props":712,"children":713},{},[714],{"type":23,"value":277},{"type":23,"value":716},": 分布的名称。",{"type":17,"tag":121,"props":718,"children":719},{},[720,724],{"type":17,"tag":60,"props":721,"children":722},{},[723],{"type":23,"value":620},{"type":23,"value":725},": 分布初始化时所用参数。",{"type":17,"tag":25,"props":727,"children":728},{},[729,730,734,736,740,741,745],{"type":23,"value":627},{"type":17,"tag":60,"props":731,"children":732},{},[733],{"type":23,"value":83},{"type":23,"value":735},"基类构造函数中，完成了检查",{"type":17,"tag":60,"props":737,"children":738},{},[739],{"type":23,"value":277},{"type":23,"value":382},{"type":17,"tag":60,"props":742,"children":743},{},[744],{"type":23,"value":696},{"type":23,"value":746}," 参数的合法性，计算并设置该分布的属性。",{"type":17,"tag":437,"props":748,"children":750},{"id":749},"distribution-构造函数中初始化的property-和公有属性",[751],{"type":23,"value":752},"Distribution 构造函数中初始化的Property 和公有属性",{"type":17,"tag":25,"props":754,"children":755},{},[756,760,762,767,768,773,774,779,780,786,787,793,794,800,801,807],{"type":17,"tag":60,"props":757,"children":758},{},[759],{"type":23,"value":83},{"type":23,"value":761}," 类的公有的Property包括",{"type":17,"tag":144,"props":763,"children":765},{"className":764},[],[766],{"type":23,"value":277},{"type":23,"value":382},{"type":17,"tag":144,"props":769,"children":771},{"className":770},[],[772],{"type":23,"value":270},{"type":23,"value":382},{"type":17,"tag":144,"props":775,"children":777},{"className":776},[],[778],{"type":23,"value":696},{"type":23,"value":382},{"type":17,"tag":144,"props":781,"children":783},{"className":782},[],[784],{"type":23,"value":785},"parameters",{"type":23,"value":382},{"type":17,"tag":144,"props":788,"children":790},{"className":789},[],[791],{"type":23,"value":792},"is_scalar_bacth",{"type":23,"value":382},{"type":17,"tag":144,"props":795,"children":797},{"className":796},[],[798],{"type":23,"value":799},"batch_shape",{"type":23,"value":382},{"type":17,"tag":144,"props":802,"children":804},{"className":803},[],[805],{"type":23,"value":806},"broadcast_shape",{"type":23,"value":808},"。 这些属性都在基类构造函数中被初始化。。",{"type":17,"tag":437,"props":810,"children":812},{"id":811},"selfparameter_type",[813],{"type":23,"value":814},"self.parameter_type",{"type":17,"tag":25,"props":816,"children":817},{},[818,823,825,830,832,838,840,845,847,853,855,860,862,868,870,875,877,882,884,889,891,895,897,902,904,909],{"type":17,"tag":144,"props":819,"children":821},{"className":820},[],[822],{"type":23,"value":814},{"type":23,"value":824},"的检查由 ",{"type":17,"tag":60,"props":826,"children":827},{},[828],{"type":23,"value":829},"mindspore.nn.probabilsity.distribution._utils.utils",{"type":23,"value":831}," 中",{"type":17,"tag":144,"props":833,"children":835},{"className":834},[],[836],{"type":23,"value":837},"set_param_type",{"type":23,"value":839},"实现。 ",{"type":17,"tag":144,"props":841,"children":843},{"className":842},[],[844],{"type":23,"value":837},{"type":23,"value":846}," 接收一个参数字典，和一个 ",{"type":17,"tag":144,"props":848,"children":850},{"className":849},[],[851],{"type":23,"value":852},"hint_type",{"type":23,"value":854},"。一般来说，",{"type":17,"tag":144,"props":856,"children":858},{"className":857},[],[859],{"type":23,"value":852},{"type":23,"value":861},"设为",{"type":17,"tag":144,"props":863,"children":865},{"className":864},[],[866],{"type":23,"value":867},"self.dtype",{"type":23,"value":869},"， 即分布的类型。 我们希望",{"type":17,"tag":144,"props":871,"children":873},{"className":872},[],[874],{"type":23,"value":814},{"type":23,"value":876},"为浮点数类型。所以对于离散函数来说，",{"type":17,"tag":144,"props":878,"children":880},{"className":879},[],[881],{"type":23,"value":852},{"type":23,"value":883},"默认为 ",{"type":17,"tag":455,"props":885,"children":886},{},[887],{"type":23,"value":888},"mindspore.float32",{"type":23,"value":890},"。当一个分布有多个参数，且以_np.array_ 或 _Tensor_的形式传入时， 参数的dtype必须一致，否则将会报错。出于统一的后端支持的原因，当传入的参数 ",{"type":17,"tag":455,"props":892,"children":893},{},[894],{"type":23,"value":270},{"type":23,"value":896}," 是某些后端运算不支持的类型，例如 ",{"type":17,"tag":455,"props":898,"children":899},{},[900],{"type":23,"value":901},"float64",{"type":23,"value":903}," 时, 参数将会被自动类型转换为 ",{"type":17,"tag":144,"props":905,"children":907},{"className":906},[],[908],{"type":23,"value":852},{"type":23,"value":435},{"type":17,"tag":437,"props":911,"children":913},{"id":912},"is_scalar_batch-batch_shape-broadcast_shape",[914],{"type":23,"value":915},"is_scalar_batch, batch_shape, broadcast_shape",{"type":17,"tag":25,"props":917,"children":918},{},[919,921,927,929,935,936,941,943,947,949,955,957,962],{"type":23,"value":920},"若初始化时，",{"type":17,"tag":144,"props":922,"children":924},{"className":923},[],[925],{"type":23,"value":926},"param['param_dict']",{"type":23,"value":928},"中值皆为 int/float/None 是， ",{"type":17,"tag":144,"props":930,"children":932},{"className":931},[],[933],{"type":23,"value":934},"is_scalar_batch",{"type":23,"value":497},{"type":17,"tag":455,"props":937,"children":938},{},[939],{"type":23,"value":940},"True",{"type":23,"value":942},"。对于非",{"type":17,"tag":60,"props":944,"children":945},{},[946],{"type":23,"value":284},{"type":23,"value":948}," 的分布来说，",{"type":17,"tag":144,"props":950,"children":952},{"className":951},[],[953],{"type":23,"value":954},"batch_shpae",{"type":23,"value":956}," 等于 ",{"type":17,"tag":144,"props":958,"children":960},{"className":959},[],[961],{"type":23,"value":806},{"type":23,"value":963},"，是所有参数广播后的 shape。若参数不能广播，将会报错。",{"type":17,"tag":437,"props":965,"children":967},{"id":966},"私有函数指针",[968],{"type":23,"value":966},{"type":17,"tag":25,"props":970,"children":971},{},[972,974,980,982,988,990,995],{"type":23,"value":973},"除了一些Property 和公有属性外，基类构造函数中还初始化了",{"type":17,"tag":144,"props":975,"children":977},{"className":976},[],[978],{"type":23,"value":979},"_call_prob",{"type":23,"value":981},"等函数指针。该指针指向派生类的",{"type":17,"tag":144,"props":983,"children":985},{"className":984},[],[986],{"type":23,"value":987},"_prob",{"type":23,"value":989},"函数或基类的",{"type":17,"tag":60,"props":991,"children":992},{},[993],{"type":23,"value":994},"wrapper functions",{"type":23,"value":996},"，这一部分会在第三节中详细介绍。",{"type":17,"tag":437,"props":998,"children":1000},{"id":999},"为派生类添加属性",[1001],{"type":23,"value":999},{"type":17,"tag":25,"props":1003,"children":1004},{},[1005,1007,1011,1013,1017,1019,1025,1027,1032,1034,1039,1041,1047,1048,1054,1056,1060,1062,1066,1068,1074,1075,1081,1082,1087,1089,1094,1096,1101,1102,1107,1109,1114,1116,1121],{"type":23,"value":1006},"完成基类初始化后，我们需要在子类中初始化子类属性, 通常为分布的 ",{"type":17,"tag":60,"props":1008,"children":1009},{},[1010],{"type":23,"value":263},{"type":23,"value":1012},", 这一步需调用 ",{"type":17,"tag":60,"props":1014,"children":1015},{},[1016],{"type":23,"value":83},{"type":23,"value":1018}," 中基类函数 ",{"type":17,"tag":144,"props":1020,"children":1022},{"className":1021},[],[1023],{"type":23,"value":1024},"_add_parameter",{"type":23,"value":1026},"，将传入的参数类型转换为类型为",{"type":17,"tag":144,"props":1028,"children":1030},{"className":1029},[],[1031],{"type":23,"value":814},{"type":23,"value":1033},"的 ",{"type":17,"tag":455,"props":1035,"children":1036},{},[1037],{"type":23,"value":1038},"Tensor",{"type":23,"value":1040},"，并将该参数及参数名称加入到 ",{"type":17,"tag":144,"props":1042,"children":1044},{"className":1043},[],[1045],{"type":23,"value":1046},"self.default_parameters",{"type":23,"value":245},{"type":17,"tag":144,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":23,"value":1053},"self.parameters_names",{"type":23,"value":1055},"两个 list 中。 以 ",{"type":17,"tag":60,"props":1057,"children":1058},{},[1059],{"type":23,"value":90},{"type":23,"value":1061}," 为例，分布的 ",{"type":17,"tag":60,"props":1063,"children":1064},{},[1065],{"type":23,"value":263},{"type":23,"value":1067}," 为 location, 和 scale, 因此，我们初始化",{"type":17,"tag":144,"props":1069,"children":1071},{"className":1070},[],[1072],{"type":23,"value":1073},"self._loc",{"type":23,"value":382},{"type":17,"tag":144,"props":1076,"children":1078},{"className":1077},[],[1079],{"type":23,"value":1080},"self._scale",{"type":23,"value":286},{"type":17,"tag":144,"props":1083,"children":1085},{"className":1084},[],[1086],{"type":23,"value":1024},{"type":23,"value":1088}," 完成后，",{"type":17,"tag":144,"props":1090,"children":1092},{"className":1091},[],[1093],{"type":23,"value":1046},{"type":23,"value":1095}," = [",{"type":17,"tag":144,"props":1097,"children":1099},{"className":1098},[],[1100],{"type":23,"value":1073},{"type":23,"value":382},{"type":17,"tag":144,"props":1103,"children":1105},{"className":1104},[],[1106],{"type":23,"value":1080},{"type":23,"value":1108},"]，",{"type":17,"tag":144,"props":1110,"children":1112},{"className":1111},[],[1113],{"type":23,"value":1053},{"type":23,"value":1115}," = ['loc', 'scale']。 这两个属性在具体的概率函数实现中尤为重要，详见第三节 ",{"type":17,"tag":60,"props":1117,"children":1118},{},[1119],{"type":23,"value":1120},"Log_prob 的参数",{"type":23,"value":435},{"type":17,"tag":25,"props":1123,"children":1124},{},[1125,1127,1131,1133,1138,1140,1144],{"type":23,"value":1126},"如果你希望检查参数的正确性，",{"type":17,"tag":60,"props":1128,"children":1129},{},[1130],{"type":23,"value":829},{"type":23,"value":1132}," 中提供了很多 ",{"type":17,"tag":60,"props":1134,"children":1135},{},[1136],{"type":23,"value":1137},"utility functions",{"type":23,"value":1139}," 可供调用。此处，我们检查 ",{"type":17,"tag":60,"props":1141,"children":1142},{},[1143],{"type":23,"value":387},{"type":23,"value":1145}," 的是否大于零。",{"type":17,"tag":364,"props":1147,"children":1149},{"code":1148},"self._loc = self._add_parameter(loc, 'loc')\n    self._scale = self._add_parameter(scale, 'scale')\n    if self._scale is not None:\n        check_greater_zero(self._scale， 'scale')\n",[1150],{"type":17,"tag":144,"props":1151,"children":1152},{"__ignoreMap":7},[1153],{"type":23,"value":1148},{"type":17,"tag":25,"props":1155,"children":1156},{},[1157,1159,1164,1166,1171,1173,1178],{"type":23,"value":1158},"另外，我们可以在构造函数外将",{"type":17,"tag":144,"props":1160,"children":1162},{"className":1161},[],[1163],{"type":23,"value":1073},{"type":23,"value":1165},"，",{"type":17,"tag":144,"props":1167,"children":1169},{"className":1168},[],[1170],{"type":23,"value":1080},{"type":23,"value":1172}," 设为 ",{"type":17,"tag":60,"props":1174,"children":1175},{},[1176],{"type":23,"value":1177},"property",{"type":23,"value":1179},"， 方便访问。",{"type":17,"tag":364,"props":1181,"children":1183},{"code":1182},"@property\n   def loc(self):\n        return self._loc\n    @property\n   def loc(self):\n        return self._loc\n",[1184],{"type":17,"tag":144,"props":1185,"children":1186},{"__ignoreMap":7},[1187],{"type":23,"value":1182},{"type":17,"tag":25,"props":1189,"children":1190},{},[1191,1193,1198,1200,1205,1207,1212],{"type":23,"value":1192},"最后, 在构造函数中初始化你需要用到的算子和nupmy的常数， 算子通常在",{"type":17,"tag":60,"props":1194,"children":1195},{},[1196],{"type":23,"value":1197},"mindspore.ops",{"type":23,"value":1199}," 和",{"type":17,"tag":60,"props":1201,"children":1202},{},[1203],{"type":23,"value":1204},"mindspore.nn.probabiltiy.distribution._utils.custom_ops",{"type":23,"value":1206}," 下找到。",{"type":17,"tag":60,"props":1208,"children":1209},{},[1210],{"type":23,"value":1211},"custom_ops",{"type":23,"value":1213},"中提供更加稳定的算子。这里以四个算子为例：",{"type":17,"tag":364,"props":1215,"children":1217},{"code":1216},"self.abs = P.Abs()\n    self.cast = P.Cast()\n    self.exp = exp_generic\n    self.log = log_generic\n",[1218],{"type":17,"tag":144,"props":1219,"children":1220},{"__ignoreMap":7},[1221],{"type":23,"value":1216},{"type":17,"tag":25,"props":1223,"children":1224},{},[1225,1227,1231],{"type":23,"value":1226},"到这里，你已经完成了",{"type":17,"tag":60,"props":1228,"children":1229},{},[1230],{"type":23,"value":90},{"type":23,"value":1232},"分布的构造函数， 完整的代码如下：",{"type":17,"tag":364,"props":1234,"children":1236},{"code":1235},"class Laplace(Distribution):\n    def __init__(self, loc=0.， scale=1., dtype=mstype.float32, name='Laplace'):\n        param = dict(locals())\n        param['param_dict']={\"loc\": loc, \"scale\", scale}\n        valid_type = mstype.float_type\n        Validator.check_type(type(self.__name__), dtype, valid, type)\n        super(Laplace, self).__init__(seed, dtype, name, param)\n        self._loc = self._add_parameter(loc, 'loc')\n        self._scale = self._add_parameter(scale, 'scale')\n        if self._scale is not None:\n            check_greater_zero(self._scale， ‘scale’)\n        \n        self.abs = P.Abs()\n        self.cast = P.Cast()\n        self.const = P.ScalarToArray()\n        self.exp = exp_generic\n        self.log = log_generic\n        self.log1p = P.Log1p()\n        self.sqrt = P.Sqrt()\n        self.shape = P.Shape()\n        self.sign = P.Sign()\n        self.squeeze = P.Squeeze(0)\n        self.uniform = C.uniform\n        \n        self.eps = np.finfo(float).eps\n    \n    @property\n    def loc(self):\n        return self._loc\n    @property\n    def loc(self):\n        return self._loc\n",[1237],{"type":17,"tag":144,"props":1238,"children":1239},{"__ignoreMap":7},[1240],{"type":23,"value":1235},{"type":17,"tag":41,"props":1242,"children":1244},{"id":1243},"实现打包函数参数的公有接口",[1245],{"type":23,"value":1243},{"type":17,"tag":25,"props":1247,"children":1248},{},[1249,1251,1257,1258,1264,1265,1270],{"type":23,"value":1250},"下面我们来实现一些需要重载的公有接口， ·",{"type":17,"tag":144,"props":1252,"children":1254},{"className":1253},[],[1255],{"type":23,"value":1256},"_get_dist_type",{"type":23,"value":245},{"type":17,"tag":144,"props":1259,"children":1261},{"className":1260},[],[1262],{"type":23,"value":1263},"_get_dist_args",{"type":23,"value":286},{"type":17,"tag":144,"props":1266,"children":1268},{"className":1267},[],[1269],{"type":23,"value":1256},{"type":23,"value":1271}," 不接收任何参数，返回一个代表函数类型的字符串。",{"type":17,"tag":364,"props":1273,"children":1275},{"code":1274},"def _get_dist_type(self):\n        return \"Laplace\"\n",[1276],{"type":17,"tag":144,"props":1277,"children":1278},{"__ignoreMap":7},[1279],{"type":23,"value":1274},{"type":17,"tag":25,"props":1281,"children":1282},{},[1283,1288,1290,1294],{"type":17,"tag":144,"props":1284,"children":1286},{"className":1285},[],[1287],{"type":23,"value":1263},{"type":23,"value":1289}," 接收 ",{"type":17,"tag":60,"props":1291,"children":1292},{},[1293],{"type":23,"value":263},{"type":23,"value":1295},", 可打包函数以list 的形式返回, 一般形式为",{"type":17,"tag":364,"props":1297,"children":1299},{"code":1298},"def  _get_dist_type(self，dist_spec_args1=None， dist_spec_args2=None, ... )\n",[1300],{"type":17,"tag":144,"props":1301,"children":1302},{"__ignoreMap":7},[1303],{"type":23,"value":1298},{"type":17,"tag":25,"props":1305,"children":1306},{},[1307,1309,1313,1315,1319,1321,1327,1329,1333,1334,1339],{"type":23,"value":1308},"在此函数中，需检查传入的 ",{"type":17,"tag":60,"props":1310,"children":1311},{},[1312],{"type":23,"value":263},{"type":23,"value":1314}," 是否为 ",{"type":17,"tag":60,"props":1316,"children":1317},{},[1318],{"type":23,"value":1038},{"type":23,"value":1320},"（可以直接调用基类已初始化的",{"type":17,"tag":144,"props":1322,"children":1324},{"className":1323},[],[1325],{"type":23,"value":1326},"self.checktensor",{"type":23,"value":1328}," 算子）。如果传入 ",{"type":17,"tag":60,"props":1330,"children":1331},{},[1332],{"type":23,"value":263},{"type":23,"value":497},{"type":17,"tag":144,"props":1335,"children":1337},{"className":1336},[],[1338],{"type":23,"value":509},{"type":23,"value":1340},", 返回初始化时的值。 具体实现如下：",{"type":17,"tag":364,"props":1342,"children":1344},{"code":1343},"def _get_dist_args(self, loc=None, scale=None):\n        if loc is not None:\n            self.checktensor(loc, 'loc')\n        else:\n            loc = self.loc\n        if scale is not None:\n            self.checktensor(scale, 'scale')\n        else:\n            scale = self.scale\n        return loc, scale\n",[1345],{"type":17,"tag":144,"props":1346,"children":1347},{"__ignoreMap":7},[1348],{"type":23,"value":1343},{"type":17,"tag":41,"props":1350,"children":1352},{"id":1351},"实现-log_prob-函数",[1353],{"type":23,"value":1354},"实现 log_prob 函数",{"type":17,"tag":25,"props":1356,"children":1357},{},[1358,1360,1364,1366,1371,1372,1377,1378,1383,1384,1389,1390,1395,1396,1401,1402,1406,1407,1412,1413,1418,1419,1424,1425,1430,1431,1436,1438,1443,1445,1450,1452,1458,1460,1465,1467,1472,1474,1478,1480,1484],{"type":23,"value":1359},"现在我们进入到具体的函数的实现把！ ",{"type":17,"tag":60,"props":1361,"children":1362},{},[1363],{"type":23,"value":83},{"type":23,"value":1365}," 类支持的函数包括 ",{"type":17,"tag":455,"props":1367,"children":1368},{},[1369],{"type":23,"value":1370},"prob",{"type":23,"value":382},{"type":17,"tag":455,"props":1373,"children":1374},{},[1375],{"type":23,"value":1376},"log_prob",{"type":23,"value":382},{"type":17,"tag":455,"props":1379,"children":1380},{},[1381],{"type":23,"value":1382},"cdf",{"type":23,"value":382},{"type":17,"tag":455,"props":1385,"children":1386},{},[1387],{"type":23,"value":1388},"log_cdf",{"type":23,"value":382},{"type":17,"tag":455,"props":1391,"children":1392},{},[1393],{"type":23,"value":1394},"survival_function",{"type":23,"value":382},{"type":17,"tag":455,"props":1397,"children":1398},{},[1399],{"type":23,"value":1400},"log_survival",{"type":23,"value":382},{"type":17,"tag":455,"props":1403,"children":1404},{},[1405],{"type":23,"value":459},{"type":23,"value":382},{"type":17,"tag":455,"props":1408,"children":1409},{},[1410],{"type":23,"value":1411},"sd",{"type":23,"value":382},{"type":17,"tag":455,"props":1414,"children":1415},{},[1416],{"type":23,"value":1417},"var",{"type":23,"value":382},{"type":17,"tag":455,"props":1420,"children":1421},{},[1422],{"type":23,"value":1423},"entropy",{"type":23,"value":382},{"type":17,"tag":455,"props":1426,"children":1427},{},[1428],{"type":23,"value":1429},"kl_loss",{"type":23,"value":382},{"type":17,"tag":455,"props":1432,"children":1433},{},[1434],{"type":23,"value":1435},"cross_entropy",{"type":23,"value":1437},",和 ",{"type":17,"tag":455,"props":1439,"children":1440},{},[1441],{"type":23,"value":1442},"sample",{"type":23,"value":1444},"，由派生类函数的具体实现决定参数。调用时，基类会调用对应函数指针指向的函数，这些指针在基类构造函数中比如说，使用",{"type":17,"tag":144,"props":1446,"children":1448},{"className":1447},[],[1449],{"type":23,"value":1370},{"type":23,"value":1451},"时，会调用指针",{"type":17,"tag":144,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":23,"value":1457},"self._call_prob",{"type":23,"value":1459},"指向的函数。 ",{"type":17,"tag":144,"props":1461,"children":1463},{"className":1462},[],[1464],{"type":23,"value":1457},{"type":23,"value":1466},"默认指向",{"type":17,"tag":144,"props":1468,"children":1470},{"className":1469},[],[1471],{"type":23,"value":987},{"type":23,"value":1473},", 所以，派生类中需重载 ",{"type":17,"tag":455,"props":1475,"children":1476},{},[1477],{"type":23,"value":987},{"type":23,"value":1479}," 来支持基类 ",{"type":17,"tag":455,"props":1481,"children":1482},{},[1483],{"type":23,"value":1370},{"type":23,"value":1485}," 计算。",{"type":17,"tag":25,"props":1487,"children":1488},{},[1489],{"type":23,"value":1490},"完整的函数表：",{"type":17,"tag":686,"props":1492,"children":1493},{},[1494,1503,1512,1521,1530,1539,1548,1557,1567,1576,1585,1594,1603,1612,1621,1631],{"type":17,"tag":121,"props":1495,"children":1496},{},[1497,1501],{"type":17,"tag":60,"props":1498,"children":1499},{},[1500],{"type":23,"value":1370},{"type":23,"value":1502}," : 概率密度函数（pdf）/ 概率质量函数（pmf）",{"type":17,"tag":121,"props":1504,"children":1505},{},[1506,1510],{"type":17,"tag":60,"props":1507,"children":1508},{},[1509],{"type":23,"value":1376},{"type":23,"value":1511}," ：对数似然函数。",{"type":17,"tag":121,"props":1513,"children":1514},{},[1515,1519],{"type":17,"tag":60,"props":1516,"children":1517},{},[1518],{"type":23,"value":1382},{"type":23,"value":1520}," : 累积分布函数（cdf）。",{"type":17,"tag":121,"props":1522,"children":1523},{},[1524,1528],{"type":17,"tag":60,"props":1525,"children":1526},{},[1527],{"type":23,"value":1388},{"type":23,"value":1529}," : 对数累积分布函数（cdf）。",{"type":17,"tag":121,"props":1531,"children":1532},{},[1533,1537],{"type":17,"tag":60,"props":1534,"children":1535},{},[1536],{"type":23,"value":1394},{"type":23,"value":1538}," : 生存函数。与 cdf 互补。",{"type":17,"tag":121,"props":1540,"children":1541},{},[1542,1546],{"type":17,"tag":60,"props":1543,"children":1544},{},[1545],{"type":23,"value":1400},{"type":23,"value":1547}," : 对数生存函数。",{"type":17,"tag":121,"props":1549,"children":1550},{},[1551,1555],{"type":17,"tag":60,"props":1552,"children":1553},{},[1554],{"type":23,"value":459},{"type":23,"value":1556}," : 均值。",{"type":17,"tag":121,"props":1558,"children":1559},{},[1560,1565],{"type":17,"tag":60,"props":1561,"children":1562},{},[1563],{"type":23,"value":1564},"mode",{"type":23,"value":1566}," : 众数。",{"type":17,"tag":121,"props":1568,"children":1569},{},[1570,1574],{"type":17,"tag":60,"props":1571,"children":1572},{},[1573],{"type":23,"value":1411},{"type":23,"value":1575}," : 标准差。",{"type":17,"tag":121,"props":1577,"children":1578},{},[1579,1583],{"type":17,"tag":60,"props":1580,"children":1581},{},[1582],{"type":23,"value":1417},{"type":23,"value":1584}," : 方差。",{"type":17,"tag":121,"props":1586,"children":1587},{},[1588,1592],{"type":17,"tag":60,"props":1589,"children":1590},{},[1591],{"type":23,"value":1423},{"type":23,"value":1593}," : 熵。",{"type":17,"tag":121,"props":1595,"children":1596},{},[1597,1601],{"type":17,"tag":60,"props":1598,"children":1599},{},[1600],{"type":23,"value":1429},{"type":23,"value":1602}," : Kullback-Leibler散度。",{"type":17,"tag":121,"props":1604,"children":1605},{},[1606,1610],{"type":17,"tag":60,"props":1607,"children":1608},{},[1609],{"type":23,"value":1435},{"type":23,"value":1611}," : 两个概率分布的交叉熵。",{"type":17,"tag":121,"props":1613,"children":1614},{},[1615,1619],{"type":17,"tag":60,"props":1616,"children":1617},{},[1618],{"type":23,"value":1442},{"type":23,"value":1620}," : 随机取样。",{"type":17,"tag":121,"props":1622,"children":1623},{},[1624,1629],{"type":17,"tag":60,"props":1625,"children":1626},{},[1627],{"type":23,"value":1628},"get_dist_type",{"type":23,"value":1630},": 分布类型",{"type":17,"tag":121,"props":1632,"children":1633},{},[1634,1639],{"type":17,"tag":60,"props":1635,"children":1636},{},[1637],{"type":23,"value":1638},"get_dist_args",{"type":23,"value":1640},": 分布特征参数",{"type":17,"tag":1642,"props":1643,"children":1645},"h3",{"id":1644},"wrapper-functions",[1646],{"type":23,"value":1647},"Wrapper Functions",{"type":17,"tag":25,"props":1649,"children":1650},{},[1651,1653,1657,1659,1663,1665,1671,1673,1677,1679,1683,1685,1689],{"type":23,"value":1652},"然而并不是每一个函数都需要在派生类中实现， ",{"type":17,"tag":60,"props":1654,"children":1655},{},[1656],{"type":23,"value":83},{"type":23,"value":1658}," 实现了多样的 ",{"type":17,"tag":60,"props":1660,"children":1661},{},[1662],{"type":23,"value":994},{"type":23,"value":1664},"， 完成函数间的相互转换。 例如， ",{"type":17,"tag":144,"props":1666,"children":1668},{"className":1667},[],[1669],{"type":23,"value":1670},"_calc_prob_from_log_prob",{"type":23,"value":1672},"， 通过求 ",{"type":17,"tag":455,"props":1674,"children":1675},{},[1676],{"type":23,"value":1376},{"type":23,"value":1678}," 来获得 ",{"type":17,"tag":455,"props":1680,"children":1681},{},[1682],{"type":23,"value":1370},{"type":23,"value":1684}," 的值。",{"type":17,"tag":60,"props":1686,"children":1687},{},[1688],{"type":23,"value":83},{"type":23,"value":1690},"中该函数的实现如下：",{"type":17,"tag":364,"props":1692,"children":1694},{"code":1693},"def _calc_prob_from_log_prob(self, value, *args, **kwargs):\n        return self.exp_base(self._log_prob(value, *args, **kwargs))\n",[1695],{"type":17,"tag":144,"props":1696,"children":1697},{"__ignoreMap":7},[1698],{"type":23,"value":1693},{"type":17,"tag":25,"props":1700,"children":1701},{},[1702,1704,1708,1710,1716,1717,1723,1724,1730,1732,1737,1739,1745,1747,1752,1754,1760,1762,1768,1770,1775,1776,1781,1783,1789,1791,1796,1798,1803,1805,1811,1813,1818,1819,1824,1826,1831],{"type":23,"value":1703},"在 ",{"type":17,"tag":60,"props":1705,"children":1706},{},[1707],{"type":23,"value":83},{"type":23,"value":1709}," 构造函数中，",{"type":17,"tag":144,"props":1711,"children":1713},{"className":1712},[],[1714],{"type":23,"value":1715},"_set_prob",{"type":23,"value":382},{"type":17,"tag":144,"props":1718,"children":1720},{"className":1719},[],[1721],{"type":23,"value":1722},"_set_log_prob",{"type":23,"value":382},{"type":17,"tag":144,"props":1725,"children":1727},{"className":1726},[],[1728],{"type":23,"value":1729},"_set_cdf",{"type":23,"value":1731}," 等函数通过判断派生类的函数实现情况，设定基类函数指针。举个例子，若派生类中实现了 ",{"type":17,"tag":144,"props":1733,"children":1735},{"className":1734},[],[1736],{"type":23,"value":987},{"type":23,"value":1738}," 函数，但未实现 ",{"type":17,"tag":144,"props":1740,"children":1742},{"className":1741},[],[1743],{"type":23,"value":1744},"_log_prob",{"type":23,"value":1746},"函数，默认地，",{"type":17,"tag":144,"props":1748,"children":1750},{"className":1749},[],[1751],{"type":23,"value":1722},{"type":23,"value":1753}," 会将 ",{"type":17,"tag":144,"props":1755,"children":1757},{"className":1756},[],[1758],{"type":23,"value":1759},"self._call_log_prob",{"type":23,"value":1761}," 函数指针指向 ",{"type":17,"tag":144,"props":1763,"children":1765},{"className":1764},[],[1766],{"type":23,"value":1767},"_calc_prob_fromlog__prob",{"type":23,"value":1769},"。因为",{"type":17,"tag":144,"props":1771,"children":1773},{"className":1772},[],[1774],{"type":23,"value":1370},{"type":23,"value":382},{"type":17,"tag":144,"props":1777,"children":1779},{"className":1778},[],[1780],{"type":23,"value":1376},{"type":23,"value":1782}," 之间可相互转换，所以派升类只需实现其中的一个函数，若两个函数都没有在派生类中实现，那么这两个函数的指针指向一个报错函数 ",{"type":17,"tag":144,"props":1784,"children":1786},{"className":1785},[],[1787],{"type":23,"value":1788},"_raise_not_implemented_error",{"type":23,"value":1790},"。当尝试调用",{"type":17,"tag":144,"props":1792,"children":1794},{"className":1793},[],[1795],{"type":23,"value":1744},{"type":23,"value":1797},"或",{"type":17,"tag":144,"props":1799,"children":1801},{"className":1800},[],[1802],{"type":23,"value":987},{"type":23,"value":1804},"是，会出现",{"type":17,"tag":144,"props":1806,"children":1808},{"className":1807},[],[1809],{"type":23,"value":1810},"NotImplementedError",{"type":23,"value":1812},"。 但为了函数稳定性与计算效率，亦可同时在派生类中实现",{"type":17,"tag":144,"props":1814,"children":1816},{"className":1815},[],[1817],{"type":23,"value":987},{"type":23,"value":382},{"type":17,"tag":144,"props":1820,"children":1822},{"className":1821},[],[1823],{"type":23,"value":1744},{"type":23,"value":1825},"。此时。基类函数中的",{"type":17,"tag":144,"props":1827,"children":1829},{"className":1828},[],[1830],{"type":23,"value":1715},{"type":23,"value":1832}," 等函数将不会选择 wrapper function， 而会直接指向派生类中的函数。",{"type":17,"tag":25,"props":1834,"children":1835},{},[1836,1838,1842,1844,1849,1850,1855,1857,1862],{"type":23,"value":1837},"今天在",{"type":17,"tag":60,"props":1839,"children":1840},{},[1841],{"type":23,"value":90},{"type":23,"value":1843},"分布中，我们选择重载",{"type":17,"tag":144,"props":1845,"children":1847},{"className":1846},[],[1848],{"type":23,"value":1744},{"type":23,"value":286},{"type":17,"tag":144,"props":1851,"children":1853},{"className":1852},[],[1854],{"type":23,"value":1370},{"type":23,"value":1856},"的计算将由基类调用",{"type":17,"tag":144,"props":1858,"children":1860},{"className":1859},[],[1861],{"type":23,"value":1670},{"type":23,"value":1863},"进行。",{"type":17,"tag":1642,"props":1865,"children":1867},{"id":1866},"log_prob-的参数",[1868],{"type":23,"value":1869},"log_prob 的参数",{"type":17,"tag":25,"props":1871,"children":1872},{},[1873,1875,1880,1881,1886,1887,1892,1893,1898,1899,1904,1905,1910,1912,1916,1918,1924,1926,1930,1932,1937,1939,1943,1945,1950,1951,1956,1958,1963],{"type":23,"value":1874},"一般地，",{"type":17,"tag":144,"props":1876,"children":1878},{"className":1877},[],[1879],{"type":23,"value":1370},{"type":23,"value":382},{"type":17,"tag":144,"props":1882,"children":1884},{"className":1883},[],[1885],{"type":23,"value":1376},{"type":23,"value":382},{"type":17,"tag":144,"props":1888,"children":1890},{"className":1889},[],[1891],{"type":23,"value":1382},{"type":23,"value":382},{"type":17,"tag":144,"props":1894,"children":1896},{"className":1895},[],[1897],{"type":23,"value":1388},{"type":23,"value":382},{"type":17,"tag":144,"props":1900,"children":1902},{"className":1901},[],[1903],{"type":23,"value":1394},{"type":23,"value":382},{"type":17,"tag":144,"props":1906,"children":1908},{"className":1907},[],[1909],{"type":23,"value":1400},{"type":23,"value":1911}," 有相同的参数形式，必须传入一个为 ",{"type":17,"tag":455,"props":1913,"children":1914},{},[1915],{"type":23,"value":1038},{"type":23,"value":1917}," 的 ",{"type":17,"tag":144,"props":1919,"children":1921},{"className":1920},[],[1922],{"type":23,"value":1923},"value",{"type":23,"value":1925},"。可选参数为分布的特征参数 ",{"type":17,"tag":60,"props":1927,"children":1928},{},[1929],{"type":23,"value":263},{"type":23,"value":1931},", 默认值为",{"type":17,"tag":144,"props":1933,"children":1935},{"className":1934},[],[1936],{"type":23,"value":509},{"type":23,"value":1938},"。以",{"type":17,"tag":60,"props":1940,"children":1941},{},[1942],{"type":23,"value":90},{"type":23,"value":1944}," 为例， 可选参数为",{"type":17,"tag":144,"props":1946,"children":1948},{"className":1947},[],[1949],{"type":23,"value":174},{"type":23,"value":1165},{"type":17,"tag":144,"props":1952,"children":1954},{"className":1953},[],[1955],{"type":23,"value":387},{"type":23,"value":1957},"。根据以上原则，",{"type":17,"tag":144,"props":1959,"children":1961},{"className":1960},[],[1962],{"type":23,"value":1376},{"type":23,"value":1964}," 的函数定义如下：",{"type":17,"tag":364,"props":1966,"children":1968},{"code":1967},"def _log_prob(self, value, loc=None, scale=None):\n",[1969],{"type":17,"tag":144,"props":1970,"children":1971},{"__ignoreMap":7},[1972],{"type":23,"value":1967},{"type":17,"tag":25,"props":1974,"children":1975},{},[1976,1978,1983,1984,1989,1991,1996],{"type":23,"value":1977},"进入函数后，我们需要对",{"type":17,"tag":144,"props":1979,"children":1981},{"className":1980},[],[1982],{"type":23,"value":1923},{"type":23,"value":382},{"type":17,"tag":144,"props":1985,"children":1987},{"className":1986},[],[1988],{"type":23,"value":174},{"type":23,"value":1990},",",{"type":17,"tag":144,"props":1992,"children":1994},{"className":1993},[],[1995],{"type":23,"value":387},{"type":23,"value":1997}," 进行检查。",{"type":17,"tag":117,"props":1999,"children":2000},{},[2001],{"type":17,"tag":121,"props":2002,"children":2003},{},[2004,2006,2011],{"type":23,"value":2005},"对",{"type":17,"tag":144,"props":2007,"children":2009},{"className":2008},[],[2010],{"type":23,"value":1923},{"type":23,"value":2012},"进行处理",{"type":17,"tag":364,"props":2014,"children":2016},{"code":2015},"value = self._check_value(value, \"value\")\n    value = self.cast(value, self.dtype)\n",[2017],{"type":17,"tag":144,"props":2018,"children":2019},{"__ignoreMap":7},[2020],{"type":23,"value":2015},{"type":17,"tag":25,"props":2022,"children":2023},{},[2024,2030,2032,2036,2038,2043,2044,2048,2050,2055,2057,2062,2064,2069,2071,2076,2078,2083,2084,2089],{"type":17,"tag":144,"props":2025,"children":2027},{"className":2026},[],[2028],{"type":23,"value":2029},"_check_value",{"type":23,"value":2031}," 为",{"type":17,"tag":60,"props":2033,"children":2034},{},[2035],{"type":23,"value":83},{"type":23,"value":2037},"基类函数，检查",{"type":17,"tag":144,"props":2039,"children":2041},{"className":2040},[],[2042],{"type":23,"value":1923},{"type":23,"value":1314},{"type":17,"tag":455,"props":2045,"children":2046},{},[2047],{"type":23,"value":1038},{"type":23,"value":2049}," 类型，如果不是Tensor将报错。为保证函数稳定性，建议将所有 ",{"type":17,"tag":455,"props":2051,"children":2052},{},[2053],{"type":23,"value":2054},"input value",{"type":23,"value":2056}," 都转换为 ",{"type":17,"tag":455,"props":2058,"children":2059},{},[2060],{"type":23,"value":2061},"float_type",{"type":23,"value":2063},"。 这里可以将 ",{"type":17,"tag":144,"props":2065,"children":2067},{"className":2066},[],[2068],{"type":23,"value":1923},{"type":23,"value":2070}," 类型转换为 ",{"type":17,"tag":144,"props":2072,"children":2074},{"className":2073},[],[2075],{"type":23,"value":867},{"type":23,"value":2077},". 离散分布可将",{"type":17,"tag":144,"props":2079,"children":2081},{"className":2080},[],[2082],{"type":23,"value":1923},{"type":23,"value":2070},{"type":17,"tag":144,"props":2085,"children":2087},{"className":2086},[],[2088],{"type":23,"value":814},{"type":23,"value":2090},".",{"type":17,"tag":117,"props":2092,"children":2094},{"start":2093},2,[2095],{"type":17,"tag":121,"props":2096,"children":2097},{},[2098,2100,2105,2106,2111,2113,2119,2120,2126,2128,2133,2134,2139,2141,2146,2147,2152,2154,2159,2160,2165,2167,2172,2174,2179,2180,2185,2186,2191,2192,2197],{"type":23,"value":2099},"检查",{"type":17,"tag":144,"props":2101,"children":2103},{"className":2102},[],[2104],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2107,"children":2109},{"className":2108},[],[2110],{"type":23,"value":387},{"type":23,"value":2112}," 这里有四种情况需要考虑，1. 初始化时 loc, scale 不为空（即 ",{"type":17,"tag":144,"props":2114,"children":2116},{"className":2115},[],[2117],{"type":23,"value":2118},"self.loc",{"type":23,"value":382},{"type":17,"tag":144,"props":2121,"children":2123},{"className":2122},[],[2124],{"type":23,"value":2125},"self.scale",{"type":23,"value":2127}," 不为空），log_prob 时未传入 loc, scale; 2. ",{"type":17,"tag":144,"props":2129,"children":2131},{"className":2130},[],[2132],{"type":23,"value":2118},{"type":23,"value":382},{"type":17,"tag":144,"props":2135,"children":2137},{"className":2136},[],[2138],{"type":23,"value":2125},{"type":23,"value":2140}," 不为空, log_prob 传入新的 loc, scale; 3. ",{"type":17,"tag":144,"props":2142,"children":2144},{"className":2143},[],[2145],{"type":23,"value":2118},{"type":23,"value":382},{"type":17,"tag":144,"props":2148,"children":2150},{"className":2149},[],[2151],{"type":23,"value":2125},{"type":23,"value":2153}," 为空, log_prob 未传入 loc, scale; 4. ",{"type":17,"tag":144,"props":2155,"children":2157},{"className":2156},[],[2158],{"type":23,"value":2118},{"type":23,"value":382},{"type":17,"tag":144,"props":2161,"children":2163},{"className":2162},[],[2164],{"type":23,"value":2125},{"type":23,"value":2166}," 为空, log_prob时传入新的 loc, scale. 对这四种请况的讨论可直接调用基类函数 ",{"type":17,"tag":144,"props":2168,"children":2170},{"className":2169},[],[2171],{"type":23,"value":567},{"type":23,"value":2173}," 完成对 ",{"type":17,"tag":144,"props":2175,"children":2177},{"className":2176},[],[2178],{"type":23,"value":2118},{"type":23,"value":382},{"type":17,"tag":144,"props":2181,"children":2183},{"className":2182},[],[2184],{"type":23,"value":2125},{"type":23,"value":382},{"type":17,"tag":144,"props":2187,"children":2189},{"className":2188},[],[2190],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2193,"children":2195},{"className":2194},[],[2196],{"type":23,"value":387},{"type":23,"value":2198},"的检查与选择。",{"type":17,"tag":364,"props":2200,"children":2202},{"code":2201},"loc, scale = self._check_param_type(loc, scale)\n",[2203],{"type":17,"tag":144,"props":2204,"children":2205},{"__ignoreMap":7},[2206],{"type":23,"value":2201},{"type":17,"tag":437,"props":2208,"children":2209},{"id":567},[2210],{"type":23,"value":567},{"type":17,"tag":25,"props":2212,"children":2213},{},[2214,2216,2221,2222,2227,2229,2234,2236,2241,2243,2248,2250,2254,2255,2259,2261,2266,2267,2272,2274,2279,2280,2285,2287,2292,2294,2299,2301,2306],{"type":23,"value":2215},"需注意的是，在调用此函数时，",{"type":17,"tag":144,"props":2217,"children":2219},{"className":2218},[],[2220],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2223,"children":2225},{"className":2224},[],[2226],{"type":23,"value":387},{"type":23,"value":2228}," 的传入顺序需与",{"type":17,"tag":144,"props":2230,"children":2232},{"className":2231},[],[2233],{"type":23,"value":360},{"type":23,"value":2235},"中 ",{"type":17,"tag":144,"props":2237,"children":2239},{"className":2238},[],[2240],{"type":23,"value":1024},{"type":23,"value":2242},"的顺序一致。例如，在",{"type":17,"tag":144,"props":2244,"children":2246},{"className":2245},[],[2247],{"type":23,"value":360},{"type":23,"value":2249},"中，加入的顺序为 ",{"type":17,"tag":60,"props":2251,"children":2252},{},[2253],{"type":23,"value":2118},{"type":23,"value":382},{"type":17,"tag":60,"props":2256,"children":2257},{},[2258],{"type":23,"value":2125},{"type":23,"value":2260},", 此时传入的顺序亦为先 loc 后 scale。在这个函数中，会检查传入的 ",{"type":17,"tag":144,"props":2262,"children":2264},{"className":2263},[],[2265],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2268,"children":2270},{"className":2269},[],[2271],{"type":23,"value":387},{"type":23,"value":2273}," 正确性，并决定使用此时传入的",{"type":17,"tag":144,"props":2275,"children":2277},{"className":2276},[],[2278],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2281,"children":2283},{"className":2282},[],[2284],{"type":23,"value":387},{"type":23,"value":2286}," ，或初始化时存入在 ",{"type":17,"tag":144,"props":2288,"children":2290},{"className":2289},[],[2291],{"type":23,"value":1046},{"type":23,"value":2293}," 中的 ",{"type":17,"tag":144,"props":2295,"children":2297},{"className":2296},[],[2298],{"type":23,"value":2118},{"type":23,"value":2300},"和",{"type":17,"tag":144,"props":2302,"children":2304},{"className":2303},[],[2305],{"type":23,"value":2125},{"type":23,"value":435},{"type":17,"tag":25,"props":2308,"children":2309},{},[2310,2312,2317,2318,2323,2325,2330,2332,2336,2338,2343,2344,2349,2351,2356,2357,2362,2363,2368,2370,2374,2376,2381,2382,2387,2388,2393,2395,2400,2401,2406,2408,2413,2415,2420,2421,2426,2428,2433,2435,2439,2441,2446,2448,2453,2454,2460,2462,2467,2469,2473,2474,2479,2481,2486,2488,2492,2494,2498,2500,2505,2507,2512,2513,2518],{"type":23,"value":2311},"若传入的",{"type":17,"tag":144,"props":2313,"children":2315},{"className":2314},[],[2316],{"type":23,"value":174},{"type":23,"value":1990},{"type":17,"tag":144,"props":2319,"children":2321},{"className":2320},[],[2322],{"type":23,"value":387},{"type":23,"value":2324}," 不为 ",{"type":17,"tag":144,"props":2326,"children":2328},{"className":2327},[],[2329],{"type":23,"value":509},{"type":23,"value":2331},", 且为 ",{"type":17,"tag":455,"props":2333,"children":2334},{},[2335],{"type":23,"value":1038},{"type":23,"value":2337},", 此函数会选择使用新传入的 ",{"type":17,"tag":144,"props":2339,"children":2341},{"className":2340},[],[2342],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2345,"children":2347},{"className":2346},[],[2348],{"type":23,"value":387},{"type":23,"value":2350},"。 若传入的",{"type":17,"tag":144,"props":2352,"children":2354},{"className":2353},[],[2355],{"type":23,"value":174},{"type":23,"value":1990},{"type":17,"tag":144,"props":2358,"children":2360},{"className":2359},[],[2361],{"type":23,"value":387},{"type":23,"value":2324},{"type":17,"tag":144,"props":2364,"children":2366},{"className":2365},[],[2367],{"type":23,"value":509},{"type":23,"value":2369},", 但不为 ",{"type":17,"tag":455,"props":2371,"children":2372},{},[2373],{"type":23,"value":1038},{"type":23,"value":2375},", 将会报错。 若传入的",{"type":17,"tag":144,"props":2377,"children":2379},{"className":2378},[],[2380],{"type":23,"value":174},{"type":23,"value":1990},{"type":17,"tag":144,"props":2383,"children":2385},{"className":2384},[],[2386],{"type":23,"value":387},{"type":23,"value":497},{"type":17,"tag":144,"props":2389,"children":2391},{"className":2390},[],[2392],{"type":23,"value":509},{"type":23,"value":2394},", 此函数会检查初始化时的",{"type":17,"tag":144,"props":2396,"children":2398},{"className":2397},[],[2399],{"type":23,"value":2118},{"type":23,"value":1990},{"type":17,"tag":144,"props":2402,"children":2404},{"className":2403},[],[2405],{"type":23,"value":2125},{"type":23,"value":2407},"是否为None, 如果不为 ",{"type":17,"tag":144,"props":2409,"children":2411},{"className":2410},[],[2412],{"type":23,"value":509},{"type":23,"value":2414},",函数将使用初始化时候的值。 若传入的",{"type":17,"tag":144,"props":2416,"children":2418},{"className":2417},[],[2419],{"type":23,"value":174},{"type":23,"value":1990},{"type":17,"tag":144,"props":2422,"children":2424},{"className":2423},[],[2425],{"type":23,"value":387},{"type":23,"value":2427}," 和初始化值都为 ",{"type":17,"tag":144,"props":2429,"children":2431},{"className":2430},[],[2432],{"type":23,"value":509},{"type":23,"value":2434},",函数将报错, 即初始化时若建立了一个 ",{"type":17,"tag":60,"props":2436,"children":2437},{},[2438],{"type":23,"value":527},{"type":23,"value":2440},", 必须在",{"type":17,"tag":144,"props":2442,"children":2444},{"className":2443},[],[2445],{"type":23,"value":1744},{"type":23,"value":2447},"等函数中通过 ",{"type":17,"tag":144,"props":2449,"children":2451},{"className":2450},[],[2452],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2455,"children":2457},{"className":2456},[],[2458],{"type":23,"value":2459},"sccale",{"type":23,"value":2461}," 传入参数。 简而言之， 若某一个 _dist_spec_args1_在初始化时为 ",{"type":17,"tag":144,"props":2463,"children":2465},{"className":2464},[],[2466],{"type":23,"value":509},{"type":23,"value":2468},", 则在计算函数中需传入一个为 ",{"type":17,"tag":455,"props":2470,"children":2471},{},[2472],{"type":23,"value":1038},{"type":23,"value":1917},{"type":17,"tag":455,"props":2475,"children":2476},{},[2477],{"type":23,"value":2478},"dist_spec_args1",{"type":23,"value":2480},"。 若某一个 _dist_spec_args1_在初始化时不为 ",{"type":17,"tag":144,"props":2482,"children":2484},{"className":2483},[],[2485],{"type":23,"value":509},{"type":23,"value":2487},", 可选择传入的 ",{"type":17,"tag":455,"props":2489,"children":2490},{},[2491],{"type":23,"value":2478},{"type":23,"value":2493}," 。 另外，新传入的 ",{"type":17,"tag":60,"props":2495,"children":2496},{},[2497],{"type":23,"value":263},{"type":23,"value":2499}," 只会在此次调用中替代 ",{"type":17,"tag":144,"props":2501,"children":2503},{"className":2502},[],[2504],{"type":23,"value":1046},{"type":23,"value":2506},", 但是不会 ",{"type":17,"tag":60,"props":2508,"children":2509},{},[2510],{"type":23,"value":2511},"overwrite",{"type":23,"value":549},{"type":17,"tag":144,"props":2514,"children":2516},{"className":2515},[],[2517],{"type":23,"value":1046},{"type":23,"value":435},{"type":17,"tag":25,"props":2520,"children":2521},{},[2522,2524,2529,2531,2536,2538,2543,2545,2550,2551,2556,2558,2563,2565,2570,2572,2576],{"type":23,"value":2523},"需注意的是，在",{"type":17,"tag":144,"props":2525,"children":2527},{"className":2526},[],[2528],{"type":23,"value":567},{"type":23,"value":2530}," 中会完成",{"type":17,"tag":144,"props":2532,"children":2534},{"className":2533},[],[2535],{"type":23,"value":174},{"type":23,"value":2537},"与",{"type":17,"tag":144,"props":2539,"children":2541},{"className":2540},[],[2542],{"type":23,"value":387},{"type":23,"value":2544},"的广播. 例: 若 ",{"type":17,"tag":144,"props":2546,"children":2548},{"className":2547},[],[2549],{"type":23,"value":174},{"type":23,"value":497},{"type":17,"tag":455,"props":2552,"children":2553},{},[2554],{"type":23,"value":2555},"shape",{"type":23,"value":2557}," 为 (1,), ",{"type":17,"tag":144,"props":2559,"children":2561},{"className":2560},[],[2562],{"type":23,"value":387},{"type":23,"value":2564}," 为 (2, 1), 此函数return 后 ",{"type":17,"tag":144,"props":2566,"children":2568},{"className":2567},[],[2569],{"type":23,"value":174},{"type":23,"value":2571},"将被 broadcast 成一个(2,1)的 ",{"type":17,"tag":455,"props":2573,"children":2574},{},[2575],{"type":23,"value":1038},{"type":23,"value":435},{"type":17,"tag":25,"props":2578,"children":2579},{},[2580,2582,2587],{"type":23,"value":2581},"检查处理完参数后，就可以开始写计算公式啦！调用 constuctor 中已初始化的算子，计算",{"type":17,"tag":144,"props":2583,"children":2585},{"className":2584},[],[2586],{"type":23,"value":1744},{"type":23,"value":435},{"type":17,"tag":364,"props":2589,"children":2591},{"code":2590},"z = (x - loc) / scale\nreturn -1. \\* (self.abs(z) + self.log(2. \\* scale))\n",[2592],{"type":17,"tag":144,"props":2593,"children":2594},{"__ignoreMap":7},[2595],{"type":23,"value":2590},{"type":17,"tag":364,"props":2597,"children":2599},{"code":2598},"z = (x - loc) / scale\n    return -1. * (self.abs(z) + self.log(2. * scale))\n",[2600],{"type":17,"tag":144,"props":2601,"children":2602},{"__ignoreMap":7},[2603],{"type":23,"value":2598},{"type":17,"tag":25,"props":2605,"children":2606},{},[2607,2609,2614],{"type":23,"value":2608},"完整的 ",{"type":17,"tag":144,"props":2610,"children":2612},{"className":2611},[],[2613],{"type":23,"value":1744},{"type":23,"value":2615}," 代码如下：",{"type":17,"tag":364,"props":2617,"children":2619},{"code":2618},"def _log_prob(self, value, loc=None, scale=None):\n        value = self._check_value(value, \"value\")\n        value = self.cast(value, self.dtype)\n        loc, scale = self._check_param_type(loc, scale)\n        z = (x - loc) / scale\n    return -1. * (self.abs(z) + self.log(2. * scale))\n",[2620],{"type":17,"tag":144,"props":2621,"children":2622},{"__ignoreMap":7},[2623],{"type":23,"value":2618},{"type":17,"tag":25,"props":2625,"children":2626},{},[2627,2629,2634,2636,2642,2644,2650,2651,2657,2658,2664],{"type":23,"value":2628},"在完成 ",{"type":17,"tag":144,"props":2630,"children":2632},{"className":2631},[],[2633],{"type":23,"value":1744},{"type":23,"value":2635}," 之后， 相信大家能够完成类似的",{"type":17,"tag":144,"props":2637,"children":2639},{"className":2638},[],[2640],{"type":23,"value":2641},"_cdf",{"type":23,"value":2643},"， ",{"type":17,"tag":144,"props":2645,"children":2647},{"className":2646},[],[2648],{"type":23,"value":2649},"_log_cdf",{"type":23,"value":382},{"type":17,"tag":144,"props":2652,"children":2654},{"className":2653},[],[2655],{"type":23,"value":2656},"_survival_function",{"type":23,"value":382},{"type":17,"tag":144,"props":2659,"children":2661},{"className":2660},[],[2662],{"type":23,"value":2663},"_log_survival",{"type":23,"value":2665}," 函数。需要注意的是，这四个函数中，择一实现即可。",{"type":17,"tag":41,"props":2667,"children":2669},{"id":2668},"kl散度",[2670],{"type":23,"value":2671},"KL散度",{"type":17,"tag":25,"props":2673,"children":2674},{},[2675,2677,2683],{"type":23,"value":2676},"这一节中向大家介绍 ",{"type":17,"tag":144,"props":2678,"children":2680},{"className":2679},[],[2681],{"type":23,"value":2682},"_kl_loss",{"type":23,"value":2684},"的写法。kl_loss计算两个分布之间的KL散度, 而在讯息系统中称为相对熵, 记为 KL(a||b)。KL散度是两个概率分布 a 和 b 差别的非对称性的度量，或者可以理解他是两个概率分布之间的距离。KL散度中的两个分布的地位是不同的，典型情况下，a 表示数据的真实分布，b 表示数据的理论分布、估计的模型分布、或 b 的近似分布。在很多机器学习的模型中会使用KL散度作为目标函数的一部分作为优化目标。",{"type":17,"tag":25,"props":2686,"children":2687},{},[2688,2690,2695,2697,2702,2704,2709,2711,2717,2719,2725,2726,2732,2734,2738,2739,2744,2746,2750,2751,2756],{"type":23,"value":2689},"当我们使用一个概率分布计算KL散度的时候，他本身是作为KL散度计算里的 ",{"type":17,"tag":60,"props":2691,"children":2692},{},[2693],{"type":23,"value":2694},"a",{"type":23,"value":2696}," 分布。那么不同于其他函数，kl_loss的输入则是KL散度计算中的另一个概率分布。这里，我们把分布 ",{"type":17,"tag":60,"props":2698,"children":2699},{},[2700],{"type":23,"value":2701},"b",{"type":23,"value":2703}," 以参数列表的形式，作为必选参数传入函数中。参数列表的包括两个部分，参数的类型和参数对应的 ",{"type":17,"tag":144,"props":2705,"children":2707},{"className":2706},[],[2708],{"type":23,"value":263},{"type":23,"value":2710}," 。此处我们使用 ",{"type":17,"tag":144,"props":2712,"children":2714},{"className":2713},[],[2715],{"type":23,"value":2716},"dist",{"type":23,"value":2718}," 以_string_ 的形式指定参数类型，",{"type":17,"tag":144,"props":2720,"children":2722},{"className":2721},[],[2723],{"type":23,"value":2724},"loc_b",{"type":23,"value":245},{"type":17,"tag":144,"props":2727,"children":2729},{"className":2728},[],[2730],{"type":23,"value":2731},"scale_b",{"type":23,"value":2733}," 组成分布 ",{"type":17,"tag":60,"props":2735,"children":2736},{},[2737],{"type":23,"value":2701},{"type":23,"value":1917},{"type":17,"tag":144,"props":2740,"children":2742},{"className":2741},[],[2743],{"type":23,"value":263},{"type":23,"value":2745},"。 这样我们就获得了",{"type":17,"tag":60,"props":2747,"children":2748},{},[2749],{"type":23,"value":90},{"type":23,"value":549},{"type":17,"tag":144,"props":2752,"children":2754},{"className":2753},[],[2755],{"type":23,"value":1429},{"type":23,"value":2757},"函数定义：",{"type":17,"tag":364,"props":2759,"children":2761},{"code":2760},"def _kl_loss(self, dist, loc_b, scale_b, loc=None, scale=None):\n",[2762],{"type":17,"tag":144,"props":2763,"children":2764},{"__ignoreMap":7},[2765],{"type":23,"value":2760},{"type":17,"tag":25,"props":2767,"children":2768},{},[2769,2771,2775,2777,2781,2783,2787,2789,2795,2797,2802],{"type":23,"value":2770},"因为只有当分布 ",{"type":17,"tag":60,"props":2772,"children":2773},{},[2774],{"type":23,"value":2701},{"type":23,"value":2776}," 同为 ",{"type":17,"tag":60,"props":2778,"children":2779},{},[2780],{"type":23,"value":90},{"type":23,"value":2782}," 分布时我们有对应KL散度的解析解公式，我们调用 ",{"type":17,"tag":60,"props":2784,"children":2785},{},[2786],{"type":23,"value":829},{"type":23,"value":2788}," 中 ",{"type":17,"tag":144,"props":2790,"children":2792},{"className":2791},[],[2793],{"type":23,"value":2794},"check_distribution_name",{"type":23,"value":2796}," 对 ",{"type":17,"tag":144,"props":2798,"children":2800},{"className":2799},[],[2801],{"type":23,"value":2716},{"type":23,"value":2803}," 判定输入的分布是我们支持的类型。",{"type":17,"tag":364,"props":2805,"children":2807},{"code":2806},"check_distribution_name（dist, \"Laplace\"）\n",[2808],{"type":17,"tag":144,"props":2809,"children":2810},{"__ignoreMap":7},[2811],{"type":23,"value":2806},{"type":17,"tag":25,"props":2813,"children":2814},{},[2815,2817,2822,2823,2828,2829,2833,2835,2840],{"type":23,"value":2816},"之后，我们检查",{"type":17,"tag":144,"props":2818,"children":2820},{"className":2819},[],[2821],{"type":23,"value":2724},{"type":23,"value":382},{"type":17,"tag":144,"props":2824,"children":2826},{"className":2825},[],[2827],{"type":23,"value":2731},{"type":23,"value":1314},{"type":17,"tag":455,"props":2830,"children":2831},{},[2832],{"type":23,"value":1038},{"type":23,"value":2834},", 并将其类型转换为",{"type":17,"tag":144,"props":2836,"children":2838},{"className":2837},[],[2839],{"type":23,"value":814},{"type":23,"value":435},{"type":17,"tag":364,"props":2842,"children":2844},{"code":2843},"loc_b = self._check_value(loc_b, 'loc_b')\n    loc_b = self.cast(loc_b, self.parameter_type)\n    scale_b = self._check_value(scale_b, 'scale_b')\n    scale_b = self.cast(scale_b, self.parameter_type)\n",[2845],{"type":17,"tag":144,"props":2846,"children":2847},{"__ignoreMap":7},[2848],{"type":23,"value":2843},{"type":17,"tag":25,"props":2850,"children":2851},{},[2852,2854,2859,2860,2865],{"type":23,"value":2853},"最后检查 ",{"type":17,"tag":144,"props":2855,"children":2857},{"className":2856},[],[2858],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2861,"children":2863},{"className":2862},[],[2864],{"type":23,"value":387},{"type":23,"value":435},{"type":17,"tag":364,"props":2867,"children":2868},{"code":2201},[2869],{"type":17,"tag":144,"props":2870,"children":2871},{"__ignoreMap":7},[2872],{"type":23,"value":2201},{"type":17,"tag":25,"props":2874,"children":2875},{},[2876],{"type":23,"value":2877},"完成参数检查后，就可以开始写计算公式了。",{"type":17,"tag":364,"props":2879,"children":2881},{"code":2880},"loc_diff = self.abs(loc - loc_b)\n    scale_log_diff = self.log(scale) - self.log(scale_b)\n    return (-1 * scale_log_diff +\\\n            loc_diff / scale_b - 1. +\\\n            self.exp(-1 * loc_diff / scale + scale_log_diff))\n",[2882],{"type":17,"tag":144,"props":2883,"children":2884},{"__ignoreMap":7},[2885],{"type":23,"value":2880},{"type":17,"tag":25,"props":2887,"children":2888},{},[2889,2891,2896],{"type":23,"value":2890},"完整的",{"type":17,"tag":144,"props":2892,"children":2894},{"className":2893},[],[2895],{"type":23,"value":2682},{"type":23,"value":2897},"代码如下：",{"type":17,"tag":364,"props":2899,"children":2901},{"code":2900},"def _kl_loss(self, dist, loc_b, scale_b, loc=None, scale=None):\n        check_distribution_name（dist, 'Laplace'）\n        loc_b = self._check_value(loc_b, 'loc_b')\n        loc_b = self.cast(loc_b, self.parameter_type)\n        scale_b = self._check_value(scale_b, 'scale_b')\n        scale_b = self.cast(scale_b, self.parameter_type)\n        loc, scale = self._check_param_type(loc, scale)\n        loc_diff = self.abs(loc - loc_b)\n        scale_log_diff = self.log(scale) - self.log(scale_b)\n        return (-1 * scale_log_diff +\\\n            loc_diff / scale_b - 1. +\\\n            self.exp(-1 * loc_diff / scale + scale_log_diff))\n",[2902],{"type":17,"tag":144,"props":2903,"children":2904},{"__ignoreMap":7},[2905],{"type":23,"value":2900},{"type":17,"tag":41,"props":2907,"children":2909},{"id":2908},"采样-sample",[2910],{"type":23,"value":2911},"采样 Sample",{"type":17,"tag":25,"props":2913,"children":2914},{},[2915,2917,2922,2924,2929,2931,2937,2938,2942,2944,2950,2952,2957,2959,2964,2965,2970],{"type":23,"value":2916},"最后，我们介绍采样函数 ",{"type":17,"tag":144,"props":2918,"children":2920},{"className":2919},[],[2921],{"type":23,"value":1442},{"type":23,"value":2923}," 的写法。此函数接受一个类型为 ",{"type":17,"tag":455,"props":2925,"children":2926},{},[2927],{"type":23,"value":2928},"tuple",{"type":23,"value":2930}," 的shape， 默认值为空值 ",{"type":17,"tag":144,"props":2932,"children":2934},{"className":2933},[],[2935],{"type":23,"value":2936},"()",{"type":23,"value":435},{"type":17,"tag":60,"props":2939,"children":2940},{},[2941],{"type":23,"value":263},{"type":23,"value":2943}," 可选择传入。类似地，我们首先进行参数检查。我们调用基类算子 ",{"type":17,"tag":144,"props":2945,"children":2947},{"className":2946},[],[2948],{"type":23,"value":2949},"_check_tuple",{"type":23,"value":2951}," 对",{"type":17,"tag":144,"props":2953,"children":2955},{"className":2954},[],[2956],{"type":23,"value":2555},{"type":23,"value":2958},"进行检查, 并检查是否传入了新的 ",{"type":17,"tag":144,"props":2960,"children":2962},{"className":2961},[],[2963],{"type":23,"value":174},{"type":23,"value":382},{"type":17,"tag":144,"props":2966,"children":2968},{"className":2967},[],[2969],{"type":23,"value":387},{"type":23,"value":435},{"type":17,"tag":364,"props":2972,"children":2974},{"code":2973},"def _sample(self, shape=(), loc=None, scale=None):\n        shape = self._check_tuple(shape, \"shape\")\n        loc, scale = self._check_param_type(loc, scale)\n",[2975],{"type":17,"tag":144,"props":2976,"children":2977},{"__ignoreMap":7},[2978],{"type":23,"value":2973},{"type":17,"tag":25,"props":2980,"children":2981},{},[2982,2984,2989],{"type":23,"value":2983},"首先计算样本的形状, original_shape 为 [shape , batch_shape]。 若传入的shape 与batch_shape 均为scalar, 即 ",{"type":17,"tag":144,"props":2985,"children":2987},{"className":2986},[],[2988],{"type":23,"value":2936},{"type":23,"value":2990},"，我们在此处增加一维。",{"type":17,"tag":364,"props":2992,"children":2994},{"code":2993},"original_shape = shape + self.shape(loc)\n    if original_shape == ():\n        sample_shape = (1,)\n    else:\n        sample_shape = original_shape\n",[2995],{"type":17,"tag":144,"props":2996,"children":2997},{"__ignoreMap":7},[2998],{"type":23,"value":2993},{"type":17,"tag":25,"props":3000,"children":3001},{},[3002,3004,3009,3011,3015],{"type":23,"value":3003},"根据上面介绍的抽样方法，这里我们利用 ",{"type":17,"tag":60,"props":3005,"children":3006},{},[3007],{"type":23,"value":3008},"uniform",{"type":23,"value":3010}," 抽样算子，变换得到实现 ",{"type":17,"tag":60,"props":3012,"children":3013},{},[3014],{"type":23,"value":90},{"type":23,"value":3016}," 抽样，并将得到的samples 类型转换为分布类型，即self.dtype。",{"type":17,"tag":364,"props":3018,"children":3020},{"code":3019},"low = self.const(-1.0 + self.eps)\n    high = self.const(1.0)\n    uniform_samples = self.uniform(sample_shape, low, high, self.seed)\n    samples = (loc - scale * self.sign(uniform_samples) *\n            self.log1p(-1. * self.abs(uniform_samples)))\n    samples = self.cast(samples, self.dtype)\n",[3021],{"type":17,"tag":144,"props":3022,"children":3023},{"__ignoreMap":7},[3024],{"type":23,"value":3019},{"type":17,"tag":25,"props":3026,"children":3027},{},[3028],{"type":23,"value":3029},"最后，若original_shape 为()，降维：",{"type":17,"tag":364,"props":3031,"children":3033},{"code":3032},"if original_shape == ():\n        return self.squeeze(samples)\n    return samples\n",[3034],{"type":17,"tag":144,"props":3035,"children":3036},{"__ignoreMap":7},[3037],{"type":23,"value":3032},{"type":17,"tag":25,"props":3039,"children":3040},{},[3041],{"type":23,"value":3042},"完整的代码如下：",{"type":17,"tag":364,"props":3044,"children":3046},{"code":3045},"def _sample(self, shape=(), loc=None, scale=None):\n        shape = self._check_tuple(shape, \"shape\")\n        loc, scale = self._check_param_type(loc, scale)\n        original_shape = shape + self.shape(loc)\n        if original_shape == ():\n            sample_shape = (1,)\n        else:\n            sample_shape = original_shape\n        low = self.const(-1.0 + self.eps)\n        high = self.const(1.0)\n        uniform_samples = self.uniform(sample_shape, low, high, self.seed)\n        samples = (loc - scale * self.sign(uniform_samples) *\n                self.log1p(-1. * self.abs(uniform_samples)))\n        samples = self.cast(samples, self.dtype)\n        if original_shape == ():\n            return self.squeeze(samples)\n        return samples\n",[3047],{"type":17,"tag":144,"props":3048,"children":3049},{"__ignoreMap":7},[3050],{"type":23,"value":3045},{"type":17,"tag":25,"props":3052,"children":3053},{},[3054],{"type":23,"value":3055},"Congrats!",{"type":17,"tag":25,"props":3057,"children":3058},{},[3059,3061,3065],{"type":23,"value":3060},"到这里教程就结束了，恭喜你完成了第一个自定义概率分布。",{"type":17,"tag":60,"props":3062,"children":3063},{},[3064],{"type":23,"value":97},{"type":23,"value":3066},"作为开源社区期待你加入更多的概率分布，让我们一起来扩充概率分布类吧！",{"type":17,"tag":25,"props":3068,"children":3069},{},[3070,3075,3077,3081,3083,3087],{"type":17,"tag":60,"props":3071,"children":3072},{},[3073],{"type":23,"value":3074},"作者介绍：",{"type":23,"value":3076}," 作者邓洵（华为多伦多异构编译器实验室实习生）目前就读于加拿大多伦多大学，参与设计与开发",{"type":17,"tag":60,"props":3078,"children":3079},{},[3080],{"type":23,"value":97},{"type":23,"value":3082},"概率分布采用库，是",{"type":17,"tag":60,"props":3084,"children":3085},{},[3086],{"type":23,"value":97},{"type":23,"value":3088},"开源社区概率编程模块的重要代码贡献者。",{"title":7,"searchDepth":3090,"depth":3090,"links":3091},4,[3092,3093,3094,3103,3104,3111,3112],{"id":43,"depth":2093,"text":43},{"id":102,"depth":2093,"text":102},{"id":224,"depth":2093,"text":227,"children":3095},[3096,3097,3098,3099,3100,3101,3102],{"id":439,"depth":3090,"text":442},{"id":665,"depth":3090,"text":668},{"id":749,"depth":3090,"text":752},{"id":811,"depth":3090,"text":814},{"id":912,"depth":3090,"text":915},{"id":966,"depth":3090,"text":966},{"id":999,"depth":3090,"text":999},{"id":1243,"depth":2093,"text":1243},{"id":1351,"depth":2093,"text":1354,"children":3105},[3106,3108],{"id":1644,"depth":3107,"text":1647},3,{"id":1866,"depth":3107,"text":1869,"children":3109},[3110],{"id":567,"depth":3090,"text":567},{"id":2668,"depth":2093,"text":2671},{"id":2908,"depth":2093,"text":2911},"markdown","content:technology-blogs:zh:326.md","content","technology-blogs/zh/326.md","technology-blogs/zh/326","md",1776506128156]