首页 > 其他分享 >TensorFlow与Serverless架构结合

TensorFlow与Serverless架构结合

时间:2023-01-26 16:11:26浏览次数:44  
标签:Serverless 10 架构 训练 模型 1875 tf TensorFlow

4.2.1 TensorFlow介绍

TensorFlow是一个基于数据流编程(Data Flow Programming)的符号数学系统,被广泛应用于各类机器学习算法的编程实现。其前身是谷歌的神经网络算法库DistBelief。TensorFlow拥有多层级结构,可部署于各类服务器、PC终端和网页,支持GPU和TPU高性能数值计算,因此也被广泛应用于谷歌内部的产品开发和各领域的科学研究。

TensorFlow可作为一个端到端开源机器学习框架,拥有全面而灵活的生态系统,其中包含各种工具、库和社区资源,可助力机器学习技术的发展,并使开发者能够轻松地构建和部署由机器学习提供支持的应用。TensorFlow的标志如图4-5所示。

 

 

 


图4-5 TensorFlow项目的标志 

TensorFlow是采用数据流图(Data Flow Graph)计算的,所以在使用该框架时我们首先需要创建一个数据流图,然后再将数据(数据以张量的形式存在)放在数据流图中计算。节点在图中表示数学操作,图中的边表示在节点间相互联系的多维数据数组,即张量(Tensor)。训练模型时,张量会不断地从数据流图中的一个节点流动(Flow)到另一个节点,这就是TensorFlow名字的由来。

TensorFlow有3个重要特点,即张量、计算图(Graph)、会话(Session)。其中,张量有多种,零阶张量为纯量或标量,也就是一个数值,如[1];一阶张量为向量,比如一维的[1, 2, 3];二阶张量为矩阵,比如二维的[[1, 2, 3]、[4, 5, 6]、[7, 8, 9]]。以此类推还有三阶张量等。张量从流图的一端流动到另一端的计算过程,生动形象地描述了复杂数据在人工神经网中的流动、传输、分析和处理模式。

计算图相当于盖房子之前设计的图纸,使得预先定义好的张量根据运算逻辑逐步运行。我们根据定义好的目标函数对计算图进行整体的优化。计算图具有可并发、可分发、可优化、可移植的优点。

有了张量和计算图,我们就可以构建模型了。但是,这样的模型怎么运行呢?虽然计算图已经有了,但是这个图是静态的,它的数据入口也没有流入数据。TensorFlow中提供了一个叫tf.Session的会话机制,它为任务提供了计算环境,但需要为这个环境提供输入数据。例如下面的代码块:

 

import tensorflow as tf # 初始化Session sess = tf.Session() # 以float32数据类型创建常量w和b w = tf.constant(3, dtype=tf.float32) b = tf.constant(4, dtype=tf.float32) # 创建x的占位符,因为是一个标量,所以shape为空 x = tf.placeholder(tf.float32, []) # 前面三个Tensor表示节点,创建它们之间联系来表示边 y = w * x + b # 运行计算图 print(sess.run(y, {x: 6})) # 每次运行后需关闭Session sess.close()

 

目前,TensorFlow拥有支持多种语言的API。以Python语言为例,官方目前在Pypi中提供了多个软件包供选择。

·tensorflow:支持CPU和GPU的最新稳定版(适用于Ubuntu和Windows)。

·tf-nightly:预览build(不稳定)。Ubuntu和Windows均支持GPU。

·tensorflow==1.15:TensorFlow 1.x的最终版本。

TensorFlow可以通过以下指令进行安装:

 

pip install --user --upgrade tensorflow  # install in $HOME

 

安装完成之后,验证安装效果:

 

python-c "import tensorflow as tf; print(tf.reduce_sum(tf.random.normal([1000, 1000])))"

 

4.2.2 TensorFlow实践:基于人工智能的衣物区分

Fashion MNIST数据集是由Zalando(德国的一家时尚科技公司)旗下研究部门提供的一个替代MNIST手写数字集的图像数据集。Fashion MNIST的大小、格式和训练/测试数据划分与原始的MNIST完全一致,所以开发者通常情况下可以直接用它来测试机器学习和深度学习算法性能,且不需要改动任何代码。

