我正在将Nvidia的GAN生成器的渐进式增长转换为coreML。我已经设法将所有内容转移到coreML上,除了Pixelwise Normalization(Lambda)层之外,我计划将其实现为Swift / Metal中的自定义coreML层。
在TensorFlow.Keras中,我将像素规范实现为
def pixelwise_norm(a):
return a / tf.sqrt(tf.reduce_mean(a * a, axis=3, keep_dims=True) + 1e-8)
现在,我几乎从未使用过着色器/金属,但是按照此处的说明进行操作:http://machinethink.net/blog/coreml-custom-layers/,我设置了一个自定义层,以使用Metal进行前馈操作。我使用的MTLComputePipelineState(调用?编码?)以下着色器用于图层的操作:
#include <metal_stdlib>
using namespace metal;
kernel void pixelwise_norm(
texture2d_array<half, access::read> inTexture [[texture(0)]],
texture2d_array<half, access::write> outTexture [[texture(1)]],
ushort3 gid [[thread_position_in_grid]])
{
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height()) {
return;
}
const float4 x = float4(inTexture.read(gid.xy, gid.z));
const float4 y = 0.0000001f + (x / sqrt(pow(x,2)));
outTexture.write(half4(y), gid.xy, gid.z);
}
我在弄清楚“ reduce_mean”的等效金属时遇到了麻烦,现在此着色器实现了〜tensorflow〜操作,如
return a / tf.sqrt((a * a) + 1e-8)
有人有指针吗? 谢谢
答案 0 :(得分:0)
如果我没看错的话,那么对于特征图中的每个像素,都可以将该像素除以该像素通道上的L2范数?
在这种情况下,您需要使用for循环来读取该像素的通道,将这些数字求和,然后除以通道数。 (仅当通道数大于4时才需要执行此循环。)
还请注意,您的1e-8必须位于sqrt()内或至少在分母中。