SwiftyForesight
Swift API,用于将移动应用程序与 Foresight 云框架集成。
内容
安装
SwiftyForesight
通过 CocoaPods 提供安装。在 Podfile 中输入 pod 'SwiftyForesight'
,然后从终端输入 pod install
。
用户指南
此库提供了一种简单的方法,在 iOS 设备和 Foresight 云平台之间建立接口。基于 Foresight 框架构建的 iOS 设备必须(1)连接到 AWS 云服务,(2)以正确格式传输数据,以及(3)在本地下载和运行远程生成的自定义计算模型。为此三个任务,此库提供了三个重要的类:CloudManager
、LibraData
和 LibraModel
。
重要提示:所有在 SwiftyForesight
中的异步函数都包含完成处理程序。请在需要通过使用 DispatchGroup
将数据传输与其他进程同步的情况下使用这些处理程序。
AWS 依赖项
由于 Foresight 框架使用亚马逊网络服务 (AWS),如果在安装时未安装,SwiftyForesight
CocoaPod 将随重要 AWS 依赖项一起安装。使用此库时,请确保您从 Enabyl 代表处获取了有关您的 AWS 资源的信息。另外,请确保您已经收到您的 awsconfiguration.json
文件并将其包含在主项目目录中。
导入 SwiftyForesight
在所有使用 SwiftyForesight
类的文件中,请将其添加到文件头部的 import SwiftyForesight
。
CloudManager
CloudManager
类负责管理 iOS 应用程序与各种 AWS 资源之间的数据连接。它定义了 LibraData
和 LibraModels
类用以为与其相应的 AWS 资源进行通信的各种函数。通过调用初始化器创建应用程序的 CloudManager
对象。
// Instantiate CloudManager object
let cloudManager = CloudManager(identityID: "<name>", userID: "<name>", writeBucket: "<name>", readBucket: "<name>")
重要提示:在使用 Foresight 框架的设备上,每个用户应分配一个唯一的字母数字用户 ID。轻松生成此 ID 的方法是用 UUID.uuidstring()
并将其存储在密钥链或用户默认值。此 ID 由 Foresight 框架用于识别特定用户模型、生成性能报告等,因此,确保此 ID 保持一致是开发者的最佳利益。
此类要求用户指定他们的身份 ID(在他们的 awsconfiguration.json
文件中找到),他们要向其中传输数据的目标 S3 桶名称,以及要从其中下载计算模型的 S3 桶名称。只有一个用例可能需要直接调用 CloudManager
方法,如以下部分中所述。
LibraModel
初始化
LibraModel
是由 Foresight 框架生成的所有计算模型的超类。根据您的应用程序,您可能需要在您的设备上运行 LibraModel
的一个或多个子类。目前支持两种模型子类型:SequentialModel
(例如 LSTM)和 FeedforwardModel
(例如 Softmax)。以下示例展示了如何实例化一个 SequentialModel
对象,但是同样的过程也可以用于一个 FeedforwardModel
。
// Instantiate SequentialModel object
let myModel = SequentialModel(modelClass: MLModel(), numInputFeatures: 10, localFilepath: <path>, withManager: cloudManager)
可以通过 modelClass
参数输入一个已经安装到主应用程序包中的 MLModel
对象(如果有的话),作为远程模型下载和编译的占位符。在大多数情况下,这将留如上所示的占位符。用户必须指定模型中的输入特征数量,以及远程编译的模型将临时存储的本地文件路径(包括 .mlmodel 文件名)。最后,用户应包含之前定义的 CloudManager
对象,以便模型可以管理其 AWS 连接。为将在您设备上运行的每个计算模型执行此过程。
模型配置
为了使用 LibraModel
生成预测,必须在训练/保存模型时指定分配给模型输入和输出节点的名称。默认情况下,输入和输出节点的名称由 SwiftyForesight
API 自动处理,但如果你为自己的模型的输入和输出节点设置了自定义名称,必须使用 seFeatures()
函数指定它们。
获取和使用模型
LibraModel
超类包括两个用于执行这些模型任务的有用方法。包括以下内容:
fetch()
:从 Foresight 服务器平台获取并下载最新模型。predict()
:根据提供的输入向量生成预测。
预测数据格式化是一个简单任务。对于序列模型,特征向量应以列表格式提供(即 [[Double]]
),每个条目都是一个单个特征向量。特征向量的总数应与上面指定的 numInputFeatures
相匹配。对于前馈模型,特征向量应以 [Double]
格式提供,元素数量也应与 numInputFeatures
相匹配。《predict()` 函数将返回结果在 MLMultiArray
对象中,可以通过从中提取元素来获得模型预测。
LibraData
初始化
LibraData
对象的作用是将数据格式化后发送到远程服务器资源进行训练。对于每个正在远程训练的模型,应该创建一个LibraData
对象,并使用它来格式化和上传训练数据。第一步如下实例化对象。
let myData = LibraData(hasTimestamp: true, featureVectors: 10, labelVectorLength: 3, withManager: cloudManager)
参数hasTimestamp
在模型训练期间用于说明如何处理第一个特征向量。《featureVectors》参数应指定数据有多少个特征向量(不包括时间戳列)。labelVectorLength
指定标签向量的长度(例如,对于具有三个类别的softmax分类器,labelVectorLength
= 3)。
数据格式化
注意对于前馈和网络模型,每个特征向量代表单个特征在训练样本中的值,而不是在单步时间中所有特征的截面。以下是一个关于数据如何格式化的示例。
// Collect features and labels
let featureVector1 = [1.0, 2.0, 3.0] // First input feature values at t = 1, 2, 3
let featureVector2 = [4.0, 5.0, 6.0] // Second input feature values at t = 1, 2, 3
let labelVector1 = [0.0, 1.0] // First label vector at t = 1
let labelVector2 = [1.0, 0.0] // Second label vector at t = 2
let labelVector3 = [1.0, 0.0] // Third label vector at t = 3
// Format features and labels into an array for import to LibraData object
let features = [featureVector1, featureVector2] // Feature vector
let labels = [labelVector1, labelVector2, labelVector3] // Label vector
数据传输
为了上传数据,将特征向量和标签向量添加到LibraData
对象中并上传。
myData.addFeatures(features) // Add features to object
myData.addLabels(labels) // Add labels to object
myData.formatData() // Formatting data for upload
myData.uploadDataToRemote(fromLocalFile: <path>) // Uploading data to remote
formatData()
函数格式化训练数据并将其保存为本地.csv文件。此文件被自动命名为<userID>_<eventDate>.csv
,以便稍后正确处理。然后,使用具有相同文件名的函数uploadDataToRemote()
将该文件上传到远程AWS资源。注意,必须指定本地文件路径,因为函数uploadDataToRemote()
也由《SwiftyForesight》框架中的其他函数使用。然而,函数formatData()
在完成处理程序中返回文件名,然后可以直接传递给uploadDataToRemote()
。请注意,LibraData
还包含一个保护措施,用于稍后重新尝试所有失败的传输(例如,当网络连接丢失时)。
// Retrying all failed uploads
myData.retryFailedUploads()
如果用户希望删除与失败的传输关联的所有数据文件,LibraData
还包括可以用来清除数据的函数clearErrorLogs()
,如果它开始消耗比预期的更多内存。
引入元数据
当数据文件传输到远程资源进行模型训练时,可能需要包含元数据以供训练算法提供上下文。元数据存储在DynamoDB数据库中。为了启用元数据,用户必须采取以下步骤。
- 初始化您的
CloudManager
后,使用CloudManager.tableName = <您的表名>
指定您的DynamoDB表名。 - 要将元数据添加到您的
LibraData
对象中,请使用函数myData.addMetadata()
。 - 要上传到DynamoDB,请使用函数
myData.uploadMetadataToRemote()
。
通过 addMetadata()
传递给您的 LibraData
对象的数据应具有以下格式的字典
// Generating a metadata dictionary
let myDict = [Keys.hash : <userID>, Keys.range: <eventDate>, Keys.m0: <metadata0>, Keys.m1: <metadata1>, ...]
Foresight框架提供的默认DynamoDB表接受多达12个字段。《_userID》和《_eventDate》分别是所需的哈希键和范围键,但用户可根据自己的意愿存储多达10个额外的元数据字段。这些字段可以分别用键《_m0》到《_m9》添加到元数据字典中。为防止输入错误,提供了《Keys》类,该类包含静态变量,用于存储哈希键、范围键和10个元数据字段的正确名称。请注意,这些字段名称不能更改,因此用户必须记录和规范每个元数据字段所存储的内容。存储元数据的最佳实践指南是,此字典中使用的《
还可以使用 LibraData
函数 queryData()
查询元数据,该函数返回两个指定日期之间的所有元数据条目。日期应按照以下格式格式化,以便查询正确执行。
let myDate = Date() // Specify date here
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMhhmmss""
let properDate = formatter.string(from: myDate)
数据管理
为了保持法规遵从性,通常会需要为应用程序的用户提供删除所有已收集的远程数据和元数据的能力。《LibraData》提供了用于删除当前正在处理的所有数据的函数《clearData()`》(即尚未上传或本地保存的数据)。对于删除远程文件,我们必须直接使用《CloudManager》。《CloudManager》提供了用于清除远程资源中所有《数据文件》的函数《removeAllUserFiles()`》,以及用于删除所有《元数据》的函数《removeAllUserMetadata()`》。
版本历史
- v1.0.0:初始版本
- 版本1.0.1:自动生成本地和远程文件名并保持正确格式。
- 版本1.0.2:自动处理DynamoDB表属性。
- 版本1.0.3:添加元数据查询并优化元数据键的组织。