问题描述
正如标题所说,我有以下内容 :一个 NXN 平方一热编码数组,其中只有一个单元格为 1,所有其他单元格为 0。这个 1 可以在网格上的任何地方,不一定在中心。
我想使用 tensorflow 现在使正方形成为类似高斯的二维数组,其中具有 1 的单元格是值为 1 的平均值,并且它周围的所有单元格都是值
import numpy as np
import matplotlib.pyplot as plt
x,y = np.meshgrid(np.linspace(-1,1,10),np.linspace(-1,10))
d = np.sqrt(x*x+y*y)
sigma,mu = 1.0,1.0
g = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )
plt.imshow(g,interpolation='none')
plt.show()
对我上述问题的任何建议/帮助将不胜感激!
解决方法
这使用 scipy
生成高斯内核。和 np.where
得到值 1 的坐标。
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
N = 7 # kernel size
k1d = signal.gaussian(N,std=1).reshape(N,1)
kernel = np.outer(k1d,k1d)
plt.imshow(kernel)
plt.show()
A = np.zeros((16,16))
A[5,9] = 1 # random
plt.imshow(A)
plt.show()
row,col = np.where(A == 1)
A[row[0]-(N//2):row[0]+(N//2)+1,col[0]-(N//2):col[0]+(N//2)+1] = kernel
plt.imshow(A)
输出:
,您可以使用 tfp.distributions.MultivariateNormalDiag
from tensorflow_probability
中的概率分布函数:
import tensorflow_probability as tfp
import tensorflow as tf
def get_gaussian(mu,sigma):
mvn = tfp.distributions.MultivariateNormalDiag(loc=mu,scale_diag=sigma)
x,y = tf.cast(tf.linspace(-1,1,10),tf.float32),tf.cast(tf.linspace(-1,tf.float32)
# meshgrid as a list of [x,y] coordinates
coords = tf.reshape(tf.stack(tf.meshgrid(x,y),axis=-1),(-1,2))
gauss = mvn.prob(coords)
return tf.reshape(gauss,(10,10))
均值 (0.4,-0.6) 方差为 (0.5,0.5) 的示例:
>>> g = get_gaussian([0.4,-0.6],[0.5,0.5])
>>> plt.imshow(g,extent=[-1,-1,1])
>>> plt.show()
,
实现此目的的简单方法是使用高斯核进行卷积(即应用高斯平滑)。
TensorFlow 在函数 tfa.gaussian_filter2d
中有一个 2D 高斯平滑。
因为平滑保留了总强度,原来为 1 的像素在之后会有一个更低的值。您可以手动计算必要的缩放以将其恢复为 1(这取决于 sigma),或者您可以简单地将图像归一化使其最大值为 1。
我认为它会像这样实现:
ele
如上计算 import tensorflow as tf
import tensorflow_addons as tfa
import numpy as np
img = (your array)
sigma = 1.0
size = ceil(3*sigma)*2+1
img = tfa.image.gaussian_filter2d(img,size,sigma,'CONSTANT',0)
img /= np.amax(img)
在距原点合理距离处切断高斯。