Fashion MNIST数据集包含10个类别的70 000个灰度图像(60 000/10 000的训练/测试数据划分),这些图像以低分辨率(28×28像素)展示了单件衣物,如图4-6所示。


 

 

图4-6 Fashion MNIST数据集展示 

本案例将以该数据集为例,通过TensorFlow框架实现图像分类。

1.开发前准备

本案例中使用的tf.keras是TensorFlow用来构建和训练模型的高级API。在进行图像分类案例实现之前,先导入算法相关的库,包括TensorFlow、keras等。

 

# TensorFlow and tf.keras import tensorflow as tf from tensorflow import keras # Helper libraries import numpy as np import matplotlib.pyplot as plt

 

在本案例中,可以使用60 000个图像训练网络,使用10 000个图像评估网络对图像分类的准确率。开发者可以直接从TensorFlow中导入和加载Fashion MNIST数据:

 

fashion_mnist = keras.datasets.fashion_mnist (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

 

其中:

·train_images和train_labels数组是训练集,即模型用于学习的数据。

·test_images和test_labels是测试集,被用来对模型进行测试。

数据集加载完成之后,我们还需要对数据进行预处理。这里将这些值缩小至0~1之间,然后将其输入神经网络模型:

 

train_images=train_images / 255.0 test_images=test_images / 255.0

 

神经网络的基本组成部分是神经网络层。神经网络层会从向其传送的数据中提取表示形式。大多数网络层(如tf.keras.layers.Dense)拥有在训练期间学习到的参数。这里定义一个简单的神经网络模型:

 

model = keras.Sequential([    keras.layers.Flatten(input_shape=(28, 28)),    keras.layers.Dense(128, activation='relu'),    keras.layers.Dense(10) ])

 

该网络的第一层tf.keras.layers.Flatten将图像格式从二维数组(28×28像素)转换成一维数组(28×28=784像素)。该层意味着将图像数据展开成向量形式,将特征空间转换成后面全连接网络层的输入。该层没有要学习的参数,只会重新格式化数据。展平图像后,网络包括两个tf.keras.layers.Dense层。它们是全连接神经层。第一个Dense层以128个神经元作为隐藏层,第二个(也是最后一个)层是输出层,最终输出长度为10的数组。每个节点都包含一个得分,用来表示当前图像属于10个类中的哪一类。

之后对模型进行训练,模型训练前需要定义好损失函数、优化器、评价指标等。

·损失函数:用于测量模型在训练期间的准确率。开发者通常希望最小化此函数,以便将模型“引导”到正确的方向上。

·优化器:决定模型如何根据其看到的数据和自身的损失函数进行更新。

·评价指标:用于监控训练和测试步骤。以下示例使用的准确率,即被正确分类的图像的比例。

 

model.compile(optimizer='adam',              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),              metrics=['accuracy'])

 

2.模型训练

作为TensorFlow中更为高级的API,Keras极大地简化了训练代码。通常情况下,训练只需要一行代码:

 

model.fit(train_images, train_labels, epochs=10)

 

其中,train_images、train_labels表示训练的图像数据和对应的标签,epochs表示训练迭代的次数。

启动训练后,打印如下日志:

 

Epoch 1/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.4924 - accuracy: 0.8265 Epoch 2/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.3698 - accuracy: 0.8669 Epoch 3/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.3340 - accuracy: 0.8781 Epoch 4/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.3110 - accuracy: 0.8863 Epoch 5/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.2924 - accuracy: 0.8936 Epoch 6/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.2776 - accuracy: 0.8972 Epoch 7/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.2659 - accuracy: 0.9021 Epoch 8/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.2543 - accuracy: 0.9052 Epoch 9/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.2453 - accuracy: 0.9084 Epoch 10/10 1875/1875 [==========] - 3s 1ms/step - loss: 0.2366 - accuracy: 0.9122

 

3.模型验证

在模型训练期间,系统会显示损失和准确率指标。此模型在训练集上的准确率在0.91(或91%)左右,但在训练集上的表现并不代表在实际场景中的表现。于是,我们需要对模型进行验证。

 

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2) print('Test accuracy:', test_acc)

 

验证结果为:

 

