Преобразование MPSNNImageNode с использованием Metal Performance Shader
В настоящее время я работаю над репликацией YOLOv2 (не крошечной) на iOS (Swift4) с использованием MPS.
Проблема в том, что мне трудно реализовать функцию space_to_depth ( https://www.tensorflow.org/api_docs/python/tf/space_to_depth) и объединение двух результатов из сверток (13x13x256 + 13x13x1024 -> 13x13x1280). Не могли бы вы дать мне несколько советов по изготовлению этих деталей? Мои коды ниже.
...
let conv19 = MPSCNNConvolutionNode(source: conv18.resultImage,
weights: DataSource("conv19", 3, 3, 1024, 1024))
let conv20 = MPSCNNConvolutionNode(source: conv19.resultImage,
weights: DataSource("conv20", 3, 3, 1024, 1024))
let conv21 = MPSCNNConvolutionNode(source: conv13.resultImage,
weights: DataSource("conv21", 1, 1, 512, 64))
/*****
1. space_to_depth with conv21
2. concatenate the result of conv20(13x13x1024) to the result of 1 (13x13x256)
I need your help to implement this part!
******/
2 ответа
я верю
space_to_depth
может быть выражен в виде свертки: например, для ввода с измерением[1,2,2,1]
, Используйте 4 ядра свертки, которые выводят одно число на один канал, т.е.[[1,0],[0,0]] [[0,1],[0,0]] [[0,0],[1,0]] [[0,0],[0,1]]
, это должно поместить все входные числа из пространственного измерения в измерение глубины.MPS на самом деле имеет конкатный узел. Смотрите здесь: https://developer.apple.com/documentation/metalperformanceshaders/mpsnnconcatenationnode%5C
Вы можете использовать это так:
concatNode = [[MPSNNConcatenationNode alloc] initWithSources:@[layerA.resultImage, layerB.resultImage]];
Если вы работаете с высокоуровневым интерфейсом и MPSNNGraph, вам просто нужно использовать MPSNNConcatenationNode, как описано выше в Tianyu Liu.
Если вы работаете с низкоуровневым интерфейсом, манипулируя MPSKernels вокруг себя, то это делается с помощью:
- Создайте 1280-канальное конечное изображение для хранения результата
- Запустите первый фильтр как обычно, чтобы получить первые 256 каналов результата
- Запустите второй фильтр, чтобы создать оставшиеся каналы с параметром destinationFeatureChannelOffset, равным 256.
Этого должно быть достаточно во всех случаях, кроме случаев, когда данные не являются продуктом MPSKernel. В этом случае вам нужно будет скопировать его в себя или использовать что-то вроде линейного нейрона (a=1,b=0), чтобы сделать это.