Я использую Metal Performance Shader для настройки нейронной сети и столкнулся с проблемой при написании класса инициализации весов: Тип MyWeights не соответствует протоколу NSCopying. Что вызвало ошибку и как ее исправить?

PS . Я попытался исправить это, добавив функцию copy (), но не знаю, что возвращать и что это значит.

import Foundation
import MetalPerformanceShaders

class MyWeights: NSObject, MPSCNNConvolutionDataSource {
//Error: Type 'MyWeights' does not conform to protocol 'NSCopying'

/*
func copy(with zone: NSZone? = nil) -> Any {
    return self
}
*/

let name: String
let kernelWidth: Int
let kernelHeight: Int
let inputFeatureChannels: Int
let outputFeatureChannels: Int

var data: Data?

init(name: String, kernelWidth: Int, kernelHeight: Int,
     inputFeatureChannels: Int, outputFeatureChannels: Int,
     useLeaky: Bool = true) {
    self.name = name
    self.kernelWidth = kernelWidth
    self.kernelHeight = kernelHeight
    self.inputFeatureChannels = inputFeatureChannels
    self.outputFeatureChannels = outputFeatureChannels
}

func dataType() -> MPSDataType {
    return .float32
}

func descriptor() -> MPSCNNConvolutionDescriptor {
    let desc = MPSCNNConvolutionDescriptor(kernelWidth: kernelWidth,
                                           kernelHeight: kernelHeight,
                                           inputFeatureChannels: inputFeatureChannels,
                                           outputFeatureChannels: outputFeatureChannels)
    return desc
}

func weights() -> UnsafeMutableRawPointer {
    return UnsafeMutableRawPointer(mutating: (data! as NSData).bytes)
}

func biasTerms() -> UnsafeMutablePointer<Float>? {
    return nil
}

func load() -> Bool {
    if let url = Bundle.main.url(forResource: name, withExtension: "dat") {
        do {
            data = try Data(contentsOf: url)
            return true
        } catch {
            print("Error: could not load \(url): \(error)")
        }
    }
    return false
}

func purge() {
    data = nil
}

func label() -> String? {
    return name
}

}
0
Jerry Xu 14 Сен 2018 в 05:26

2 ответа

Лучший ответ

Он сообщает вам именно , что делать.

Вам необходимо объявить, что ваш класс соответствует протоколу NSCopying, а затем вам необходимо реализовать единственную функцию в этом протоколе, copy(with:)

class MyWeights: NSObject, MPSCNNConvolutionDataSource, NSCopying {

    func copy(with zone: NSZone? = nil) -> Any {
        return MyWeights(
          name: self.name,
          kernelWidth: self.kernelWidth,
          kernelHeight: self.kernelHeight,
          inputFeatureChannels: self.inputFeatureChannels,
          outputFeatureChannels: self.outputFeatureChannels,
          useLeaky: self.useLeaky)
    }
    //The rest of your class
}
1
Duncan C 14 Сен 2018 в 02:37

Вы должны реализовать весь протокол NSCopying

class MyWeights: NSObject, MPSCNNConvolutionDataSource, NSCopying {

    init(/* ... */) {
    // your init...

        super.init() // NSObject init
    }

    // add this method
    func copy(with zone: NSZone? = nil) -> Any {
        return super.copy() // NSObject copy
    }
    //The rest of your class
}
0
Sombre Osmo'z 16 Фев 2019 в 15:53