313/313 - 0s - loss: 0.3726 - accuracy: 0.8635 Test accuracy: 0.8634999990463257

 

其中,test_images、test_labels为测试集对应的图像数据和标签,最终验证模型的准确率为0.86,相比训练时的准确率降低4%。训练准确率和测试准确率之间的差距代表过拟合。过拟合是指机器学习模型在新的输入数据上的表现不如在训练数据上的表现。

4.2.3 与Serverless架构结合:目标检测系统

ImageAI是一个Python库,旨在使开发人员使用简单的几行代码构建具有包含深度学习和计算机视觉功能的应用程序和系统。ImageAI本着编程简单的原则,支持最先进的机器学习算法,用于图像预测、自定义图像预测、物体检测、视频检测、视频对象跟踪和图像预测训练。目前,该库除支持使用在ImageNet-1000数据集上训练的4种机器学习算法进行图像预测和训练,还支持使用在COCO数据集上训练的RetinaNet进行对象检测、视频检测和对象跟踪等。

ImageAI依赖TensorFlow 1.4.0及以上版本。通过对TensorFlow的进一步封装,ImageAI提供用于图像预测的4种算法,包括SqueezeNet、ResNet、InceptionV3和DenseNet。我们可以通过非常简单的方法实现图像预测、目标检测等任务。

1.本地开发

首先明确要进行目标检测的图像,如图4-7所示。


 

 

图4-7 目标检测图像 

然后根据ImageAI提供的开发文档,实现以下代码:

 

# index.py from imageai.Prediction import ImagePrediction # 模型加载 prediction = ImagePrediction() prediction.setModelTypeAsResNet() prediction.setModelPath("resnet50_weights_tf_dim_ordering_tf_kernels.h5") prediction.loadModel() predictions, probabilities = prediction.predictImage("./picture.jpg", result_count=5 ) for eachPrediction, eachProbability in zip(predictions, probabilities):    print(str(eachPrediction) + " : " + str(eachProbability))

 

完成代码开发之后,可以通过执行该文件进行效果测试:

 

laptop : 71.43893241882324 notebook : 16.265612840652466 modem : 4.899394512176514 hard_disc : 4.007557779550552 mouse : 1.2981942854821682

 

你如果在使用过程中发现模型resnet50_weights_tf_dim_ordering_tf_kernels.h5过大,耗时过长,可以按需选择模型。

·SqueezeNet(文件大小为4.82 MB,预测时间最短,准确度适中)。

·ResNet50:by Microsoft Research(文件大小为98 MB,预测时间较快,准确度高)。

·InceptionV3:by Google Brain team(文件大小为91.6 MB,预测时间慢,准确度更高)。

·DenseNet121:by Facebook AI Research(文件大小为31.6 MB,预测时间较慢,准确度最高)。

2.部署到Serverless架构

在本地完成ImageAI的基本测试之后,我们可以将目标检测模型部署到Serverless架构。在Serverless架构上,该模型的基本运行流程如图4-8所示。


 

 

图4-8 目标检测模型的基本运行流程 

按照以上流程,以阿里云函数计算和轻量级Python Web框架Bottle为例,我们可以分别实现页面代码以及逻辑代码。其中,对于逻辑代码,这里主要是将在本地开发案例代码稍做修改,与Bottle框架进行结合:

 

# -*- coding: utf-8 -*- from imageai.Prediction import ImagePrediction import base64 import bottle import random import json # 随机字符串 randomStr = lambda num=5: "".join(random.sample('abcdefghijklmnopqrstuvwxyz', num)) # 模型加载 prediction = ImagePrediction() prediction.setModelTypeAsResNet() prediction.setModelPath("/mnt/auto/model/resnet50_weights_tf_dim_ordering_tf_kernels.h5") prediction.loadModel() @bottle.route('/image_prediction', method='POST') def getNextLine():    postData = json.loads(bottle.request.body.read().decode("utf-8"))    image = postData.get("image", None)    image = image.split("base64,")[1]    # 图片获取    imagePath = "/tmp/%s" % randomStr(10)    with open(imagePath, 'wb') as f:        f.write(base64.b64decode(image))    # 内容预测    result = {}    predictions, probabilities = prediction.predictImage(imagePath, result_count=5)    for eachPrediction, eachProbability in zip(predictions, probabilities):        result[str(eachPrediction)] = str(eachProbability)    return result @bottle.route('/', method='GET') def getNextLine():    return bottle.template('./html/index.html') app = bottle.default_app() if __name__ == "__main__":    bottle.run(host='localhost', port=8080)

 

