在TensorFlow中使用模型剪枝将机器学习模型变得更小

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
交互式建模 PAI-DSW,5000CU*H 3个月
模型训练 PAI-DLC,5000CU*H 3个月
简介: 在TensorFlow中使用模型剪枝将机器学习模型变得更小

学习如何通过剪枝来使你的模型变得更小

640.png

剪枝是一种模型优化技术,这种技术可以消除权重张量中不必要的值。这将会得到更小的模型,并且模型精度非常接近标准模型。

在本文中,我们将通过一个例子来观察剪枝技术对最终模型大小和预测误差的影响。

导入常见问题


我们的第一步导入一些工具、包:

  • Os和Zi    pfile可以帮助我们评估模型的大小。
  • tensorflow_model_optimization用来修剪模型。
  • load_model用于加载保存的模型。
  • 当然还有tensorflow和keras。


最后,初始化TensorBoard,这样就可以将模型可视化:

importosimportzipfileimporttensorflowastfimporttensorflow_model_optimizationastfmotfromtensorflow.keras.modelsimportload_modelfromtensorflowimportkeras%load_exttensorboard

数据集生成


在这个实验中,我们将使用scikit-learn生成一个回归数据集。之后,我们将数据集分解为训练集和测试集:

fromsklearn.datasetsimportmake_friedman1X, y=make_friedman1(n_samples=10000, n_features=10, random_state=0)
fromsklearn.model_selectionimporttrain_test_splitX_train, X_test, y_train, y_test=train_test_split(X, y, test_size=0.33, random_state=42)

没有应用剪枝技术的模型


我们将创建一个简单的神经网络来预测目标变量y,然后检查均值平方误差。在此之后,我们将把它与修剪过的整个模型进行比较,然后只与修剪过的Dense层进行比较。


接下来,在30个训练轮次之后,一旦模型停止改进,我们就使用回调来停止训练它。

early_stop = keras.callbacks.EarlyStopping(monitor=’val_loss’, patience=30)

我们打印出模型概述,以便与运用剪枝技术的模型概述进行比较。

model=setup_model()
model.summary()

640.png

让我们编译模型并训练它。

tf.keras.utils.plot_model(
model,
to_file=”model.png”,
show_shapes=True,
show_layer_names=True,
rankdir=”TB”,
expand_nested=True,
dpi=96,
)

640.png

现在检查一下均方误差。我们可以继续到下一节,看看当我们修剪整个模型时,这个误差是如何变化的。

fromsklearn.metricsimportmean_squared_errorpredictions=model.predict(X_test)
print(‘WithoutPruningMSE%.4f%mean_squared_error(y_test,predictions.reshape(3300,)))
WithoutPruningMSE0.0201

当把模型部署到资源受限的边缘设备(如手机)时,剪枝等优化模型技术尤其重要。

采用等稀疏修剪对整个模型进行剪枝

我们将上面的MSE与修剪整个模型得到的MSE进行比较。第一步是定义剪枝参数。权重剪枝是基于数量级的。这意味着在训练过程中一些权重被转换为零。模型变得稀疏,这样就更容易压缩。由于可以跳过零,稀疏模型还可以加快推理速度。


预期的参数是剪枝计划、块大小和块池类型。

  • 在本例中,我们设置了50%的稀疏度,这意味着50%的权重将归零。
  • block_size —— 矩阵权重张量中块稀疏模式的维度(高度,权值)。
  • block_pooling_type —— 用于对块中的权重进行池化的函数。必须是AVG或MAX。

 

fromtensorflow_model_optimization.sparsity.kerasimportConstantSparsitypruning_params= {
'pruning_schedule': ConstantSparsity(0.5, 0),
'block_size': (1, 1),
'block_pooling_type': 'AVG'}

现在,我们可以应用我们的剪枝参数来修剪整个模型。

fromtensorflow_model_optimization.sparsity.kerasimportprune_low_magnitudemodel_to_prune=prune_low_magnitude(
keras.Sequential([
tf.keras.layers.Dense(128, activation='relu', input_shape=(X_train.shape[1],)),
tf.keras.layers.Dense(1, activation='relu')
]), **pruning_params)

我们检查模型概述。将其与未剪枝模型的模型进行比较。从下图中我们可以看到整个模型已经被剪枝 —— 我们将很快看到剪枝一个稠密层后模型概述的区别。

model_to_prune.summary()

640.png

在TF中,我们必须先编译模型,然后才能将其用于训练集和测试集。

model_to_prune.compile(optimizer=’adam’,
loss=tf.keras.losses.mean_squared_error,
metrics=[‘mae’, ‘mse’])

由于我们正在使用剪枝技术,所以除了早期停止回调函数之外,我们还必须定义两个剪枝回调函数。我们定义一个记录模型的文件夹,然后创建一个带有回调函数的列表。

