Инициализация MLUpdateTask вызывает сигнал SIGABRT: Ошибка загрузки файла: * .mlmodelc / model.espresso.weights - PullRequest
1 голос
/ 07 октября 2019

(я новичок в ML, поэтому, пожалуйста, извините меня, если я говорю / делаю фигню ...)

Что я пытался сделать:

Я пыталсясоздать приложение для изучения ML (чтобы попасть в SwiftUI и CoreML). Приложение предназначено для того, чтобы научить какую-то нейронную сеть играть в крестики-нолики, используя обучение с подкреплением. Для этого вы можете сыграть AIPlayer против RandomPlayer, AlgorithmicPlayer, самого себя или себя. AIPlayer должен изучать каждую игру, в которую играл, путем обновления базовой модели, используя результаты игры и выборки, сделанные во время игры.

Проблема

Проблема в том, чтоинициализация MLUpdateTask завершается неудачно после определенного количества обновлений с сигналом SIGABRT. Таким образом, приложение вылетает. Точная сумма зависит от устройства. При запуске его на моем iPhone 6s 240-я инициализация MLUpdateTask завершается неудачно, на симуляторе это 243-я.

Я получаю сообщение об ошибке:

libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: Error loading file: /private/var/containers/Bundle/Application/714E7417-B792-4F80-8EAE-A2855E138A95/TicTacToe.app/UpdatableNNClassifier.mlmodelc/model.espresso.weights

Я проследилошибка до этой строки ... весь код на GitHub. https://github.com/theMomax/TicTacToe/blob/0182db0af27498d504fb5dcfd0556267e23c063b/TicTacToe/MLBase.swift#L132

Что я пытался решить эту проблему:

Я пытался уменьшить количество слоев в моей модели. Без эффекта.

Я пытался иметь только одну задачу обновления за раз. Никакого эффекта.

Я перенес все приложение на macOS. Это «решило» проблему.

Модель

Этот ноутбук является основой для , который я использовал для производства CoreML Model . Я только изменил то, что было необходимо для адаптации модели к моим форматам ввода / вывода. Возможно, модель, которая у меня есть сейчас, не сможет на самом деле учиться / совершенствоваться из-за ее структуры, но я не думаю, что это актуально сейчас.

Система

Mac:10,15 бета (19A582a)

iPhone: 13.1.2 (17A860)

Xcode: 11,1 (11A1027)

Обновление кода

Здесь - это файл на GitHub. Моя ссылка здесь это видео от WWDC. Я попытался удалить ненужные части ниже и добавить некоторые комментарии, описывающие, когда каждая функция вызывается ...


// is initialized once on startup
class MLWrapper {

    let bundle = Bundle(for: UpdatableNNClassifier.self)

    let updatableModelURL: URL

    var model = UpdatableNNClassifier()

    var trainingData: [(gameboard: [Position: FieldState], pick: Position)] = []

    init() {
        self.updatableModelURL = bundle.url(forResource: "UpdatableNNClassifier", withExtension: "mlmodelc")!
    }

    // Returns a randomly selected alternative to pick. 
    private func other(than pick: Position, in gameboard: [Position: FieldState?]) -> Position? {
        // ...
    }

    private func convertInput(gameboard: [Position: FieldState]) -> MLMultiArray {
        // ...
    }

    private func convertOutput(output: UpdatableNNClassifierOutput) -> Position? {
        // ...
    }

    // is called each time the `AIPlayer` is supposed to make a pick
    func predict(on gameboard: [Position: FieldState]) -> Position? {
        let input = convertInput(gameboard: gameboard)
        if let output = try? model.prediction(gameboard: input) {
            if let result = convertOutput(output: output) {

                // record input and output, so that it can be used to train
                // train the model, when the game's outcome is known
                trainingData.append((gameboard, result))
                return result
            } else {
                return nil
            }
        } else {
            print("Unexpected runtime error in \(model).")
            return nil
        }
    }

    // is called after a game is completed
    func reflect(on outcome: Outcome) {
        do {            
            let bp: MLBatchProvider = try MLArrayBatchProvider(dictionary: ["gameboard": trainingData.compactMap { i in
                return convertInput(gameboard: i.gameboard)
            }, "pick": trainingData.compactMap({ I in

                // in case the `AIPlayer` won or achieved a draw, its pick was good, otherwise, try any other pick next time
                outcome != .defeat ? i.pick.description() : other(than: i.pick, in: i.gameboard)?.description() ?? i.pick.description()
            })])
            // reset trainingData
            trainingData = []            

            // the line below is the one that fails
            let updateTask = try MLUpdateTask(forModelAt: updatableModelURL, trainingData: bp, configuration: self.model.model.configuration, completionHandler: { ctx in
                if ctx.task.error == nil {
                    self.model.model = ctx.model
                } else {
                    print(ctx.task.error!)
                }
            })

            updateTask.resume()
        } catch {
            print(error)
        }
    }

}

Вопрос

Итак, мой основной вопрос: что-то не так смой код обновления? Или это скорее всего бета-ошибка? Есть ли у вас какие-либо предложения по поводу того, что я мог бы попытаться решить?

Весь этот код выше вызывается из DispatchQueue в Controller.swift. Может ли это быть проблемой?

...