Миграция MPSCNN полностью подключена к MPSCNNConvolutionDataSource - PullRequest
0 голосов
/ 19 марта 2019

Я перевожу свою нейронную сеть из устаревших:

init(device: MTLDevice, convolutionDescriptor: MPSCNNConvolutionDescriptor, kernelWeights: UnsafePointer<Float>, biasTerms: UnsafePointer<Float>?, flags: MPSCNNConvolutionFlags)

в

init(device: MTLDevice, weights: MPSCNNConvolutionDataSource)

Я реализовал MPSCNNConvolutionDataSource, который хорошо отлажен и работает для всех моихслои кроме одного.Просто для целей тестирования я сам вызываю функцию источника данных вместе с устаревшим init () MPSCNNFullyConnected, чтобы убедиться, что источник данных реализован правильно.Я знаю, что это не предполагаемое использование, но я хотел, чтобы одни и те же данные входили в оба конструктора MPSCNNFullyConnected ().Следующий код выполняется и NN работает правильно.

  /* This code runs as intended */
  let datasource = DataSource("test", 8, 8, 224, 1024, .reLU)
  _ = datasource.load()
    let layer = MPSCNNFullyConnected(device: device,
                                   convolutionDescriptor: datasource.descriptor(),
                                   kernelWeights: UnsafeMutablePointer<Float>(mutating: datasource.weights().assumingMemoryBound(to: Float.self)),
                                   biasTerms: datasource.biasTerms(),
                                   flags: .none)

Когда я создаю экземпляр полностью подключенного слоя с новым init (), сеть перестает работать.Следующий код выполняется, но NN не работает должным образом.

  /* This code does run, but the layer does NOT output the correct values */
  let datasource = DataSource("test", 8, 8, 224, 1024, .reLU)
  let layer = MPSCNNFullyConnected(device: device, weights: datasource)

Какие-либо предложения, почему оба вызова не идентичны?

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Наконец я решил это.Разница между обоими вызовами заключается в том, что вы должны установить layer.offset явно, если вы используете:

init(device: MTLDevice, weights: MPSCNNConvolutionDataSource) 

Устаревший вызов:

init(device: MTLDevice, convolutionDescriptor: MPSCNNConvolutionDescriptor, kernelWeights: UnsafePointer<Float>, biasTerms: UnsafePointer<Float>?, flags: MPSCNNConvolutionFlags)

, кажется, сделал это неявно.

Этот код работает:

let datasource = DataSource("test", 8, 8, 224, 1024, .reLU)
let layer = MPSCNNFullyConnected(device: device, weights: datasource)
layer.offset = MPSOffset(x: 8/2, y: 8/2, z: 0)

Полагаю, это нигде не задокументировано!Спасибо Apple за три дня жесткой отладки.

0 голосов
/ 20 марта 2019

Документы Apple для большей части этого металлического материала, кажется, исчезли, но они все еще там, если вы посмотрите в файлах заголовка (или нажмите Alt-клик в Xcode и затем перейдете к определению).

Порядоквесов не изменился.Вы по-прежнему загружаете их так же, как и раньше.

Для примера того, как написать такой объект источника данных, проверьте этот репозиторий: https://github.com/hollance/YOLO-CoreML-MPSNNGraph/blob/2ba3435bfacb8d2f792b95887fc9df85d7048ae1/TinyYOLO-NNGraph/TinyYOLO-NNGraph/YOLO.swift#L254

...