tfmot.sparsity.keras.UpdatePruningStep()

使用优化器步骤更新剪枝包装器。如果未能指定剪枝包装器,将会导致错误。

tfmot.sparsity.keras.PruningSummaries()

将剪枝概述添加到Tensorboard。

log_dir=.models’callbacks= [
tfmot.sparsity.keras.UpdatePruningStep(),
#LogsparsityandothermetricsinTensorboard.
tfmot.sparsity.keras.PruningSummaries(log_dir=log_dir),
keras.callbacks.EarlyStopping(monitor=’val_loss’, patience=10)
]

有了这些,我们现在就可以将模型与训练集相匹配了。

model_to_prune.fit(X_train,y_train,epochs=100,validation_split=0.2,callbacks=callbacks,verbose=0)

在检查这个模型的均方误差时,我们注意到它比未剪枝模型的均方误差略高。

prune_predictions=model_to_prune.predict(X_test)
print(‘WholeModelPrunedMSE%.4f%mean_squared_error(y_test,prune_predictions.reshape(3300,)))
WholeModelPrunedMSE0.1830

用多项式剪枝计划对稠密层进行剪枝

现在让我们实现相同的模型,但这一次,我们将只剪枝稠密层。请注意在剪枝计划中使用多项式衰退函数。

fromtensorflow_model_optimization.sparsity.kerasimportPolynomialDecaylayer_pruning_params= {
'pruning_schedule': PolynomialDecay(initial_sparsity=0.2,
final_sparsity=0.8, begin_step=1000, end_step=2000),
'block_size': (2, 3),
'block_pooling_type': 'MAX'}
model_layer_prunning=keras.Sequential([
prune_low_magnitude(tf.keras.layers.Dense(128, activation='relu',input_shape=(X_train.shape[1],)),
**layer_pruning_params),
tf.keras.layers.Dense(1, activation='relu')
  ])


从概述中我们可以看到只有第一个稠密层将被剪枝。

model_layer_prunning.summary()

640.png

然后我们编译并拟合模型。

model_layer_prunning.compile(optimizer=’adam’,
loss=tf.keras.losses.mean_squared_error,
metrics=[‘mae’, ‘mse’])
model_layer_prunning.fit(X_train,y_train,epochs=300,validation_split=0.1,callbacks=callbacks,verbose=0)

现在,让我们检查均方误差。

layer_prune_predictions=model_layer_prunning.predict(X_test)
print(‘LayerPrunnedMSE%.4f%mean_squared_error(y_test,layer_prune_predictions.reshape(3300,)))
LayerPrunnedMSE0.1388

由于我们使用了不同的剪枝参数,所以我们无法将这里获得的MSE与之前的MSE进行比较。如果您想比较它们,那么请确保剪枝参数是相同的。在测试时,对于这个特定情况,layer_pruning_params给出的错误比pruning_params要低。比较从不同的剪枝参数获得的MSE是有用的,这样你就可以选择一个不会使模型性能变差的MSE。

比较模型大小

现在让我们比较一下有剪枝和没有剪枝模型的大小。我们从训练和保存模型权重开始,以便以后使用。

deftrain_save_weights():
model=setup_model()
model.compile(optimizer='adam',
loss=tf.keras.losses.mean_squared_error,
metrics=['mae', 'mse'])
model.fit(X_train,y_train,epochs=300,validation_split=0.2,callbacks=callbacks,verbose=0)
model.save_weights('.models/friedman_model_weights.h5')
train_save_weights()

我们将建立我们的基础模型,并加载保存的权重。然后我们对整个模型进行剪枝。我们编译、拟合模型,并在Tensorboard上将结果可视化。

base_model=setup_model()
base_model.load_weights('.models/friedman_model_weights.h5') #optionalbutrecommendedformodelaccuracymodel_for_pruning=tfmot.sparsity.keras.prune_low_magnitude(base_model)
model_for_pruning.compile(
loss=tf.keras.losses.mean_squared_error,
optimizer='adam',
metrics=['mae', 'mse']
)
model_for_pruning.fit(
X_train,
y_train,
callbacks=callbacks,
epochs=300,
validation_split=0.2,
verbose=0)
%tensorboard--logdir={log_dir}

以下是TensorBoard的剪枝概述的快照。

640.png

在TensorBoard上也可以看到其它剪枝模型概述

640.png

现在让我们定义一个计算模型大小函数

defget_gzipped_model_size(model,mode_name,zip_name):
#Returnssizeofgzippedmodel, inbytes.
model.save(mode_name, include_optimizer=False)
withzipfile.ZipFile(zip_name, 'w', compression=zipfile.ZIP_DEFLATED) asf:
f.write(mode_name)
returnos.path.getsize(zip_name)

现在我们定义导出模型,然后计算大小。