对于页面代码,这里主要是通过HTML与JavaScript实现一个便于测试的前端页面,如图4-9所示。


 

 

图4-9 前端预测页面 

为了快速进行项目的构建、依赖的安装、最终的项目部署,以及对项目进行观测,我们可以通过Serverless Devs开发者工具进行项目的托管。此时,我们需要根据Serverless Devs开发者工具相关规范,进行相关的资源描述以及行为描述:

 

edition: 1.0.0     name: imageAi                                                     # 项目名称 access: 'default'                                                 # 密钥别名 services:    imageAi:                                                      # 服务名称        component: devsapp/fc        actions:                                                  # 自定义执行逻辑            pre-deploy:                                           # 在部署之前运行                - run: s build --use-docker                       # 要运行的命令行                    path: ./                                      # 命令行运行的路径            post-deploy:                                          # 在部署之后运行                - run: s nas command mkdir /mnt/auto/.s                    path: ./                                      # 命令行运行的路径                - run: s nas upload -r -n ./.s/build/artifacts/ai-cv-image-pred-iction/server/.s/python /mnt/auto/.s/python    # 要运行的命令行                     path: ./                                    # 命令行运行的路径                - run: s nas upload -r -n ./src/model /mnt/auto/model # 要运行的命令行                     path: ./                                     # 命令行运行的路径        props:                                                    # 组件的属性值            region: cn-hangzhou            service:                name: ai-cv-image-prediction                description: 图片目标检测服务                nasConfig: auto                vpcConfig: auto                logConfig: auto            function:                name: server                description: 图片目标检测                runtime: python3                codeUri: ./src                handler: index.app                memorySize: 3072                timeout: 60                environmentVariables:                    PYTHONUSERBASE: /mnt/auto/.s/python            triggers:                - name: httpTrigger                    type: http                    config:                        authType: anonymous                        methods:                            - GET                            - POST                            - PUT            customDomains:                - domainName: auto                    protocol: HTTP                    routeConfigs:                        - path: /*

 

从上面描述的Yaml文件中不难发现,actions中的定义包括在项目部署开始前,通过Docker进行项目的构建,在项目部署完成后,在NAS中创建文件夹,上传对应的文件等。

首先是通过Serverless Devs开发者工具拉取Docker镜像,进行依赖安装。值得一提的是,在进行依赖安装之前,我们需要明确所需要的具体依赖内容:

 

tensorflow==1.13.1 numpy==1.19.4 scipy==1.5.4 opencv-python==4.4.0.46 pillow==8.0.1 matplotlib==3.3.3 h5py==3.1.0 keras==2.4.3 imageai==2.1.5 bottle==0.12.19

 

完成之后,通过s build--use-docker命令实现项目的构建,如图4-10所示。


 

 

图4-10 项目构建日志 

依赖安装完成之后,执行项目部署操作。部署完成之后,将相关文件上传到NAS,待一切都成功后,系统会进行图4-11所示的结果提示。

此时,根据工具返回的测试地址,我们可以在浏览器中打开网页,并上传之前准备好的图像进行预测,可以看到图4-12所示的结果。

可以看到,预测结果和前面在本地执行的结果是一致的。至此,我们已经成功将本地的TensorFlow项目(确切来说是基于TensorFlow开发的ImageAI项目)部署到Serverless架构,并通过Serverless架构对外暴露可视化的操作页面,以便于测试和白屏化操作。


 

 

图4-11 项目部署完成的日志 


 

 目标检测模型的测试 

3.项目优化

本项目采用的是阿里云函数计算Python运行时。相对来说,该运行时与人工智能项目相结合存在一定的复杂度。

·TensorFlow等依赖比较大,而通常情况下,函数计算可以上传的代码包大小在100MB以下,这就导致模型与依赖很难同步部署到Serverless架构。虽然本项目采用了NAS作为挂载盘,完成了大依赖包以及模型文件的上传和加载,但是在开发和部署环节相对比较复杂,比较难上手。针对这一问题,可以通过容器镜像等运行时降低复杂度。

