Оказывается, такой операции нет, как deconvolution
в MPS
. Ближайшим аналогом в tensorflow
является conv2d_transpose
.Deconvolution с металлическими шейдерами
Возможно ли выполнить выборочные операции плагина между MPS
по умолчанию?
Оказывается, такой операции нет, как deconvolution
в MPS
. Ближайшим аналогом в tensorflow
является conv2d_transpose
.Deconvolution с металлическими шейдерами
Возможно ли выполнить выборочные операции плагина между MPS
по умолчанию?
MPS теперь обеспечивает MPSCNNConvolutionTranspose в MacOS X.13 и tvOS/прошивкой 11.
Вы можете написать свои собственные ядерные вычислительные ядра и выполнить их между операциями 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
объекта. Затем вы можете закодировать его в текущий буфер команд всякий раз, когда захотите.
[Я добавляю это как новый ответ, потому что это другое решение.]
Обратите внимание, что деконволюции в глубоком обучении также известна как «транспонированной свертка», что означает, что это то же самое, как делать регулярную свертку но с ядрами по горизонтали и вертикали.
Таким образом, вы должны быть в состоянии использовать обычный 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.
У меня нет кода для примера с металлом, чтобы показать вам, но он действительно ничем не отличается от создания обычного слоя MPSCNNConvolution
. Вам просто нужно отменить весы для слоя.
Да, я знаю, что. У вас есть примеры того, как передавать параметр «MPSImage» в качестве параметра и работать с ним внутри функции «ядро»? – s1ddok
Вы не передаете 'MPSImage' напрямую. Вместо этого вы используете 'image.texture', как и в примере кода. Если у вас <= 4 канала, то текстура - всего лишь один объект текстуры; с> 4 каналами это на самом деле массив текстур. –