2017-02-02 25 views

ответ

0

MPS теперь обеспечивает MPSCNNConvolutionTranspose в MacOS X.13 и tvOS/прошивкой 11.

5

Вы можете написать свои собственные ядерные вычислительные ядра и выполнить их между операциями 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 объекта. Затем вы можете закодировать его в текущий буфер команд всякий раз, когда захотите.

+0

Да, я знаю, что. У вас есть примеры того, как передавать параметр «MPSImage» в качестве параметра и работать с ним внутри функции «ядро»? – s1ddok

+0

Вы не передаете 'MPSImage' напрямую. Вместо этого вы используете 'image.texture', как и в примере кода. Если у вас <= 4 канала, то текстура - всего лишь один объект текстуры; с> 4 каналами это на самом деле массив текстур. –

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.

У меня нет кода для примера с металлом, чтобы показать вам, но он действительно ничем не отличается от создания обычного слоя MPSCNNConvolution. Вам просто нужно отменить весы для слоя.

+0

Я бы убил для примера – s1ddok

+0

Добавлен пример. –

+0

Я думаю, что это не совсем правильно. Прежде всего, мы имеем 3 размерных веса. Предполагается, что предполагается деконволюция, чтобы увеличить ширину и высоту изображения, не так ли? – s1ddok