使用 tf.where(或 np.where)以输入为条件随机绘制
Using tf.where (or np.where) to draw randomly conditional on an input
我有一个仅包含 1 和 0 的 TensorFlow 向量,例如 a = [0, 0, 0, 1, 0, 1]
,并且以 a
的值为条件,我想绘制新的随机值 0 或 1。如果值a
的值为 1,我想绘制一个新值,但如果 a
的值为 0,我不想管它。所以我试过了:
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
# random draw of zeros and ones
a = tfd.Binomial(total_count = 1.0, probs = 0.5).sample(6)
这给了我 <tf.Tensor: shape=(6,), dtype=float32, numpy=array([0., 0., 0., 1., 0., 1.], dtype=float32)>
然后如果我重绘
# redraw with a different probability if value is 1. in the original draw
b = tf.where(a == 1.0, tfd.Binomial(total_count = 1., probs = 0.5).sample(1), a)
我希望 tf.where
给我一个新向量 b
平均而言,一半的 1 变成 0 但它要么 returns [=] 的副本16=] 或全 0 的向量。示例输出将是 b = [0, 0, 0, 0, 0, 0]
、b = [0, 0, 0, 0, 0, 1]
、b = [0, 0, 0, 1, 0, 0]
或 b = [0, 0, 0, 1, 0, 1]
之一。我当然可以只使用 b = tfd.Binomial(total_count = 1.0, probs = 0.25).sample(6)
但在我的特定情况下,原始向量的顺序很重要。
更一般的情况可能会使用不同的分布,因此无法轻松使用按位运算。例如
# random draw of normals
a = tfd.Normal(loc = 0., scale = 1.).sample(6)
# redraw with a different scale if value is greater than zero in the original draw
b = tf.where(a > 0, tfd.Normal(loc = 0., scale = 2.).sample(1), a)
方法 1:
未测试,但我认为中间参数应该是与原始参数匹配的张量。例如。 6 个元素:
首先,制作第二个长度相同的随机序列:
a2 = tfd.Binomial(total_count = 1.0, probs = 0.5).sample(6)
注意:如果您需要不同的概率,只需在创建 a2 时使用该概率即可。
prob = 0.3
a2 = tfd.Binomial(total_count = 1.0, probs = prob).sample(6)
然后:
b = tf.where(a == 1.0, a2, a)
解释:
a2 中的值与 a 为 0 的情况无关,并且在 a 为 1 的情况下平均为“概率”。
方法 2:
如果这不起作用,则需要将第一个参数映射到 [true, false, ..] 的张量:
def pos(n):
return n > 0
cond = list(map(pos,a)) # I don't have TensorFlow handy; may need to replace `list` with appropriate function to create a Tensor.
b = tf.where(cond, a2, 0.0)
方法 3:
已测试。不使用 tf.where
.
首先,制作第二个长度相同的随机序列:
a2 = tfd.Binomial(total_count = 1.0, probs = prob).sample(6)
然后结合两者,“按位与”对应的元素:
def and2(a, b):
return (a & b)
b = list(map(and2, a, a2))
注意:也可以使用任何其他函数来组合两个相应的元素。
示例数据:
a = [0,0,1,1]
a2 = [0,1,0,1]
结果:
b = [0,0,0,1]
解释:
a2 中的值与 a 为 0 的情况无关,并且在 a 为 1 的情况下平均为“概率”。
tf.where 正在广播您的第二个参数,形状 [1] 值最多为六个向量 [6]。第二个值放在现有 1 的位置:1(在这种情况下输出匹配 a)或 0(在这种情况下全为零)。在每个站点为独立重采样值绘制六个样本。
考虑 tfd.Bernoulli 0/1 个样本。
我有一个仅包含 1 和 0 的 TensorFlow 向量,例如 a = [0, 0, 0, 1, 0, 1]
,并且以 a
的值为条件,我想绘制新的随机值 0 或 1。如果值a
的值为 1,我想绘制一个新值,但如果 a
的值为 0,我不想管它。所以我试过了:
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
# random draw of zeros and ones
a = tfd.Binomial(total_count = 1.0, probs = 0.5).sample(6)
这给了我 <tf.Tensor: shape=(6,), dtype=float32, numpy=array([0., 0., 0., 1., 0., 1.], dtype=float32)>
然后如果我重绘
# redraw with a different probability if value is 1. in the original draw
b = tf.where(a == 1.0, tfd.Binomial(total_count = 1., probs = 0.5).sample(1), a)
我希望 tf.where
给我一个新向量 b
平均而言,一半的 1 变成 0 但它要么 returns [=] 的副本16=] 或全 0 的向量。示例输出将是 b = [0, 0, 0, 0, 0, 0]
、b = [0, 0, 0, 0, 0, 1]
、b = [0, 0, 0, 1, 0, 0]
或 b = [0, 0, 0, 1, 0, 1]
之一。我当然可以只使用 b = tfd.Binomial(total_count = 1.0, probs = 0.25).sample(6)
但在我的特定情况下,原始向量的顺序很重要。
更一般的情况可能会使用不同的分布,因此无法轻松使用按位运算。例如
# random draw of normals
a = tfd.Normal(loc = 0., scale = 1.).sample(6)
# redraw with a different scale if value is greater than zero in the original draw
b = tf.where(a > 0, tfd.Normal(loc = 0., scale = 2.).sample(1), a)
方法 1:
未测试,但我认为中间参数应该是与原始参数匹配的张量。例如。 6 个元素:
首先,制作第二个长度相同的随机序列:
a2 = tfd.Binomial(total_count = 1.0, probs = 0.5).sample(6)
注意:如果您需要不同的概率,只需在创建 a2 时使用该概率即可。
prob = 0.3
a2 = tfd.Binomial(total_count = 1.0, probs = prob).sample(6)
然后:
b = tf.where(a == 1.0, a2, a)
解释:
a2 中的值与 a 为 0 的情况无关,并且在 a 为 1 的情况下平均为“概率”。
方法 2:
如果这不起作用,则需要将第一个参数映射到 [true, false, ..] 的张量:
def pos(n):
return n > 0
cond = list(map(pos,a)) # I don't have TensorFlow handy; may need to replace `list` with appropriate function to create a Tensor.
b = tf.where(cond, a2, 0.0)
方法 3:
已测试。不使用 tf.where
.
首先,制作第二个长度相同的随机序列:
a2 = tfd.Binomial(total_count = 1.0, probs = prob).sample(6)
然后结合两者,“按位与”对应的元素:
def and2(a, b):
return (a & b)
b = list(map(and2, a, a2))
注意:也可以使用任何其他函数来组合两个相应的元素。
示例数据:
a = [0,0,1,1]
a2 = [0,1,0,1]
结果:
b = [0,0,0,1]
解释:
a2 中的值与 a 为 0 的情况无关,并且在 a 为 1 的情况下平均为“概率”。
tf.where 正在广播您的第二个参数,形状 [1] 值最多为六个向量 [6]。第二个值放在现有 1 的位置:1(在这种情况下输出匹配 a)或 0(在这种情况下全为零)。在每个站点为独立重采样值绘制六个样本。
考虑 tfd.Bernoulli 0/1 个样本。