如何在任何深度建模框架中实现具有均值和方差值作为输入的高斯渲染器(需要可反向传播)
How to implement a gaussian renderer with mean and variance values as input in any deep modeling framework (needs to be back-propagable)
想象一个典型的自动编码器-解码器模型。但是,我需要实现一个 structured/custom 解码器,而不是将反卷积和放大一起用于 create/synthesize 类似于模型输入的张量的通用解码器。
在这里,我需要解码器接受它的输入,例如一个 10x2 张量,其中每一行代表 x,y
个位置或坐标,并渲染一个固定的预定义大小的图像,其中在输入指定的位置生成 10 个高斯分布。
换句话说,我需要创建一个空的固定大小的张量,将 10 个坐标指定的位置填充为值 1,然后在整个张量上扫描一个高斯核。例如,想象以下一维场景。让整个模型的输入是一个大小为 10 的向量。如果解码器的输入是 [3, 7]
,这是两个 x 坐标(0 索引),以及我们想要的大小为 3 的高斯核使用的是 [0.28, 0.44, 0.28]
,则解码器的输出应如下所示(应与模型的原始输入大小相同,即 10):
[0, 0, 0.28, 0.44, 0.28, 0, 0.28, 0.44, 0.28, 0]
与[0, 0, 0, 1, 0, 0, 0, 1, 0, 0]*[0.28, 0.44, 0.28]
相同,其中*
表示卷积运算符。请注意,在第一个向量中,考虑到 0 索引格式,1 或位于位置 3 和 7。
最后会计算出一个典型的像素损失,比如MSE。重要的部分是这个渲染模块需要能够反向传播从损失到它的坐标输入的错误。
这个模块本身没有任何可训练的参数。此外,我不想更改此渲染模块之前的图层,它们需要保持原样。在更高级的设置中,我也想提供 4 个协方差值作为输入,即渲染器的输入将采用 [num_points, 5]
的形式,其中每一行是 [x_coord, y_coord, cov(x,x), cov(x,y), cov(y,y)]
.
如何在任何可用的深度学习框架中实现这样的模块?对类似内容的提示也将非常有用。
根据我的经验,神经网络中的准时事物性能会很差,因为它减少了远处像素的影响。
因此,与其使用高斯核,不如将实际的高斯函数应用于所有像素。
因此,采用二维高斯分布函数:
我们可以这样使用:
这意味着自定义函数中的一些步骤:
import keras.backend as K
def coords_to_gaussian(x): #where x is shape (batch, 10, 2), and 2 = x, y
#pixel coordinates - must match the values of x and y
#here I suppose from 0 to image size, but you may want it normalized, maybe
x_pixels = K.reshape(K.arange(image_size), (1,1,image_size,1))
x_pixels = K.concatenate([x_pixels]*image_size, axis=-1) #shape(1,1,size,size)
y_pixels = K.permute_dimensions(x_pixels, (0,1,3,2))
pixels = K.stack([x_pixels, y_pixels], axis=-1) #shape(1,1,size,size,2)
#adjusting the AE locations to a compatible shape:
locations = K.reshape(x, (-1, 10, 1, 1, 2))
#calculating the upper part of the equation
result = K.square(pixels - locations) #shape (batch, 10, size, size, 2)
result = - K.sum(result, axis=-1) / (2*square_sigma) #shape (batch, 10, size, size)
#calculating the E:
result = K.exp(result) / (2 * pi * square_sigma)
#sum the 10 channels (principle of superposition)
result = K.sum(result, axis=1) #shape (batch, size, size)
#add a channel for future convolutions
result = K.expand_dims(result, axis=-1) #shape (batch, size, size, 1)
return result
在 Lambda
层中使用它:
from keras.layers import Lambda
Lambda(coords_to_gaussian)(coordinates_tensor_from_encoder)
我这里不考虑协方差,但您可能会找到一种方法将它们放入公式中并调整代码。
想象一个典型的自动编码器-解码器模型。但是,我需要实现一个 structured/custom 解码器,而不是将反卷积和放大一起用于 create/synthesize 类似于模型输入的张量的通用解码器。
在这里,我需要解码器接受它的输入,例如一个 10x2 张量,其中每一行代表 x,y
个位置或坐标,并渲染一个固定的预定义大小的图像,其中在输入指定的位置生成 10 个高斯分布。
换句话说,我需要创建一个空的固定大小的张量,将 10 个坐标指定的位置填充为值 1,然后在整个张量上扫描一个高斯核。例如,想象以下一维场景。让整个模型的输入是一个大小为 10 的向量。如果解码器的输入是 [3, 7]
,这是两个 x 坐标(0 索引),以及我们想要的大小为 3 的高斯核使用的是 [0.28, 0.44, 0.28]
,则解码器的输出应如下所示(应与模型的原始输入大小相同,即 10):
[0, 0, 0.28, 0.44, 0.28, 0, 0.28, 0.44, 0.28, 0]
与[0, 0, 0, 1, 0, 0, 0, 1, 0, 0]*[0.28, 0.44, 0.28]
相同,其中*
表示卷积运算符。请注意,在第一个向量中,考虑到 0 索引格式,1 或位于位置 3 和 7。
最后会计算出一个典型的像素损失,比如MSE。重要的部分是这个渲染模块需要能够反向传播从损失到它的坐标输入的错误。
这个模块本身没有任何可训练的参数。此外,我不想更改此渲染模块之前的图层,它们需要保持原样。在更高级的设置中,我也想提供 4 个协方差值作为输入,即渲染器的输入将采用 [num_points, 5]
的形式,其中每一行是 [x_coord, y_coord, cov(x,x), cov(x,y), cov(y,y)]
.
如何在任何可用的深度学习框架中实现这样的模块?对类似内容的提示也将非常有用。
根据我的经验,神经网络中的准时事物性能会很差,因为它减少了远处像素的影响。
因此,与其使用高斯核,不如将实际的高斯函数应用于所有像素。
因此,采用二维高斯分布函数:
我们可以这样使用:
这意味着自定义函数中的一些步骤:
import keras.backend as K
def coords_to_gaussian(x): #where x is shape (batch, 10, 2), and 2 = x, y
#pixel coordinates - must match the values of x and y
#here I suppose from 0 to image size, but you may want it normalized, maybe
x_pixels = K.reshape(K.arange(image_size), (1,1,image_size,1))
x_pixels = K.concatenate([x_pixels]*image_size, axis=-1) #shape(1,1,size,size)
y_pixels = K.permute_dimensions(x_pixels, (0,1,3,2))
pixels = K.stack([x_pixels, y_pixels], axis=-1) #shape(1,1,size,size,2)
#adjusting the AE locations to a compatible shape:
locations = K.reshape(x, (-1, 10, 1, 1, 2))
#calculating the upper part of the equation
result = K.square(pixels - locations) #shape (batch, 10, size, size, 2)
result = - K.sum(result, axis=-1) / (2*square_sigma) #shape (batch, 10, size, size)
#calculating the E:
result = K.exp(result) / (2 * pi * square_sigma)
#sum the 10 channels (principle of superposition)
result = K.sum(result, axis=1) #shape (batch, size, size)
#add a channel for future convolutions
result = K.expand_dims(result, axis=-1) #shape (batch, size, size, 1)
return result
在 Lambda
层中使用它:
from keras.layers import Lambda
Lambda(coords_to_gaussian)(coordinates_tensor_from_encoder)
我这里不考虑协方差,但您可能会找到一种方法将它们放入公式中并调整代码。