zoukankan      html  css  js  c++  java
  • Image Processing 必备(十):Imgaug之使用随机分布作为参数

    Date:2020-09-08

    官方教程:https://nbviewer.jupyter.org/github/aleju/imgaug-doc/blob/master/notebooks/C01%20-%20Using%20Probability%20Distributions%20as%20Parameters.ipynb

    在大多数情况下,采用简单均匀分布的增强就足以产生良好的结果。

    在之前的示例中,会在一些增强方法中看到使用随机分别作为参数的情况。例如,Affine(rotate=(-30, 30)),会在(-30, 30)之间生成随机值作为旋转的角度作用于图像上;Affine(rotate=-30)会始终让图像旋转-30度。

    而有时,使用不同于均匀分布的概率分布是明智的。例如使用高斯,拉普拉斯,泊松分布等在这种情况下可以使用Affine(rotate=imgaug.parameters.Normal(0, 5.0))生成服从高斯分布的随机数。

    生成&&使用随机参数

    确定与随机参数的设置:

    • 标量值被解释为非随机/确定性值(imgaug.parameters.Deterministic);

    • 元组的形式(a, b)经常解释为均匀分布imgaug.parameters.Uniform或者imgaug.parameters.DiscreteUniform;

    • 列表被解释为要从中取样的一组值imgaug.parameters.choice

    下面的示例中通过Multiply()函数演示了标量、元组和列表构成参数的输出。

     1 import numpy as np
     2 import imgaug as ia
     3 from imgaug import augmenters as iaa
     4 from imgaug import parameters as iap
     5 %matplotlib inline
     6 np.set_printoptions(precision=2, linewidth=125, suppress=False)
     7 ia.seed(1)
     8  9 aug = iaa.Multiply(mul=1)
    10 print(aug.mul)
    11 12 aug = iaa.Multiply(mul=(0.5, 1.5))
    13 print(aug.mul)
    14 15 aug = iaa.Multiply(mul=[0.5, 1.0, 1.5])
    16 print(aug.mul)
    Deterministic(int 1)
    Uniform(Deterministic(float 0.50000000), Deterministic(float 1.50000000))
    Choice(a=[0.5, 1.0, 1.5], replace=True, p=None)

    另外,可以直接提供一个确定的参数Deterministic(1):

    1 aug = iaa.Multiply(mul=iap.Deterministic(1))
    2 print(aug.mul)
    Deterministic(int 1)

    所有随机参数提供一个方法:draw_samples(size, [random_state]),可以用于从参数中采样随机值。生成的数组具有size的形状。注意,random_state的容忍度很高,它也接受整数种子。

    1 print(iap.Deterministic(1).draw_samples(10))
    2 print(iap.Deterministic(1).draw_samples(10, random_state=1))
    3 print(iap.Deterministic(1).draw_samples(10, random_state=1))
    4 print(iap.Deterministic(1).draw_samples(10, random_state=2))
    [1 1 1 1 1 1 1 1 1 1]
    [1 1 1 1 1 1 1 1 1 1]
    [1 1 1 1 1 1 1 1 1 1]
    [1 1 1 1 1 1 1 1 1 1]

    从上述代码运行结果中可以看出,在以1为确定参数中采样10次随机值,输出10个1。但从结果中暂时看不出random_state的作用。

    下面代码使用DeterministicList方法,用于生成确定的多值序列。之前Deterministic方法仅适用于一个值。

    1 print("no random_state:", iap.DeterministicList([1,2,3]).draw_samples(10))
    2 print("random_state=1:", iap.DeterministicList([1,2,3]).draw_samples(10, random_state=1))
    3 print("random_state=2:", iap.DeterministicList([1,2,3]).draw_samples(10, random_state=2))
    no random_state: [1 2 3 1 2 3 1 2 3 1]
    random_state=1: [1 2 3 1 2 3 1 2 3 1]
    random_state=2: [1 2 3 1 2 3 1 2 3 1]

    但从返回结果中,也没有看出random_state在其中起到的作用!

    • Uniform:均匀分布

    1 print(iap.Uniform(0, 1.0).draw_samples(10))
    2 print(iap.Uniform(0, 1.0).draw_samples(10, random_state=1))
    3 print(iap.Uniform(0, 1.0).draw_samples(10, random_state=1))
    4 print(iap.Uniform(0, 1.0).draw_samples(10, random_state=2))
    5 print(iap.Uniform(0, 1.0).draw_samples(10, random_state=1))
    [0.49 0.21 0.25 0.65 0.18 0.75 0.22 0.09 0.55 0.46]
    [0.43 0.76 0.83 0.83 0.88 0.29 0.2 0.79 0.34 0.31]
    [0.43 0.76 0.83 0.83 0.88 0.29 0.2 0.79 0.34 0.31]
    [0.89 0.09 0.61 0.64 0.33 0.8 0.19 0.1 0.01 0.7 ]
    [0.43 0.76 0.83 0.83 0.88 0.29 0.2 0.79 0.34 0.31]

    从上述返回结果可以看出, random_state的作用相当于随机种子的作用表示随机状态,同一随机状态会生成相同的随机数值。 设置的随机状态的数值应该就是random_state容忍度的含义吧。

    • Choice: 随机抽取数值

    1 print(iap.Choice([0, 0.5, 1.0]).draw_samples(10))
    2 print(iap.Choice([0, 0.5, 1.0]).draw_samples(10, random_state=1))
    3 print(iap.Choice([0, 0.5, 1.0]).draw_samples(10, random_state=2))
    4 print(iap.Choice([0, 0.5, 1.0]).draw_samples(10, random_state=1))
    [1.  0.  0.5 1.  0.  0.5 0.5 0.  0.  0. ]
    [0.5 1. 0.5 0.5 0.5 0.5 1. 1. 1. 1. ]
    [0.5 1. 0. 0. 0. 1. 0. 0. 0.5 0.5]
    [0.5 1. 0.5 0.5 0.5 0.5 1. 1. 1. 1. ]
    • Binomial:二项分布

    之前的示例在draw_samples()参数中size均使用的标量。实际上, size也可以是一个tuple,用于生成矩阵。

    1 print(iap.Binomial(p=0.5).draw_samples(4*4, random_state=1))
    2 print(iap.Binomial(p=0.7).draw_samples((4, 4), random_state=1))
    [0 0 1 1 1 1 0 0 1 0 0 1 1 0 1 1]
    [[1 1 0 0]
    [0 0 1 1]
    [0 1 1 0]
    [1 1 1 1]]
    • 随机参数支持基本的数学运算

    可以在随机数的基础上进行加减乘除等数学运算。

    1 print((iap.Deterministic(1) + 1).draw_samples(10))
    2 print((iap.Deterministic(1) - 1).draw_samples(10))
    3 print((iap.Deterministic(1) / 2).draw_samples(10))
    4 print((iap.Deterministic(1) * 2).draw_samples(10))
    5 print((iap.Deterministic(1) ** 2).draw_samples(10))
    [2 2 2 2 2 2 2 2 2 2]
    [0 0 0 0 0 0 0 0 0 0]
    [0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]
    [2 2 2 2 2 2 2 2 2 2]
    [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
    1 print(iap.Choice([1, 2, 3]).draw_samples(10))
    2 print((iap.Choice([1, 2, 3]) * 2).draw_samples(10))
    [2 2 2 2 3 2 2 2 2 1]
    [6 2 6 6 2 6 6 2 4 2]

    离散随机变量

    之前介绍的案例中,要么使用连续概率分布(返回浮点值),要么使用混合概率分布(返回各种类型的数据)。 还有三种离散概率分布,返回整型。

    • 离散随机分布DiscreteUniform

    • 二项分布Binomial

    • 泊松分布Poisson

    1 print(iap.DiscreteUniform(0, 3).draw_samples(20))
    2 print(iap.Binomial(p=0.3).draw_samples(20))
    3 print(iap.Poisson(lam=1).draw_samples(20))
    [0 3 0 1 0 1 3 3 1 0 3 2 1 1 0 2 1 0 2 1]
    [1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0]
    [0 1 0 2 2 2 3 0 4 0 2 1 2 1 0 1 1 3 1 3]

    生成的随机变量均为离散随机变量。

    另外,可以使用Discretize方法将浮点型四舍五入为整型变量。

    1 print("Continuous:", iap.Normal(0.0, 1.0).draw_samples(20))
    2 print("Discrete:  ", iap.Discretize(iap.Normal(0.0, 1.0)).draw_samples(20))
    Continuous: [-0.62  1.05 -0.64 -0.79  0.04  0.48 -1.67 -0.78 -1.06  0.7  -0.22 -0.18  0.01  0.09 -1.67 -0.22 -0.97 -0.51  1.43 -2.42]
    Discrete:   [ 0 -1 -1 0 1 1 0 -1 3 2 -1 -2 1 0 -1 0 1 1 -2 1]

    Clip 设置上下限

    如果需要给随机变量设置上下限,可以使用Clip方法。

    1 uniform = iap.Uniform(-2, 2)
    2 print(uniform.draw_samples(15))
    3 print(iap.Clip(uniform, -1, None).draw_samples(15))
    4 print(iap.Clip(uniform, None, 1).draw_samples(15))
    5 print(iap.Clip(uniform, -1, 1).draw_samples(15))
    [-1.42 -1.21 -1.68 -0.14 -1.8   0.26  1.96  0.92 -0.97  1.    1.39 -0.68 -1.69 -0.27 -1.43]
    [-0.51 -0.94 1.45 -0.96 -0.9 -1.   1.12 0.38 0.11 -1.   1.34 -0.45 -0.84 -1.   0.35]
    [ 0.1 -0.25 1.   -1.21 -0.1   0.94 -0.64 -1.49 0.27 0.3 -0.45 -0.5 -0.95 -1.94 -1.47]
    [ 1.   -0.43 1.   1.   1.   -0.46 -1.   0.79 -0.6 -1.   -1.   1.   -0.43 1.   -1. ]

    从返回的结果可以看出,第二行返回结果最小值为-1,第三行返回结果最大值为1,第四行返回结果介于±1之间。

    值得注意的是Clip虽然可以将定义的最小/最大值以下/以上的所有值投影到最小/最大值上,剪辑可能导致失真的概率密度。

    1 plot = iap.Clip(uniform, -1, 1).draw_distribution_graph()
    2 plot_large = ia.imresize_single_image(plot, 2.0)
    3 ia.imshow(plot_large)

    png

    上述代码使用draw_distribution_graph的方法获取Clip返回数值的概率分布。从图中可以看出,±1的概率分布明显高于其他数值。

    改变信号

    翻转信号是最简易的方式去改变信号的正负:

    1 print(iap.Poisson(lam=1).draw_samples(20, random_state=1))
    2 print((-1) * iap.Poisson(lam=1).draw_samples(20, random_state=1))
    [1 4 0 1 0 2 1 1 2 0 1 1 0 1 1 2 0 0 3 2]
    [-1 -4 0 -1 0 -2 -1 -1 -2 0 -1 -1 0 -1 -1 -2 0 0 -3 -2]

    可以取绝对值,如果你只想要正数:

    1 print(iap.Normal(0, 1.0).draw_samples(15, random_state=1))
    2 print(iap.Absolute(iap.Normal(0, 1.0)).draw_samples(15, random_state=1))
    [-0.8   0.17  1.66 -0.61 -0.03 -0.33 -0.73  0.41  1.24 -0.97  1.2   0.54 -0.72 -1.08  0.77]
    [0.8 0.17 1.66 0.61 0.03 0.33 0.73 0.41 1.24 0.97 1.2 0.54 0.72 1.08 0.77]

    RandomSign:以p_positive概率让数值变为正数,以1-positive概率翻转信号。

    1 print(iap.Normal(0, 1.0).draw_samples(15, random_state=1))
    2 print(iap.RandomSign(iap.Normal(0,1.0), p_positive=0.8).draw_samples(15, random_state=1))
    [-0.8   0.17  1.66 -0.61 -0.03 -0.33 -0.73  0.41  1.24 -0.97  1.2   0.54 -0.72 -1.08  0.77]
    [ 0.8   0.17  1.66  0.61  0.03  0.33  0.73  0.41  1.24  0.97  1.2   0.54  0.72  1.08 -0.77]
    1 rnd_sign = iap.RandomSign(iap.Normal(0, 1.0), p_positive=0.8)
    2 print("15 random samples: ", rnd_sign.draw_samples(15))
    15 random samples:  [ 0.8   0.17  1.66  0.61  0.03  0.33  0.73  0.41  1.24  0.97  1.2   0.54  0.72  1.08 -0.77]

    ForceSign:具有两个参数:

    • 其一,positive用于控制输出值具有的正负号;

    • 其二,mode用于控制符号是否翻转,当mode="invert"时,会给信号乘以-1;当mode="reroll"时,只对符号错误的值重新采样,从而保持概率分布的密度不变(除去正/负的值)。

    1 force_sign_invert = iap.ForceSign(iap.Choice([-2, -1, 5, 10]), positive=False, mode="invert")
    2 force_sign_reroll = iap.ForceSign(iap.Choice([-2, -1, 5, 10]), positive=False, mode="reroll")
    3 print(force_sign_invert.draw_samples(15))
    4 print(force_sign_reroll.draw_samples(15))
    [ -1  -2  -2  -2  -2  -1  -5  -5  -5 -10  -1 -10 -10  -1  -1]
    [ -1  -2  -1  -2  -2  -2  -1  -1  -2 -10  -2  -2  -2  -1  -1]

    下面的示例代码将会探讨ForceSign中参数的作用:* "positive" && "mode":("invert"&&"reroll") *

    • positive为True;mode为invert的情况:

    1 param = iap.ForceSign(iap.Normal(4, 2.0), positive=True, mode="invert")
    2 plot = param.draw_distribution_graph(bins=400)
    3 plot_large = ia.imresize_single_image(plot, 2.0)
    4 ia.imshow(plot_large)

    png

    从代码中可以看出,生成的是一个均值为4,方差为2的正太分布图像。但从图中可以看出,[0, 4]的概率分布要大于[4, 8]的概率分布。这是由于[-∞, 0]的数值被乘以-1(使用mode="invert"的效果),变为正数。 同时由于[-4, 0]的概率密度相对较大(类比于[8, 12]),也就是说,概率密度增大的只有[0, 4]这段。

    • positive为true;mode为reroll的情况:

    1 param = iap.ForceSign(iap.Normal(4, 2.0), positive=True, mode="reroll")
    2 plot = param.draw_distribution_graph(bins=400)
    3 plot_large = ia.imresize_single_image(plot, 2.0)
    4 ia.imshow(plot_large)

    png

    当mode使用reroll时,对于生成的以4为均值,2为方差的正态分布。可以看出,输出无负数部分,[0, 4]与[4, 8]几乎具有相同的概率分布,整体上仍服从正态分布

    • positive为False; mode为invert时:

    param = iap.ForceSign(iap.Normal(4, 2.0), positive=False, mode="invert")
    plot = param.draw_distribution_graph(bins=400)
    plot_large = ia.imresize_single_image(plot, 2.0)
    ia.imshow(plot_large)

    png

    可以看出,当mode为invert时,positive的取False得到的概率分布图实际上与取True时是对称的。

    • positive为False;mode为reroll的情况:

    1 param = iap.ForceSign(iap.Normal(4, 2.0), positive=False, mode="reroll")
    2 plot = param.draw_distribution_graph(bins=400)
    3 plot_large = ia.imresize_single_image(plot, 2.0)
    4 ia.imshow(plot_large)

    png

    另外,Positive()和Negative()两个函数相当于是ForceSign(positive=True) 和 ForceSign(positive=False)实现的捷径。

    1 positive_invert = iap.Positive(iap.Choice([-2, -1, 5, 10]), mode="invert")
    2 positive_reroll = iap.Positive(iap.Choice([-2, -1, 5, 10]), mode="reroll")
    3 print(positive_invert.draw_samples(15))
    4 print(positive_reroll.draw_samples(15))
    [ 5  2  5 10 10  5 10  2  2 10  1  5  1  2  2]
    [ 5  5 10  5 10 10  5 10  2 10 10 10  5  5 10]

    结合概率分布

    imgaug允许组合概率分布。简单来说,可以将随机生成的数值作为某种概率分布的参数;也可以将概率分布产生的数值作为随机列表。下述两个示例将会演示这两种情况。

    • Situation 1:

    将Choice随机生成的数值作为Normal正态分布的均值参数。

    1 param = iap.Normal(iap.Choice([2, -2]), 1.0)
    2 plot = param.draw_distribution_graph()
    3 plot_large = ia.imresize_single_image(plot, 2.0)
    4 ia.imshow(plot_large)

    png

    可以看出,生成了双峰的正态分布,一个以-2为均值,一个以2为均值。

    • Situation 2:

    将Normal生成的正态分布作为Choice的随机选择的列表。

    1 param = iap.Choice([iap.Normal(-1, 1.0), iap.Normal(1, 0.1)])
    2 plot = param.draw_distribution_graph()
    3 plot_large = ia.imresize_single_image(plot, 2.0)
    4 ia.imshow(plot_large)

    png

    利用随机参数生成椒盐噪声

     1 def apply_coarse_salt_and_pepper(image, p, size_px):
     2     # mask where to replace
     3     mask = iap.Binomial(p)
     4     
     5     # make the mask coarser
     6     mask_coarse = iap.FromLowerResolution(other_param=mask, size_px=size_px)
     7 
     8     # the noise to use as replacements, mostly close to 0.0 and 1.0
     9     replacement = iap.Beta(0.5, 0.5)
    10     
    11     # project noise to uint8 value range
    12     replacement = replacement * 255
    13 
    14     # replace masked areas with noise
    15     return iaa.ReplaceElementwise(
    16         mask=mask_coarse,
    17         replacement=replacement
    18     )(image=image)
    19 
    20 import imageio 
    21 image = imageio.imread("samoye.jpg")
    22 image_aug = apply_coarse_salt_and_pepper(image, 0.05, 20)
    23 image_resize = ia.imresize_single_image(np.hstack([image, image_aug]), 4.0)
    24 ia.imshow(image_resize)

    png

    整理总结

    本节主要介绍了随机参数的使用,包含生成随机变量(连续-离散),限制生成随机变量的上下限,以及改变信号的一些方法,同时,随机变量与概率分布也可以结合使用。

    确定参数:

    • 确定参数:Deterministic

    • 确定参数列表:DeterministicList

    获取其中的值:draw_samples(size, random_state)

    • size: 从分布中取多少个参数;

    • random_state: 分布随机种子;

    获取概率分布:draw_distribution_graph()

    分布:

    • uniform 均匀分布

    • Choice 随机抽取

    • Binomial 二项分布

    • Poisson 泊松分布

    • DiscreteUniform 离散均匀分布

    • Normal 正态分布

    限制上下限:

    • Clip

    改变信号:

    • Absolute 绝对值

    • RandomSign ( p_positive 依概率)

    • ForceSign (positive, mode[invert&&reroll])

    概率分布与随机数生成相互套用

  • 相关阅读:
    RegularExpressions(正则表达式)
    IntelliJ Idea工具使用
    JavaScript总结
    Ajax技术基础
    配置Nginx作为反向代理服务器
    SpringBoot下的Dubbo和Zookeeper整合
    springSecurity初识练气初期
    Spring Security拦截器加载流程分析练气中期
    Spring Security认证流程分析练气后期
    springBoot整合spring security+JWT实现单点登录与权限管理前后端分离筑基中期
  • 原文地址:https://www.cnblogs.com/monologuesmw/p/13691799.html
Copyright © 2011-2022 走看看