今天,通过创建一个 Swift Package 引入 tensorflow/swift-models
,来的构建一个 Swift for TensorFlow 开发环境。
Swift Package Manager 是一个苹果官方出的管理源代码分发的工具,目的是更简单的使用别人共享的代码。它会直接处理包之间的依赖管理、版本控制、编译和链接。从总体功能上来说,和 iOS 平台上的 Cocoapods、Carthage 一样。
在 tensorflow/swift-models
项目主要是采用 Swift Package 结构:
creat package 执行命令:
1 swift package init --type executable
在生成的文件夹中,核心的一个是 Package.swift
,另一个是在 Sources 有一个 main.swift
,我们载入 XCode 下:
如果这时候直接在命令行或者 Xcode 直接运行:
则,会显示:
即:执行 main.swift 中的代码语句。
引入依赖包: 在 Package.swit 下我们需要先配置引入第三方依赖包:
1 2 3 4 5 6 7 dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), .package(name: "swift-models", url: "https://gitee.com/yemeishu/swift-models.git", .branch("main")) ],
其中,由于 Github 下载有点慢,我用 Gitee 同步过来,并且修改 swift-models
引入的依赖包也指向 Gitee 地址:
1 2 3 4 5 dependencies: [ .package(url: "https://gitee.com/yemeishu/swift-protobuf.git", from: "1.10.0"), .package(url: "https://gitee.com/yemeishu/swift-argument-parser.git", .branch("main")), .package(url: "https://gitee.com/yemeishu/swift-benchmark.git", from: "0.1.0"), ],
这样下载速度会快很多。
配置 Package.swift 此外,在依赖包里,我们需要在 target
里引入需要的依赖:
1 2 3 4 5 .target( name: "MyFirstPackage", dependencies: [ .product(name: "Datasets", package: "swift-models"), .product(name: "TrainingLoop", package: "swift-models")
根据实例,主要两个依赖包 Datasets
和 TrainingLoop
,而这两个依赖包来自 swift-models package
。
最后,因为 TensorFlow 包需要 10.13 以上,所以还需配置:
1 2 3 4 name: "MyFirstPackage", platforms: [ .macOS(.v10_13), ],
具体的 Package.swift
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import PackageDescription let package = Package( name: "MyFirstPackage", platforms: [ .macOS(.v10_13), ], dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), .package(name: "swift-models", url: "https://gitee.com/yemeishu/swift-models.git", .branch("main")) ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "MyFirstPackage", dependencies: [ .product(name: "Datasets", package: "swift-models"), .product(name: "TrainingLoop", package: "swift-models") ] ), .testTarget( name: "MyFirstPackageTests", dependencies: ["MyFirstPackage"]), ] )
main.swift 有了,swift-model 依赖包,我们就可以结合官网提供的 Demo,尝试写代码了,具体在 main.swift
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import Datasets import TensorFlow import TrainingLoop let epochCount = 12 let batchSize = 128 let device = Device.defaultTFEager let dataset = MNIST(batchSize: batchSize, on: device) var classifier = Sequential { Conv2D<Float>(filterShape: (5, 5, 1, 6), padding: .same, activation: relu) AvgPool2D<Float>(poolSize: (2, 2), strides: (2, 2)) Conv2D<Float>(filterShape: (5, 5, 6, 16), activation: relu) AvgPool2D<Float>(poolSize: (2, 2), strides: (2, 2)) Flatten<Float>() Dense<Float>(inputSize: 400, outputSize: 120, activation: relu) Dense<Float>(inputSize: 120, outputSize: 84, activation: relu) Dense<Float>(inputSize: 84, outputSize: 10) } var optimizer = SGD(for: classifier, learningRate: 0.1) var trainingLoop = TrainingLoop( training: dataset.training, validation: dataset.validation, optimizer: optimizer, lossFunction: softmaxCrossEntropy, metrics: [.accuracy], callbacks: [try! CSVLogger().log]) trainingLoop.statisticsRecorder!.setReportTrigger(.endOfEpoch) try! trainingLoop.fit(&classifier, epochs: epochCount, on: device)
点击 xcode 运行,结果如下:
总结 今天主要是学习创建一个 Swift Package,和引入 swift-model,为我们后续自学 Swift for Tensorflow 提供完备的开发环境。
此外也可以直接 clone swift-model 代码,做二次开发,如:
保持和 swift-model 代码同步,这样也可以实时了解 Swift for TensorFlow 最新成果。