·由于FaaS平台的环境在很多情况下和开发者的本地环境有一定差异,因此一些依赖无法跨平台运行,需要准备和FaaS平台一致的环境,进行依赖的安装和项目的打包。类似Serverless Devs的开发者工具虽然能协助依赖安装和项目打包,但是在一定程度上还是相对复杂的。此时,我们可以通过容器镜像等运行时降低这一部分的复杂度。

·深度学习项目如果有GPU实例的支持会让训练和推理的速度大幅度提升,而本实例使用的是CPU实例进行的业务逻辑处理(包括预测部分),如果这一部分可以替换成GPU实例,将会大大提高训练和推理速度,获得更好的客户端体验。

·在部署完成该项目,首次使用该项目时,不难发现网页打开的速度以及训练和推理的速度相对较慢,这充分说明冷启动的存在,并对项目产生了影响。为了在生产过程中降低冷启动带来的危害,可以适当进行实例的预留,以最大限度地保证项目性能。

·在该项目中,网页等静态资源和预测等业务逻辑全部在函数中处理的。在复杂场景下,这种做法极有可能加剧Serverless架构的冷启动,所以相对科学的做法是将页面等静态资源部署到对象存储等云产品中,函数计算仅作为计算平台,并对外暴露API以提供相对应的能力。

 

标签:Serverless,10,架构,训练,模型,1875,tf,TensorFlow
From: https://www.cnblogs.com/muzinan110/p/17067881.html

相关文章

  • scikit-learn与Serverless架构结合
    1scikit-learn介绍scikit-learn是一个面向Python的第三方提供的非常强力的机器学习库,简称sklearn,标志如下所示。它建立在NumPy、SciPy和Matplotlib上,包含从数据预处理到......
  • Serverless架构下的AI应用
    近年来,Serverless架构逐渐被更多的开发者所认识、接受,逐渐被应用到了更多领域,其中包括如今非常热门的机器学习领域。与其他领域不同的是,在Serverless架构上进行人工智能相......
  • Serverless架构下的应用开发流程
    UCBerkeley认为Serverless架构的出现过程类似于40多年前从汇编语言转向高级语言的过程,在未来Serverless架构的使用会飙升,或许服务器式云计算不会消失,但是将促进BaaS发展,以......
  • Serverless面临的挑战
    在Serverless架构为使用者提供全新的编程范式的同时,当用户在享受Serverless带来的第一波技术红利的时候,Serverless的缺点也逐渐地暴露了出来,例如函数的冷启动问题,就是如今......
  • Serverless架构下用Python轻松实现图像分类和预测
    Serverless架构下用Python轻松实现图像分类和预测图像分类是人工智能领域的一个热门话题。通俗解释就是,图像分类是一种根据各自在图像信息中所反映的不同特征,把不同类别的......
  • Serverless 触发器和函数赋能自动化运维
    Serverless架构在运维层面有着得天独厚的优势,不仅因为其事件触发可以有针对性地获取、响应一些事件,还因为其轻量化、低运维的特性让很多运维开发者甚是喜爱。在实际生产中......
  • Serverless与监控告警、自动化运维
    通过Serverless架构实现监控告警功能在实际生产中,经常需要编写一些监控脚本来监控网站服务或API服务的健康状况,包括是否可用、响应速度是否足够快等。传统的方法是直接使......
  • Serverless Workflow
    ServerlessWorkflowServerlessWorkflow(Serverless工作流)是一个用来协调多个分布式任务执行的全托管云服务。如图4-21所示,在Serverless工作流中,用户可以用顺序、分支、......
  • Serverless可观测性
    4.3.3可观测性Serverless应用的可观测性是被很多用户所关注的。可观测性是通过外部表现判断系统内部状态来衡量的。在应用开发中,可观测性帮助用户判断系统内部的健康状......
  • Serverless应用优化
    Serverless应用优化4.4.1资源评估依旧重要Serverless架构虽然是按量付费的,但是并不代表它就一定比传统的服务器租用费用低。如果对自己的项目评估不准确,对一些指标设置......