与其上来就学习相对枯燥易让人放弃的数学, 不如先做几个例子并在 AndroidiOS 上初步实验熟悉下整个操作流程, 通过实战激发下兴趣
开发环境准备
首先安装 Python, 推荐 Python3, 装好后别忘了设置下载源镜像, 不然安装各种包的时候下载速度很感人
新建文件:~/.pip/pip.conf
- [global]
- index-url = https://pypi.tuna.tsinghua.edu.cn/simple
- [install]
- use-mirrors = true
- mirrors = https://pypi.tuna.tsinghua.edu.cn/simple
再安装 NumpySciPyPandasMatplotlibPilTensorFlow scikit-learn 等库, 都是深度学习不可缺少的
pip3 install --user numpy scipy matplotlib ipython jupyter pandas sympy nose
更多安装介绍可参考底部参考链接
TensorFlow 的安装, 官方推荐在 Linux 系统里安装 gpu 版, 但我们学习阶段在 mac 上安装 cpu 版即可, 官方从 1.2 版本后就不再编译 gpu 版的 mac 安装包, 需要自己从源码编译, 由于深知 cpu 版训练很慢, 我自己尝试编译了 gpu 版, 在 10.13 系统上遇到不少坑, 各种修改耗费大半天后终于编译成功, 完整一次性编译成功在 2014 款 15 寸 mbp 高配上大约需要近 1 个小时, 具体可参考底部参考资料
但由于不明原因, 在使用 gpu 训练时系统会卡住, 甚至花屏, 直到训练完成才能陆续恢复, 因此在 mac 上学习推荐直接用官方编译的 cpu 版即可
pip3 install tensorflow
Python IDE 个人看习惯随意选择, TensorFlow 安装后先来个 Hello world 脚本试试各组件是否完备:
- import tensorflow as tf
- hello = tf.constant('Hello, TensorFlow!')
- sess = tf.Session()
- sess.run(hello)
- # 应该输出'Hello, TensorFlow!'
- a = tf.constant(10)
- b = tf.constant(32)
- sess.run(a + b)
- # 应该输出 42
- sess.close()
对于客户端程序员来说, AndroidiOS 的环境现成的
AI 在 iOS 上的应用:
在 CoreML 的帮助下, 使用. mlmodel 模型文件可以在 XCode 中自动生成调用模型的代码文件
- https://developer.apple.com/machine-learning/
- https://github.com/apple/coremltools
.mlmodel 文件可从上面 Apple 官方网页资料里下载回来, 也可以用 Python 库 coremltools 将各种学习框架生成的文件转成. mlmodel, 目前支持对 kerasCaffescikit-learnlibsvmXGBoost 生成的模型文件转换
Coremltools 当前还只支持 python2, 执行 pip install -U coremltools, 通用会有依赖库的冲突, 可选择 pipenv 等 python 上的虚拟环境进行安装
自己训练模型并将. pkl 转成. mlmodel 可参考: https://antscript.com/post/2017-12-28-step-by-step-machine-learning/
后续使用线性回归算法训练模型自己转一转, 这里先下载苹果官方模型 MobileNet 回来试试效果:
从中可以看出, 输入是一个 224*224 的图片像素二维数组, 输出有两个, classLabel 表示最可能的结果文本, 还有一个 dictionary 表示所有的识别结果及概率
下面写个从摄像头捕获图片进行识别的 app, 也可以从相册里选择一张图, 核心代码如下:
- CVPixelBufferRef buffer = [UIImage pixelBufferFromCGImage:scaledImage.CGImage];
- MobileNetInput *input = [[MobileNetInput alloc] initWithImage:buffer];
- NSError *error = nil;
- MobileNetOutput *output = [self.mobileNet predictionFromFeatures:input error:&error];
- CVPixelBufferRelease(buffer);
- if (error) {
- return error.localizedDescription;
- } else {
- return output.classLabel;
- }
其中有三个方法比较耗时, 在 iPhone7 上大概如下:
将摄像头拍摄的图片裁剪成 224*224 大小, 约 75ms
[[MobileNet alloc] init] 约 90ms, 但是它可以只初始化一次
predictionFromFeatures 识别图像内容 35ms
App 实际效果:
背景大图是摄像头捕获的完整画面, 将中间一块方形缩小到 224*224, 左下角即模型接受的实际图片, 底部橙色背景白色文字的的即结果, 对于训练到的图片还是识别准确的
AI 在 Android 上的应用
Android 上使用训练好的模型需要依赖 TensorFlow 的 jar 和 so 库, 可通过配置 gradle:compile org.tensorflow:tensorflow-android:1.2.0, 也可以从 https://github.com/tensorflow/tensorflow 下载源码自己根据资料编译, 可参考 https://www.jianshu.com/p/6a2a98ad5c5b
方便之处在于都是 google 的产品, TensorFlow 训练的模型可保存成. pb 文件直接供 TensorFlowInferenceInterface 使用, 使用起来基本 3 个方法就可以了: feed,runfetch, 分别是提供输入执行获取结果
以下是一个简单的线性回归算法生成的 kai_linear_only_mul.pb 模型文件, 核心试验代码如下:
- mTensorFlowInterface = new TensorFlowInferenceInterface(getActivity().getAssets()
- , "file:///android_asset/kai_linear_only_mul.pb");
- mTensorFlowInterface.feed("input", new float[]{input});
- mTensorFlowInterface.run(new String[]{"k", "b", "calcY"}, false);
- float[] result = new float[1];
- mTensorFlowInterface.fetch("calcY", result);
- float calcY = result[0];
- mTensorFlowInterface.fetch("k", result);
- float k = result[0];
- mTensorFlowInterface.fetch("b", result);
- float b = result[0];
- String result = String.format(Locale.getDefault()
- , "y = %.4fx + %.2f \ninput = %.2f \nresult = %.4f"
- , k, b, input, calcY);
试验效果如下图:
参考:
http://qianhk.com/2018/02 / 客户端码农学习 ML - 工具框架 Tensorflow/
- https://www.python.org/
- https://www.scipy.org/install.html
- https://www.tensorflow.org/install/install_mac
- https://github.com/fendouai/Awesome-TensorFlow-Chinese
gpu 版 TensorFlow 需要的 cuda 资料:
- cuda: https://developer.nvidia.com/cuda-toolkit
- cuDNN: https://developer.nvidia.com/developer-program
mac 上源码编译常见问题及解决方案:
- http://www.jianshu.com/p/5df0c2f48b21
- https://github.com/JimmyKon/tensorflow_build_issue_fix/tree/master
- https://stackoverflow.com/questions/43113508/math-functions-hpp-not-found-when-using-cuda-with-eigen
- https://gist.github.com/smitshilu/53cf9ff0fd6cdb64cca69a7e2827ed0f
- https://github.com/nteract/nteract/issues/1523
- LD_LIBRARY_PATH and DYLD_LIBRARY_PATH not imported on OS X
- rather than disable SIP, I've resorted to linking the .dylib objects into /usr/local/lib. E.g., ln -s $ORACLE_HOME/.dylib /usr/local/lib
- https://devtalk.nvidia.com/default/topic/1025945/mac-cuda-9-0-driver-fully-compatible-with-macos-high-sierra-10-13-error-quot-update-required-quot-solved-/
来源: https://yq.aliyun.com/articles/514183