机器学习的通用工作流程
主要分为三大步:
- 定义任务:了解问题所属领域和客户需求背后的业务逻辑。收集数据集,理解数据所代表的含义,帮选择衡量任务成功的指标。
- 开发模型:准备数据,使其可以被机器学习模型处理。选择模型评估方法,并确定一个简单基准(模型应能够超越这个基准)。训练第一个具有泛化能力并且能够过拟合的模型,然后对模型进行正则化并不断调节,直到获得最佳泛化性能。
- 部署模型:将工作展示给利益相关者,将模型部署到Web服务器、移动应用程序、网页或者嵌入式设备上,监控模型在真实环境中的性能,并开始收集构建下一代模型所需要的数据。
1 定义任务
1.1 是否能够使用机器学习?
在某些情况下,机器学习可能不是理解数据的最佳方式。例如,对于音乐推荐引擎来说,矩阵分解(协同过滤)比深度学习的效果更好。当你了解完这个领域的研究现状之后,你要根据效果选择是否使用机器学习模型。
1.2 是哪个细分领域的问题?
如果确定选择机器学习模型,你需要去细分你要解决的问题是机器学习的哪个领域的问题,你要把问题划分到细分领域。以下是问题的细分领域的举例:
- 二分类
- 多分类
- 标量回归
- 向量回归
- 多标签
- 图像分割
- 排序
- 聚类
- 生成式学习
- 强化学习
- ……
在具体的划分时,你有可能把一个大问题划分成几个阶段,然后去考虑每个阶段属于哪个领域的问题。例如,你想要利用图像识别去判断生产线上有哪些是异常饼干,你首先需要开发一个目标检测模型,以便从原始图像中正确裁剪出饼干图像。随后,你才能根据裁剪出的图像进行图像的二分类。
1.3 数据从哪里获得?
你需要明白你的输入数据是什么?你要预测什么?在大多数情况下,你需要自己收集和标注新的数据集,所以,花费大量的时间找到与自己领域基本契合的数据集是基本没有结果的。你需要提前明白,收集数据集这一步是最费力、最费时、最费钱的!
你需要深刻意识到数据集的重要性!模型的泛化能力几乎完全来自训练数据的属性,即数据点的数量、标签的可靠性以及特征的质量。好的数据集是一种值得关注和投资的资产。如果你在一个项目上额外多出50各小时的可用时间,那么最有效的时间分配方式可能是收集更多的数据,而不是尝试逐步改进模型!
1.3.1 自己做还是交给别人做?
不管是自己进行数据的收集和标注还是把这个工作交给别人,你都需要尽可能的找到你想要解决这个问题领域的专家,去了解这个问题专家如何对数据进行收集和标注,了解每个关键步骤的缘由,并在收集和标注数据时尽可能的复现出来。了解完专家如何进行标注,你才需要开始考虑这个工作是自己做还是交给别人做。
自己做和交给别人做都有利有弊。交给别人做可以交给众包平台或者请专业的数据标注公司。
中国、美国最出色的众包平台是哪几个?区别在哪里? - 知乎
https://www.zhihu.com/question/19624575/answer/94887802
数据标注公司及平台排名 - 知乎
https://zhuanlan.zhihu.com/p/127836009
自己做的优势在于你可以有控制权,并且自己对标注的质量能够有效把握,缺点是花费的时间精力多。交给别人做的优势在于可能会节约时间和金钱,缺点是质量无法保证,并且这样做会夺走你的控制权。
1.3.2 用什么软件做?
对于每个任务来讲,数据标注的需求都是不同的。能够运用现成的数据标注软件当然更好,但是你要做好没有软件能够契合你的需求,你可能首先需要自己开发一个软件进行标注。高效的数据标注软件将为你节约大量的世家你,所以值得在项目早期对其进行投资!
以下是一些经典的数据标注平台:
从LabelMe到一键Label All! 8 款数据标注工具真实试用推荐-CSDN博客https://blog.csdn.net/moxibingdao/article/details/142113632
1.3.3 收集和标注的注意事项?
1.3.3.1 生产环境要统一
你要首先明白你训练的模型要最终投入生产环境。所以你的训练的数据要和生产环境产生的数据一样。你的训练数据要能够代表生产数据!假如有一个能够自动识别菜品名称的模型,你用使用专业设备拍摄的、光线充足的、令人垂涎的照片进行训练,然后投入到用户在餐厅用手机随便拍的照片进行预测,结果可能会产生很多错误。所以,你要尽可能的去了解你的训练数据和生产环境的数据有哪些不同,并且你要主动对这些差异做出修正。
1.3.3.2 数据要有时效性
有一个概念叫概念漂移。如果生产数据的属性会随着时间发生变化,那么就会出现概念漂移,导致模型的精度逐渐下降。你用实现强的IMDB数据集去预测影评的情感倾向,其结果大概率会差于用今年的数据去预测,原因在于词汇、表达、电影类型这些描述事物内在特征的属性随时间变化,导致问题的流形发生改变。因此,要解决快速的概念漂移,你需要持续的进行数据采集、标注和模型的再训练。
1.3.3.3 避免抽样偏倚
如果你的数据手机过程与你尝试预测的目标之间存在相互影响,那么就会出现抽样偏倚。假如你要去预测5G用户的规模,你选择的调查对象是上海陆家嘴的人群,尽管你对这个人群进行了随机抽样,但你本身的群体选择和你的目标之间有一定的关联,陆家嘴的人群收入高并且大多是知识分子,他们更愿意尝试新鲜事物。所以你本身调查研究的这个抽样环节本身对结果有影响。
1.4 理解数据
将数据集看作黑盒子是一种非常不好的做法。在模型开始训练之前,你应该尽可能的理解数据。你的目的是深入了解为何数据具有可预测性,你的手段大多是可视化。
这个步骤可以称为数据透视,详细的步骤和原理请参考:
机器学习中如何对数据集进行数据透视和预处理?_首先,打开此数据集,用decribe命令看它所包含的变量。 用sum命令加选择项“detail-CSDN博客https://blog.csdn.net/weixin_65259109/article/details/145806790
1.5 现有的解决方案是什么?
在大多数情况下,机器学习想要解决的问题是有一个解决方案的。可能是很多嵌套的if语句,也可能是有人在手动解决这个问题。你应该了解目前在用的是哪些系统,以及它们是如何工作的。这有助于你了解问题的全貌,并发现更多可用的数据和灵感。
1.6 问题是否有一些特殊的限制?
这里你需要考虑的大多是数据问题和部署问题。比如,你在为一个应用程序构建垃圾信息检测系统,而这个应用程序是完全端到端加密的,垃圾信息检测需要部署在最终用户的收集上,并且需要在外部数据集上进行训练(因为你拿不到内部数据)。生产线上的饼干异常检测模型需要很强的实时性,你不能将这个模型部署在具有很高延迟性的云服务器中,更多情况下,你应该部署在嵌入式设备上。
1.7 怎样确立我的目标?
要想控制一个事物,你必须能够观察它。要想成功,你首先需要知道成功的定义。同样,你需要设立指标来衡量你的模型的性能。
这个指标的设立科核从两个方面出发:机器学习的任务类型和具体的任务情景。
按照机器学习的任务类型(分类和回归)的评价指标可以参考:
机器学习:分类模型评估指标(准确率、精准率、召回率、F1、ROC曲线、AUC曲线)_二分类模型准确率多少才算高-CSDN博客https://blog.csdn.net/Vermont_/article/details/108625669机器学习-最全面的评价指标体系 - 知乎
https://zhuanlan.zhihu.com/p/359997979【机器学习】12种回归评价指标-CSDN博客
https://blog.csdn.net/fengdu78/article/details/127761729
总结一下其中的主要意思:
- 准确率衡量了预测正确的占总预测数量的比例,是一个宏观的指标。
- 精确率衡量了对于机器预测出的某一类(最后再汇总)的机器预测,机器预测的这一类中真正正确的比例,是从具体机器预测类别出发的指标。你要想去衡量机器的预测情况,用这个。
- 召回率衡量了对于真实世界中的某一类(最后再汇总)的机器预测,真实世界这一类中被机器正确预测出的比例,是从真实世界的类别出发的指标。你要想衡量实际的应用水平,用这个。
- F1分数是精确率和召回率的调和平均数。
- ROC和AUC曲线是用来解决分类问题中样本类别不均衡的情况,他们的计算方法可以忽略样本的不均衡。如果你的样本标签类别分布不均衡,用这个。
- 回归问题主要用MAE和MSE
对于具体任务的指标,你可以浏览Kaggle上的数据科学竞赛,上面展示了各种各样问题和评估指标。
2 开发模型
模型开发只是机器学习工作流程中的一个步骤,它并不是最难的一步。机器学习中最难的步骤是问题定义、数据收集、数据标注和数据处理。
2.1 准备数据
机器学习模型通常不会直接读取原始数据。在开发模型之前,你需要让原始的数据适用于模型。拿神经网络来说,你一般需要进行向量化、规范化和处理缺失值。
对于整体的架构而言,准备数据可以分为数据的通用处理和具体领域的特定处理(比如文本数据或图像数据)。以下介绍通用处理的一般步骤(以神经网络模型为例):
2.1.1 向量化
你需要将输入数据转化为向量(张量的形式)。对于类别列,你需要先转化为数字的对应关系,然后再转化为one-hot编码。对于数值类的列,你需要将数据类型转化为'float32'的格式。
以下是一个向量化的例子:
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder
# 创建示例数据
data = {
'Age': [25, 30, 35, 40],
'Salary': [50000, 60000, 80000, 90000],
'Gender': ['Male', 'Female', 'Female', 'Male'],
'City': ['New York', 'Los Angeles', 'Chicago', 'New York']
}
df = pd.DataFrame(data)
# 1. 对类别列进行数字编码,先将格式转化为类别列,
df['Gender'] = df['Gender'].astype('category').cat.codes # Male -> 1, Female -> 0 cat 是 Pandas 中 category 类型的访问器,用于操作类别数据。.cat.codes 返回每个类别对应的数字编码。
df['City'] = df['City'].astype('category').cat.codes # New York -> 1, Los Angeles -> 0, Chicago -> 2
# 2. 对类别列进行 One-Hot 编码
encoder = OneHotEncoder(sparse_output=False) # 设置 sparse_output=False 以返回密集数组
one_hot_encoded = encoder.fit_transform(df[['Gender', 'City']])
# 将 One-Hot 编码结果转换为 DataFrame
one_hot_df = pd.DataFrame(one_hot_encoded, columns=encoder.get_feature_names_out(['Gender', 'City']))
#默认情况下,OneHotEncoder 返回稀疏矩阵(scipy.sparse 格式),以节省内存。设置 sparse_output=False 后,OneHotEncoder 将返回密集数组(numpy.ndarray 格式),即普通的 NumPy 数组。
# 3. 将数值列转换为 float32 格式
df[['Age', 'Salary']] = df[['Age', 'Salary']].astype('float32')
# 4. 合并数值列和 One-Hot 编码列
final_df = pd.concat([df[['Age', 'Salary']], one_hot_df], axis=1)
# 5. 转换为张量(NumPy 数组或 TensorFlow/PyTorch 张量)
final_array = final_df.to_numpy() # 转换为 NumPy 数组
2.1.2 规范化
输入数据规范化的目的是保障神经网络能够正常进行梯度更新。一般来说,将取值相对较大的数据(比如多位整数,比神经网络权重的初始值大很多)和异质数据(比如数据的一个特征在0-1范围,另一个特征在100-200范围内)输入神经网络是不安全的。这样的数据可能导致较大的梯度更新,进而导致神经网络无法收敛。从可视化来看,训练时的loss可能会一直震荡。
所以,为了让神经网络的学习变得更容易,输入数据应该取值小,并且特征的取值要大概在一个范围内。
注意,只要达到输入取值较小(与初始值权重相比)并且在取值范围大概在同一范围内即可,并不是说一定要进行严格的归一化(均值为0,方差为1)。
对于数值列而言,你大可以将所有的数值进行严格的归一化从而使得输入符合要求。这样做是非常方便的,并且易于理解。
但是,对于类别列,将采用何种方法使得输入能够符合要求呢?
对于一些类别数较少的列,你可以直接进行数字编码:
import pandas as pd
# 示例数据
data = {'Gender': ['Male', 'Female', 'Female', 'Male']}
df = pd.DataFrame(data)
# 数字编码
df['Gender_encoded'] = df['Gender'].astype('category').cat.codes
print(df)
对于类别数量中等的列,你可以使用one-hot编码,这样可以通过增加列数量来使得数值范围的缩小:
from sklearn.preprocessing import OneHotEncoder
# 创建 OneHotEncoder 对象
encoder = OneHotEncoder(sparse_output=False)
# 对 Gender 列进行 One-Hot 编码
one_hot_encoded = encoder.fit_transform(df[['Gender']])
# 转换为 DataFrame
one_hot_df = pd.DataFrame(one_hot_encoded, columns=encoder.get_feature_names_out(['Gender']))
print(one_hot_df)
对于类别数量大的列,你可以使用嵌入的方法,从而避免one-hot导致的维度爆炸。你可以理解为用一个特定维度的向量(不再光是0-1)来标记一个特定的类别。
import tensorflow as tf
from tensorflow.keras.layers import Embedding
# 示例数据
categories = ['User1', 'User2', 'User3', 'User4']
num_categories = len(categories)
embedding_dim = 5 # 嵌入向量的维度
# 创建嵌入层
embedding_layer = Embedding(input_dim=num_categories, output_dim=embedding_dim)
# 将类别转换为数字编码
category_indices = tf.constant([0, 1, 2, 3]) # 假设类别已经编码为数字
# 获取嵌入向量
embedded_vectors = embedding_layer(category_indices)
print(embedded_vectors)
2.1.3 如何应对缺失值?
你必须尽可能的让模型的训练数据和测试数据的状态尽可能的一致。在现实世界中,很难收集到完全没有缺失的数据。但是,在模型训练和测试时,你的划分可能会导致训练集有缺失值,但是测试集没有;或者测试集有缺失值,但是训练集没有。我们的目标是尽可能的让集合的数据流形一样,所以要处理缺失值。
请注意,这里所说的出现缺失值均是指特征(即输入X)出现缺失值。如果标签出现缺失值,最好的方法是把这个样本删除。当然,下面的方法同样适用。例如,你可以将分类类别定为“此值缺失”(一个新的类别)用于预测。
2.1.3.1 删除出现缺失值的样本
import pandas as pd
# 假设我们有一个数据集df
df = pd.DataFrame({
'A': [1, 2, None, 4],
'B': [5, None, None, 8],
'C': [10, 11, 12, 13]
})
# 删除包含缺失值的样本
df_dropped = df.dropna()
2.1.3.2 填充缺失值
填充缺失值有两种方法,一种是直接使用均值或者中位数或者众数来填充。一种是再开发一个模型用来预测缺失值。两种方法的核心都是保证特征的潜在空间呈现连续性。
方法一:适用统计指标填充
# 使用均值填充
df_filled_mean = df.fillna(df.mean())
# 使用中位数填充
df_filled_median = df.fillna(df.median())
# 使用众数填充
df_filled_mode = df.fillna(df.mode().iloc[0])
方法二:使用模型预测填充
from sklearn.ensemble import RandomForestRegressor
# 假设我们使用随机森林模型来预测缺失值
def predict_missing_values(df, target_column):
# 分离出有缺失值和无缺失值的数据
df_missing = df[df[target_column].isnull()]
df_not_missing = df[~df[target_column].isnull()]
# 特征和标签
X = df_not_missing.drop(target_column, axis=1)
y = df_not_missing[target_column]
# 训练模型
model = RandomForestRegressor()
model.fit(X, y)
# 预测缺失值
X_missing = df_missing.drop(target_column, axis=1)
predicted_values = model.predict(X_missing)
# 填充缺失值
df.loc[df[target_column].isnull(), target_column] = predicted_values
return df
# 假设我们要填充列'A'的缺失值
df_filled_model = predict_missing_values(df, 'A')
2.1.3.3 均衡缺失值
在划分完训练集和测试集之后,你应该手动生成一些有缺失值的样本:将一些训练样本复制多次,然后舍弃测试数据中可能缺失的某些分类特征。
均衡缺失值的核心思想是通过在训练集中引入缺失值,使模型在训练过程中能够学习到如何处理缺失值。这样,当模型在测试集或实际应用中遇到缺失值时,能够更好地处理这些情况,从而提高模型的鲁棒性和泛化能力。
import numpy as np
# 假设我们有一个训练集train_df和测试集test_df
train_df = pd.DataFrame({
'A': [1, 2, 3, 4],
'B': [5, 6, 7, 8],
'C': [10, 11, 12, 13]
})
test_df = pd.DataFrame({
'A': [1, None, 3, 4],
'B': [5, 6, None, 8],
'C': [10, 11, 12, 13]
})
# 复制训练样本
train_df_duplicated = train_df.copy()
# 引入缺失值
np.random.seed(42)
for col in train_df_duplicated.columns:
# 随机选择一些位置引入缺失值
idx = np.random.choice(train_df_duplicated.index, size=1, replace=False)
train_df_duplicated.loc[idx, col] = np.nan
# 合并数据集
train_df_balanced = pd.concat([train_df, train_df_duplicated], ignore_index=True)
2.2 选择评估方法
机器学习的目的在于实现泛化。但是,你需要一个指标来引领你一步一步前进,因为你没有办法观察到机器是如何反应现实的。
为了更加清晰的评估机器的泛化能力,你需要选择结合你的目标选择合适的评估方法。
你可以将目标选择理解为计算一个具体的数。合适的评估方法是如何组织合适的流程用于计算这些数。
关于目标选择请见1.7.
关于合适的评估方法请见下面博客的简单留出验证、K折交叉验证、带有重复的K折交叉验证:
如何对机器学习模型进行评估?-CSDN博客https://blog.csdn.net/weixin_65259109/article/details/145731095大多数情况下,第一种方法就足以得到很好的效果。不过要始终注意验证集的代表性。并且注意训练集和验证集之间不要存在冗余样本(重复样本)。
2.3 超越基准
2.3.1 设置基准
你开发的模型最好是有意义的,意思是你的初始目标是获得统计功效。
你需要先去计算为了解决这个问题使用随机器的结果如何,使用一些简单的统计和机器学习模型的结果又如何。这样你就得到了一些基准。你的目标是不断的超越这些基准,以此证明你模型的优越性。
你可以参考下面博客的“2 设置指标并超越”部分详细了解:
如何对机器学习模型进行评估?-CSDN博客https://blog.csdn.net/weixin_65259109/article/details/145731095
2.3.2 超越基准
这部分是你构建模型的主要部分,你需要通过你在数据和模型的变化来不断提高模型的表现。
2.3.2.1 特征工程
你需要对数据进行处理来找到最适合输入的特征。
对于已有数据,你需要对已有数据进行筛选,过滤掉没有信息量的特征。
# 2. 筛选特征
X = df.drop('target', axis=1)
y = df['target']
model = RandomForestClassifier()
model.fit(X, y)
feature_importances = model.feature_importances_
print("\n特征重要性:")
for feature, importance in zip(iris.feature_names, feature_importances):
print(f"{feature}: {importance:.4f}")
对于未知的数据,你需要尽可能扩充可用的数据集,并且利用自己对问题的了解,开发新的有用的特征。
2.3.2.2 选择模型架构
在选择模型架构之前你必须了解现在已有的模板,来明确前人筛选出的哪些模型最适合、哪些模型不能用。对于神经网络而言,提供几种常见的架构作为参考:
- 密集连接网络
- 卷积神经网络
- 循环神经网络
- Transformer
- ……
2.3.2.3 选择模型配置
对于神经网络而言,最重要的是你应该使用什么损失函数?批量大小和学习率分别是多少?等等。
激活函数:
神经网络中的激活函数及其各自的优缺点、以及如何选择激活函数_神经网络的激活函数有哪些?他们对神经网络的性能有何影响。-CSDN博客https://blog.csdn.net/qq_40765537/article/details/106086418深度学习神经网络中激活函数选择对模型性能的影响研究 - 知乎
https://zhuanlan.zhihu.com/p/688178835为神经网络选择正确的激活函数 - 知乎
https://zhuanlan.zhihu.com/p/460177194损失函数:
训练深度学习神经网络时如何选择损失函数_mlp损失函数-CSDN博客https://blog.csdn.net/Hanx09/article/details/107393370
批量大小:
Batch Size的相关问题及如何选择Batch Size的大小 - 知乎https://zhuanlan.zhihu.com/p/420167970
2.3.2.4 训练并重新思考
你需要不断的对你开发的模型进行调试,你的最终的性能体现在验证集的效果上。验证集产生的指标要能够超过基线模型。
你需要做好准备的是,你设计的模型不是一定能够取得统计功效。如果你尝试了多种合理架构之后,仍然无法超越简单基准。那么,你需要回到定义任务的部分重新进行思考。
2.4 使模型过拟合
你现在已经得到一个具有统计功效的模型。你需要找到最适合你要处理的问题的最优模型,你要去找到优化和泛化的临界点,要找到欠拟合和过拟合的界限,从而得到稳健拟合的模型。对于神经网络而言,你必须首先实现模型正常训练,然后实现超越基准,最后再去实现过拟合。实现过拟合的目的在于找到稳健拟合的位置。
为了实现过拟合,你可以通过增加模型容量、调整训练轮数的方法,详细请见:
神经网络模型如何改进模型拟合?-CSDN博客https://blog.csdn.net/weixin_65259109/article/details/145791879
2.5 改进模型泛化
在进行这一步之前你必须实现模型超过基线的统计性能,并且模型实现了过拟合。
改进模型泛化可以通过正则化和调节超参数实现。这一步需要不断的实验从而找到最优最简单具有最强泛化能力的模型。
关于正则化的操作请见:
如何提高神经网络的泛化能力?-CSDN博客https://blog.csdn.net/weixin_65259109/article/details/145805689关于调节超参数,你可以利用超参数自动调节软件(如KerasTuner)实现。
2.6 测试集最后评估一次
一旦你开发出令人满意的模型配置,你就可以在所可用数据(训练数据和验证数据)上训练最终的生产模型,然后在测试集上最后评估一次。
如果模型的性能与之前实验(验证集上)的相差不大,恭喜你这个模型是可用的。
如果模型在测试集上的性能比验证集上相差很大,那么可能是你的验证流程不可靠,或者没有找到稳健拟合的位置。这时你可以更换验证的指标和方法,或者在模型架构和模型配置上进行重新思考。
3 部署模型
3.1 向利益相关者解释你的工作并设定预期
模型投入到生产环境中才能完成它的使命,而投入生产环境需要开发者和客户达到共识。
首先,你需要让客户明白模型不是万能的,它不能满足一些天马星空的需求。这部分你需要展示一些失败模式的案例,特别是那些错误类别让人吃惊的样本,从而打破客户的一些幻想。
其次,你在展示模型在具体应用场景时的效果时,应该侧重使用生产环境所能够衡量的指标。尽量不要使用精度,而应该使用假阴性率和假阳性率或者召回率这样更贴近生产环境的指标。例如,如果你说“模型精度为98%”,这样会让大多数客户认为模型几乎全部能够非常高标准的完成任务,但是事实和客户的感觉会很不一样。你可以说“在这种情况下,模型将有5%的假阴性率和2.5%的假阳性率,平均每天有200笔交易会被标记为欺诈交易并送给人工检查。平均每天会有14笔欺诈性交易会被遗漏,平均每天会有266笔欺诈性交易会被正确识别”。
最后,你要和客户讨论模型开发过程中关键参数对模型训练结果再到实际的生产环境的影响。
3.2 部署推断模型
在部署时你大多会遇到如下问题:
- 生产环境的硬件不支持相同环境的部署(如嵌入式系统、移动应用系统)
- 生产环境的其他软件部分与模型环境不兼容(例如其他部分用java、C++编写)
- 生产环境只需要模型的推断部分,是不是只要部署推断部分并进行优化?
以下介绍几种可用的模型部署方式,可能能够解决上述问题:
3.2.1 推断模型优化
适用条件:
- 所要部署的模型环境有容量和性能的限制
可选方法:
- 权重剪枝:把权重矩阵中不是那么重要的参数舍弃,从而减少模型占用的内存资源和计算资源
- 权重量化:把深度学习模型适用的数据类型(float32)量化为(int8),这样可以使推断模型大小缩减为原来的四分之一
以上两种方法均使用Tensorflow生态系统的一个权重剪枝和量化的工具包实现,它与Keras API深度集成。
3.2.2 将模型部署为REST API
这是指将模型部署在云服务器上(自己托管可以,第三方托管也可以)。
适用条件:
- 你的生产环境要能够可靠的访问互联网
- 应用程序要没有严格的延迟要求
- 所产生的数据流和模型架构本身数据不是敏感的
可选方法:
- 使用Flask实现与云服务器的交互
- 使用TensorFlow Serving将模型包装成一个API
3.2.3 在设备上部署模型
你的设备可以是智能手机、嵌入式ARM CPU或微控制器。
适用条件:
- 模型有严格的延迟限制
- 模型需要在较差的网络环境下运行
- 模型能够足够小,能够在硬件环境下运行(你可以使用TensorFlow Model Optimization Toolkit进行优化)
- 数据和模型架构需要保密
可选方法:
- TensorFlow Lite,它是一个用于设备端推断的高效深度学习框架,可以在安卓智能手机和iOS智能手机、基于ARM64架构的计算机、树莓派或者某些微控制器上运行。TensorFlow Lite包含一个转换器,可以直接将Keras模型直接转化为TensorFlow Lite格式。
3.2.4 在浏览器中部署模型
在浏览器部署意味着你在本地运行,使用本地的浏览器实现与模型的交互。
适用条件:
- 你想让用户分担计算开销,或者想利用用户的GPU等计算资源
- 应用程序有严格的延迟限制
- 数据和模型架构需要保密
- 模型已经下载和缓存后,应用程序可以在没有网络连接的环境运行
- 模型的大小要和硬件环境匹配
可选方法:
- TensorFlow.js,它是一个用于深度学习的Javascript库,几乎实现了所有的Keras API。你可以很容易将已保存的Keras模型导入TensorFlow.js,将其作为基于浏览器的Javascript应用程序或桌面Electron应用程序的一部分进行查询。
3.3 监控模型在真实环境中的性能
你现在已经在生产环境中部署好了一个模型,并应用在实际的生产环境中。
你接下来需要检查在实际应用中,日志记录和状态监控模块是否能够正常运行。
最后,你需要测试部署的这个模型对原有生产环境的整体的影响,与其余部分的相互作用,以及模型最终对业务指标的影响。
在最后一步,你需要量化模型产生的实际效益。你可以通过随机A/B测试(其本质是对比实验)来衡量差异,差异的结果很可能归因于该模型。并且你也需要对生产数据上的预测结果进行定期的人工审核,如果无法进行人工审核,你可以采用用户调查的方法来确定模型在生产环境中的实际效果。
3.4 维护并迭代模型
任何模型都不能永远有效,随着时间的推进概念漂移会显得越来越明显,这时你需要准备下一代模型的开发和迭代的准备。你需要做的工作是:
- 收集并关注生产数据的变化
- 记录那些出错的样本