MNIST: http://yann.lecun.com/exdb/mnist/
MNIST机器学习入门:http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.html
iOS MNIST: https://academy.realm.io/posts/brett-koonce-cnns-swift-metal-swift-language-user-group-2017/
如果你是机器学习领域的新手, 我们推荐你从这里开始,通过讲述一个经典的问题, 手写数字识别 (MNIST), 让你对多类分类 (multiclass classification) 问题有直观的了解。
手写数字的 MNIST 数据库具有6万个示例的培训集和1万个示例的测试集。它是由 NIST 提供的更大集合的子集。数字已按大小规范化, 并以固定大小的图像为中心。
这是一个很好的数据库, 人们谁想尝试学习技术和模式识别方法的真实世界的数据, 同时花费极小的努力, 对预处理和格式。
虽然只是数字识别, 将帮助您了解如何编写自己的自定义网络从头开始使用 Keras, 并将其转换为 CoreML 模型。因为你将学习和实验很多新的东西, 我觉得最好坚持与一个简单的网络, 具有可预测的结果比工作与深层网络。
目标
在 iOS 上面识别手写数字
根据输入图片,这里我们直接用 iOS 实现绘图,也可以识别本机图片或者拍照方式,给出预测数字
步骤
- 用 keras 训练模型,输入图片,得到预测标签
- 导入 iOS ,输入图片,得到标签
准备:
一台具有 MacOS 10.13、iOS 11 和 Xcode 9 的计算机。
生成模型
给出了手写数字的 28×28
图像, 找到了能够准确预测数字的模型。
我们需要在我们的机器上设置一个工作环境来培训、测试和转换自定义的深层学习模式, CoreML 模型。我使用 python
虚拟环境 virtualenvwrapper
。打开终端并键入以下命令来设置环境。
$ mkvirtualenv -p python2.7 coreml
(coreml) $ pip install pandas matplotlib jupyter notebook scipy scikit-learn opencv-python
(coreml) $ pip install tensorflow
(coreml) $ pip install keras
(coreml) $ pip install unittest2
(coreml) $ pip install h5py==2.8.0rc1
(coreml) $ pip install coremltools
设计 & 培训网络:
对于代码的这一部分, 您可以创建一个 python 文件或者运行的 jupyter 笔记本。
$ jupyter notebook
- 首先, 让我们导入一些必要的库, 并确保 keras 后端在 TensorFlow。
import numpy as np
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.utils import np_utils
# (Making sure) Set backend as tensorflow
from keras import backend as K
K.set_image_dim_ordering('tf')
现在让我们为培训和测试准备数据集。
# Define some variables
num_rows = 28
num_cols = 28
num_channels = 1
num_classes = 10
# Import data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], num_rows, num_cols, num_channels).astype(np.float32) / 255
X_test = X_test.reshape(X_test.shape[0], num_rows, num_cols, num_channels).astype(np.float32) / 255
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
设计培训模型。
# Model
model = Sequential()
model.add(Conv2D(32, (5, 5), input_shape=(28, 28, 1), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(128, (1, 1), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
训练模型。
# Training
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2)
- 通过去除辍学层来准备推理模型。
# Prepare model for inference
for k in model.layers:
if type(k) is keras.layers.Dropout:
model.layers.remove(k)
最后保存模型。
model.save('mnistCNN.h5')
Keras 到 CoreML:
要将您的模型从 Keras 转换为 CoreML, 我们需要执行更多的其他步骤。我们的深层学习模式期望28×28正常化灰度图像, 并给出了类预测的概率为输出。此外, 让我们添加更多的信息, 我们的模型, 如许可证, 作者等。
import coremltools
output_labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
scale = 1/255.
coreml_model = coremltools.converters.keras.convert('./mnistCNN.h5',
input_names='image',
image_input_names='image',
output_names='output',
class_labels=output_labels,
image_scale=scale)
coreml_model.author = 'iOSDevLog'
coreml_model.license = 'MIT'
coreml_model.short_description = 'Model to classify hand written digit'
coreml_model.input_description['image'] = 'Grayscale image of hand written digit'
coreml_model.output_description['output'] = 'Predicted digit'
coreml_model.save('mnistCNN.mlmodel')
通过执行上述代码, 您应该在当前目录中观察名为 "mnistCNN. mlmodel" 的文件。
祝贺!您已经设计了您的第一个 CoreML 模型。使用此信息, 您可以使用 Keras 设计任何自定义模型, 并将其转换为 CoreML 模型。
iOS 应用程序:
这里的大部分内容都集中在应用程序开发上, 我只会解释一些重要的事情。
与对象识别应用程序类似, 我添加了一个名为 DrawView 的自定义视图, 用于通过手指滑动来书写数字 (此视图的大多数代码都是从 Apple 的 Metal 示例项目中获得的灵感)。
我添加了两个名为 "新建" 和 "运行" 的BarBttonItem, 其名称代表其功能。 CoreML 需要 CVPixelBuffer 格式的图像所以我添加了辅助程序代码, 将其转换为必需的格式。
接下来就是输入图片,将预测的输出的数字显示在 label 上面。
源码:https://github.com/iOSDevLog/1Day1App/tree/master/code/016.%20MNIST
简宝玉写作群日更打卡第21天