对于剪枝过的模型,tfmot.sparsity.keras.strip_pruning()用来恢复带有稀疏权重的原始模型。请注意剥离模型和未剥离模型在尺寸上的差异。

model_for_export=tfmot.sparsity.keras.strip_pruning(model_for_pruning)
print("Size of gzipped pruned model without stripping: %.2f bytes"% (get_gzipped_model_size(model_for_pruning,'.models/model_for_pruning.h5','.models/model_for_pruning.zip')))
print("Size of gzipped pruned model with stripping: %.2f bytes"% (get_gzipped_model_size(model_for_export,'.models/model_for_export.h5','.models/model_for_export.zip')))
Sizeofgzippedprunedmodelwithoutstripping: 6101.00bytesSizeofgzippedprunedmodelwithstripping: 5140.00bytes

对这两个模型进行预测,我们发现它们具有相同的均方误差。

model_for_prunning_predictions=model_for_pruning.predict(X_test)
print('Model for Prunning Error %.4f'%mean_squared_error(y_test,model_for_prunning_predictions.reshape(3300,)))
model_for_export_predictions=model_for_export.predict(X_test)
print('Model for Export Error %.4f'%mean_squared_error(y_test,model_for_export_predictions.reshape(3300,)))
ModelforPrunningError0.0264ModelforExportError0.0264

最终想法

您可以继续测试不同的剪枝计划如何影响模型的大小。显然这里的观察结果不具有普遍性。也可以尝试不同的剪枝参数,并了解它们如何影响您的模型大小、预测误差/精度,这将取决于您要解决的问题。

为了进一步优化模型,您可以将其量化。如果您想了解更多,请查看下面的回购和参考资料。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
20天前
|
机器人
1024 云上见 使用 PAI+LLaMA Factory 微调 Qwen2-VL 模型,搭建 “文旅领域知识问答机器人” 领精美计时器
1024 云上见 使用 PAI+LLaMA Factory 微调 Qwen2-VL 模型,搭建 “文旅领域知识问答机器人” 领精美计时器
72 3
|
6天前
|
机器学习/深度学习 TensorFlow API
机器学习实战:TensorFlow在图像识别中的应用探索
【10月更文挑战第28天】随着深度学习技术的发展,图像识别取得了显著进步。TensorFlow作为Google开源的机器学习框架,凭借其强大的功能和灵活的API,在图像识别任务中广泛应用。本文通过实战案例,探讨TensorFlow在图像识别中的优势与挑战,展示如何使用TensorFlow构建和训练卷积神经网络(CNN),并评估模型的性能。尽管面临学习曲线和资源消耗等挑战,TensorFlow仍展现出广阔的应用前景。
25 5
|
8天前
|
机器学习/深度学习 数据采集 Python
从零到一:手把手教你完成机器学习项目,从数据预处理到模型部署全攻略
【10月更文挑战第25天】本文通过一个预测房价的案例,详细介绍了从数据预处理到模型部署的完整机器学习项目流程。涵盖数据清洗、特征选择与工程、模型训练与调优、以及使用Flask进行模型部署的步骤,帮助读者掌握机器学习的最佳实践。
31 1
|
12天前
|
机器学习/深度学习 数据采集 监控
如何使用机器学习模型来自动化评估数据质量?
如何使用机器学习模型来自动化评估数据质量?
|
11天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
33 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
17天前
|
机器人
1024 云上见 使用 PAI+LLaMA Factory 微调 Qwen2-VL 模型,搭建 “文旅领域知识问答机器人” 领 200个 精美计时器等你领
1024 云上见 使用 PAI+LLaMA Factory 微调 Qwen2-VL 模型,搭建 “文旅领域知识问答机器人” 领 200个 精美计时器等你领
61 2
|
23天前
|
人工智能 算法 测试技术
PAI 大语言模型评测平台现已支持裁判员模型评测
本文将为您介绍如何在 PAI 大语言模型评测平台,基于裁判员模型,评价开源模型或者微调后模型的性能。该功能限时免费,欢迎使用。
|
5天前
|
机器学习/深度学习 算法
探索机器学习模型的可解释性
【10月更文挑战第29天】在机器学习领域,一个关键议题是模型的可解释性。本文将通过简单易懂的语言和实例,探讨如何理解和评估机器学习模型的决策过程。我们将从基础概念入手,逐步深入到更复杂的技术手段,旨在为非专业人士提供一扇洞悉机器学习黑箱的窗口。
|
6月前
|
机器学习/深度学习 存储 搜索推荐
利用机器学习算法改善电商推荐系统的效率
电商行业日益竞争激烈,提升用户体验成为关键。本文将探讨如何利用机器学习算法优化电商推荐系统,通过分析用户行为数据和商品信息,实现个性化推荐,从而提高推荐效率和准确性。
233 14
|
6月前
|
机器学习/深度学习 算法 搜索推荐
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)

相关产品

  • 人工智能平台 PAI