使用金属性能着色器进行反卷积

时间:2017-02-02 21:09:15

标签: tensorflow metal metal-performance-shaders

原来在deconvolution中没有MPS这样的操作。 tensorflow中最接近的类似物是conv2d_transpose

是否可以在MPS默认操作之间进行插件自定义操作?

3 个答案:

答案 0 :(得分:5)

您可以编写自己的Metal计算内核并在MPS操作之间执行这些内核。

例如:

let commandBuffer = commandQueue.makeCommandBuffer()

. . .

// Do something with an MPSCNN layer:
layer1.encode(commandBuffer: commandBuffer, sourceImage: img1, destinationImage: img2)

// Perform your own compute kernel:
let encoder = commandBuffer.makeComputeCommandEncoder()
encoder.setComputePipelineState(yourOwnComputePipeline)
encoder.setTexture(img2.texture, at: 0)
encoder.setTexture(img3.texture, at: 1)
let threadGroupSize = MTLSizeMake(. . .)
let threadGroups = MTLSizeMake(img2.texture.width / threadGroupSize.width,
                               img2.texture.height / threadGroupSize.height, 1)
encoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupSize)
encoder.endEncoding()

// Do something with another MPSCNN layer:
layer2.encode(commandBuffer: commandBuffer, sourceImage: img3, destinationImage: img4)

. . .

commandBuffer.commit()

您必须在Metal Shading Language中编写自己的计算内核,并将其加载到yourOwnComputePipeline对象中。然后,您可以随时将其编码到当前命令缓冲区中。

答案 1 :(得分:1)

[我将此添加为新答案,因为它是一个不同的解决方案。]

请注意,深度学习中的反卷积也称为“转置卷积”,这意味着它与进行常规卷积相同,但内核水平和垂直翻转。

因此,您应该能够使用常规MPSCNNConvolution图层,该图层将您要解卷积的MPSImage作为输入,并使用与“前向”卷积步骤相同的内核但水平翻转和垂直。

这样做比编写自己的计算内核更有优势的是你可以使用MPS中非常快的内核。

修改一个例子。假设你的内核权重看起来像这样:

1, 2, 3
4, 5, 6
7, 8, 9

然后在翻转内核后,权重看起来像这样:

9, 8, 7
6, 5, 4
3, 2, 1

换句话说,您需要复制权重数组并将其反转。在内存中,第一个权重看起来像这样:

1, 2, 3, 4, 5, 6, 7, 8, 9

翻转内核在内存中看起来像这样,所以它只是原始内核,但顺序相反:

9, 8, 7, 6, 5, 4, 3, 2, 1

然后使用该反转数组创建一个新的卷积层。这是你的deconv层。

我没有Metal示例代码向您展示,但它与制作常规MPSCNNConvolution图层没有什么不同。你只需要反转图层的权重。

答案 2 :(得分:1)

MPS现在在macOS X.13和tvOS / iOS 11中提供MPSCNNConvolutionTranspose。