【发布时间】:2018-09-02 06:09:43
【问题描述】:
我有一个 CNN 输出掩码 (logits, shape = [batch, x, y, classes]) 和一个矩阵 (sigma) stddev 用于每个 logit 的高斯噪声(即 sigma.shape = [x, y, classes])。 我想根据对应的 sigma 用高斯噪声破坏每个 logit。 在 tensorflow 中,我只找到了一个适用于标量的高斯:tf.random_normal。
因此我使用循环,分别“计算”每个 logit 的噪声(mean = logit[b, x, y, c]、stddev = sigma[x, y, c])并使用tf.stack 来取回我的 4-D 张量。但是:对于 [1, 1024, 1024, 2] -Tensor,这已经花费了很长时间(达到“未完成”的程度),这是有道理的,我想因为它必须创建和堆叠 > 100 万张量对象。
无论如何,我很确定这不是要走的路……
但是我应该怎么做呢? 是否有tf.random_normal 允许在更高维度上工作?
我知道tf.random_normal 可以返回一个带有(任意)shape 的更多维张量,但这对我不起作用,因为它将相同的 stddev 应用于每个元素(平均值无关紧要,因为我可能会产生 0-mean 噪声和tf.add())。
如果它以任何方式相关:我现在可以接受的一个折衷方案(以加快速度)是使用 stddev 仅基于像素(不是类)产生噪声,即 *sigma.shape = [x, y]* .但这仅带走了一个循环,而不是主要问题(x*y)。
这里是“循环”方法的代码。我测试了它的小值([1, 8, 8, 2]。我知道我可以省略for b-loop,但这不是“肉”成本,x*y 计算才是真正的问题:
logits = self.output_mask # e.g. shape: [1, 1024, 1024, 2]
sigma = tf.ones(shape=[1024, 1024, 2], dtype=logits.dtype) # dummy values, will be a learned parameter later
corrupted_logits_b = []
for b in range(logits.shape[0]):
corrupted_logits_x = []
for x in range(logits.shape[1]):
corrupted_logits_y = []
for y in range(logits.shape[2]):
corrupted_logits_c = []
for c in range(logits.shape[3]):
# this is where the noise is computed
# (added to the logit since mean = logit)
corrupted_logit = tf.random_normal(tf.shape(logits[b, x, y, c]),
mean=logits[b, x, y, c],
stddev=sigma_val[x, y, c])
# "values"/logit-tensors are appended to lists and
# ... and stacked to form higher-dim tensors
corrupted_logits_c.append(corrupted_logit)
corrupted_logits_y.append(tf.stack(corrupted_logits_c, axis=-1))
corrupted_logits_x.append(tf.stack(corrupted_logits_y))
corrupted_logits_b.append(tf.stack(corrupted_logits_x))
corrupted_logits = tf.stack(corrupted_logits_b, axis=-1)
【问题讨论】:
标签: python tensorflow normal-distribution noise