打造第一个自训练模型的Core ML应用

2018-08-20 17:06:22 浏览数 (1)

mldemo.zip

1. 介绍

Core ML是iOS11的新特性,赋予iOS App更多AI的能力,例如垃圾短信识别、Siri、人脸识别、场景识别等等,过去集成在iOS系统的AI能力终于通过Core ML开放给第三方开发者了。随后苹果在今年WWDC发布了Create ML,这个苹果自家人工智能模型训练平台,苹果人工智能生态系统正逐渐形成,今天我们就借着一个简单的Core ML应用简单窥探一下。

Core ML 是iOS系统中人工智能模型的运行环境,开发者可以将自己训练好的模型转换为mlmodel,然后就可以应用内调用模型进行分类或预测了,目前支持转换的模型有caffe、keras、scikit-learn等。至于Core ML的能耐本文也不详细介绍了,参考苹果自己封装的图像处理分析框架vision和NLP框架就知道了。

image.pngimage.png

2. 准备工具

为了简单起见,数据处理和模型的训练本文使用Python编写,以下都是机器学习常用类库,均可通过pip install xxx安装。

模型训练工具:scikit-learn

数据处理:pandas

模型转换工具:linear_model

3. 生成数据

由于本文编写的只是一个demo,所以数据是本地随机生成的,生成脚本如下

代码语言:txt复制
import random
import pandas as pd
if __name__ == '__main__':
    params_count = 4
    params = []
    for i in range(params_count):
        params.append(random.random())
    df = pd.DataFrame(columns=['x1', 'x2', 'x3', 'y'])
    for i in range(10000):
        X = []
        for j in range(params_count - 1):
            X.append(random.randint(0, 100))
        y = sum([X[i] * params[i] for i in range(params_count - 1)])
        y  = params[-1]
        line = X
        line.append(y)
        df.loc[i] = line
    df.to_csv('random_data.txt', index=False, sep=',')
    print('params = %sn'%(','.join(map(str, params))))

4. 训练模型

我们将生成的数据分为训练数据和测试数据,对于训练数据,我们用最简单的线性回归模型训练,训练过程中我们用交叉数据验证下模型的准确率,最后保存到文件中,代码如下:

代码语言:txt复制
from sklearn.cross_validation import KFold
import pandas as pd
from sklearn import linear_model
import numpy as np
from sklearn.externals import joblib
if __name__ == '__main__':
    train_data = pd.read_table('random_train_data.txt', sep=',')
    X_train = train_data.ix[:, [0, 1, 2]]
    y_train = train_data[['y']]
    kf = KFold(y_train.shape[0], n_folds=5)
    residuals, scores = [], []
    for train_index, test_index in kf:
        clf = linear_model.LinearRegression()
        clf.fit(X_train.iloc[train_index, :], y_train.iloc[train_index, :])
        residual = np.mean(clf.predict(X_train.iloc[test_index, :]) - y_train.iloc[test_index, :]) ** 2
        print('Residual sum of squares = %.2f'%(residual))
        residuals.append(residual)
        score = clf.score(X_train.iloc[test_index, :], y_train.iloc[test_index, :])
        print('Score = %.2f'%(score))
        scores.append(score)
        print('n')
    print('Mean Residual sum of squares = %.2f' % np.mean(residuals))
    print('Mean score = %.2f' % np.mean(scores))
    clf = linear_model.LinearRegression()
    clf.fit(X_train, train_data['y'])
    joblib.dump(clf, 'linear_regression.pkl')

5. 转换模型

我们得到scikit-learn模型后还不能直接在iOS中调用,需要经过苹果的工具coremltools进行转换,代码如下,关键是convert函数和save函数,其他都是关于模型的描述,可以不设置,可以说非常符合苹果API风格,简单易用。

代码语言:txt复制
import coremltools
from sklearn.externals import joblib
from sklearn import linear_model
if __name__ == '__main__':
    clf = joblib.load('linear_regression.pkl')
    coreml_model = coremltools.converters.sklearn.convert(clf, ["x1", "x2", "x3"], "y")
    coreml_model.author = "forrestlin"
    coreml_model.license = "BSD"
    coreml_model.input_description['x1'] = 'x1 in [0, 100)'
    coreml_model.input_description['x2'] = 'x2 in [0, 100)'
    coreml_model.input_description['x3'] = 'x3 in [0, 100)'
    coreml_model.output_description['y'] = 'result'
    coreml_model.save('linear_regression.mlmodel')

6. 应用模型

得到mlmodel文件后,我们可以直接将其拖入xcode工程中,选中模型文件会显示模型信息,如下图所示:

image.pngimage.png

在导入模型后,xcode会自动生成模型类,以模型文件名为类名,创建模型实例后,我们调用prediction方法即可得到预测结果,十分简单,代码如下:

代码语言:txt复制
let linearRegression = linear_regression()
let x1 = Double.init(x1TextField.text ?? "0") ?? 0.0
let x2 = Double.init(x2TextFied.text ?? "0") ?? 0.0
let x3 = Double.init(x3TextField.text ?? "0") ?? 0.0
guard let resultOutput = try? linearRegression.prediction(x1: x1, x2: x2, x3: x3) else {
	fatalError("Unexpected runtime error.")
}
resultLabel.text = "预测结果:(String.init(format: "%.3f", resultOutput.y))"

运行界面如下,由于是自己就是根据线性模型生成的数据,所以预测结果和真实结果完全一致,2333~

image.pngimage.png

总结

demo虽小,但五脏俱全,希望以此打开苹果人工智能生态系统的大门,也希望对各位读者有用,App demo源码见附件。

0 人点赞