机器学习系统或者SysMLDL笔记

在使用过TVM、TensorRT等优秀的机器学习编译优化系统以及Pytorch、Keras等深度学习框架后,总觉得有必要从理论上对这些系统进行一些分析,虽然说在实践中学习是最快最直接的(指哪儿打哪儿、不会哪儿查哪儿),但恶补一些关于系统设计的一些知识还是非常有用了,权当是巩固一些基础了。

因此,有必要学习了解一下机器学习系统的设计和思想。

以下是本系列文章的笔记来源:

  • CSE 599W: Systems for ML
  • AI-Sys Spring 2019

注意,这一系列文章并不是传统的深度学习或者机器学习讲解,关于这部分的讲解可以看CS231n或者吴恩达的入门课,该系列文章适合在深度学习方面有经验有了解的童鞋。

附一张CSE 599W这门课(偶像tqchen主讲)一开始的讲解说明:

TIM截图20190509181944

这门课主要的重点不在深度学习理论算法,而是与深度学习有关,机器学习系统方面的讲解。

什么是深度学习

简单说下深度学习。

TIM截图20190509182437

由上图可知,深度学习所包含的基本内容,也就是以下四大部分:

  • 模型的设计(最核心的地方,不同的任务设计的模型不同,使用的具体算法也不同)
  • 目标函数,训练策略(用于训练模型权重参数的目标函数,也就是损失函数,以及一些训练的方法)
  • 正则化和初始化(与训练过程中的模型权重信息有关系,加快训练的收敛速度,属于训练部分)
  • 足够多的数据(机器学习亦或深度学习都是由数据驱动着了,没有数据的话就什么都不是)

我们在学习深度学习的过程中,难免会有一些实践,于是我们就利用以下这些优秀的深度学习库去实现我们自己设计的模型,并且设计好损失函数,一些正则化策略,最终利用这些库去读入我们需要新联的数据,然后运行等待即可。

TIM截图20190509190226

这些优秀的深度学习库(caffe、Mxnet、TF、Pytorch)我们应该都耳熟能详了,那么这些深度学习库的大概结构都是什么呢?

大部分的深度学习库都是由以下三个部分组成

  • 用户API
  • 系统组件
  • 底层架构

大多数的我们其实并不需要接触除了用户API以外的其他两个部分,而用户API也是深度学习库最顶层的部分。

TIM截图20190509191530

Logistic Regression

拿个例子简单说一下用户的API,首先我们有一个逻辑回归的任务,就拿最熟悉的MNIST数据集来进行演示,我们通过输入每个数字的向量化数据,然后通过全连接层去计算这些向量并且利用softmax函数进行预测。整个网络模型很简单已有一层全连接层。

TIM截图20190509191558

接下来我们看一下使用numpy和tinyflow(这是一个迷你的深度学习系统库,麻雀虽小五脏俱全,值得我们去学习)去训练一个简单的神经网络识别MNIST手写数据库的例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上述代码中最重要的也就是三个部分(在上图右侧已经列了出来):

  • 前向计算:因为只有一个全连接层,所以我们的计算也很简单 h k = w k T x i h_{k}=w_{k}^{T} x_{i} hk=wkTxi,其中$ x_{i} 为输入的数据, 为输入的数据, 为输入的数据,w_{k}^{T} 为权重, 为权重, 为权重,h_{k}$为权重向量和数据向量点乘的结果。计算出来结果后我们使用softmax函数对其进行分类计算得到对应十个数字的概率向量(最后输出的向量包含10个元素,分别为每个数字的可能性)
  • 反向求导:我们求出权重W关于极大似然损失的导数,这里我们人工写了出来,在右图第二部分
  • 梯度更新:我们简单对权重W进行更新,更新值为学习率乘以W的梯度,即 w ← w − η ∇ w L ( w ) w \leftarrow w-\eta \nabla_{w} L(w) wwηwL(w),也就是我们经常用的SGD

整个深度学习库中最重要的也就是上述三个部分,大部分的深度学习库已经帮我们实现了上述的代码,我们不需要重复造轮子,直接使用即可。

尝试使用TensorFlow like API

接下来,我们使用类似于TensorFlow的API来对上述描述的代码进行重构,使用TensorFlow的API格式来实现上述代码实现的训练过程。

那么,为什么要使用TensorFlow类型的API进行演示而不是采用Pytorch呢?其实TensorFlow与Pytorch构建的图类型很不一样,虽然在最近一段时间TensorFlow已经出现了eager mode,但经典的TensorFlow是采用静态图来构建整个训练过程的。

也就是说,在TF中构建的是静态图,而在Pytorch中构建的是动态图:

Computation_model

其实关于静态图和动态图对于这个话题已经经过了很多的讨论,动态图灵活多变,而静态图虽然没有动态图灵活,但是因为提前都确定好了输入参数,计算方式等等过程,系统可以针对这些特点来对计算进行规划,所以在计算过程中的性能比动态图是要高一些的。

首先我们确定要进行的前向数据以及操作算子:

  • 输入x为float32类型的向量,[None,784]中None表示当前输入的batch-size未知
  • W为权重信息,维度为[784,10]
  • y为前向计算函数,利用算子函数嵌套定义了整个计算过程。

tinyflow-1

接下来设定了损失函数,可以看到

	cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y), reduction_indices=[1]))

这句中声明了一个损失函数,使用的是分类任务中最常用的交叉熵损失,注意y_代表存放么一个数据的分类label,每一个数据的分类标签是一个元素数量为10的向量,用于与预测出来的值进行比对。具体的公式在下图右侧。

tinyflow-2

接下来设定了自动求导的过程,这一步中我们要求的是权重向量对损失值(也就是交叉熵损失后计算出来的值)的梯度,这里我们只是声明了一个函数,但是其中的计算过程是比较复杂的(也就是我们常说的自动求导的过程),这个之后会进行讲解,自动求导是我们必须要掌握的,直接手撸是必须的。

tinyflow-3

设定好了损失函数,接下来我们就要拿计算出来的梯度值来更新网络的权重信息了,在这个例子中使用SGD随机梯度下降的方式进行权重更新,我们只需要设定学习率这个超参数就可以。

tinyflow-4

因为在TF中,所有的声明式都仅仅是对要计算的流程进行声明,实际上并没有计算(这里可以称为一个懒计算的方法),也就是所谓的静态图方式定义好了整个网络以及训练的步骤,只是没有开始运作而已。

在运行完sess.run一句后,整个网络才开始正式执行起来。

tinyflow-5

这几张ppt的内容讲述了一个典型的神经网络库的运行流程(TF类型的,如果是Pytorch的话略有不同),通过这个我们可以知道一个深度学习框架的基本作用。接下来要说的就是上述过程中最为重要的自动求导过程。

计算图(Computation Graph)

计算图是实现自动求导的基础,也是每个深度学习框架必须实现的部分,接下来我们简单说说计算图是什么?

要说起计算图首先简单提一下声明式编程,正如下图中所展示的,计算图本质上是一种声明式语言,怎么说比较合适,这种语言不同于我们平时所说的python和C++,它是一种DSL(领域语言)或者一种迷你语言,这种语言深入嵌入到Python和C++中,也就是我们使用Python去操作,使用C++去具体实现。

是声明式编程不是简单地一条接一条地执行我们的指令,而是根据我们给出的所有指令创建一个计算图(computing graph)。这个图被内部优化和编译成可执行的 C++ 代码。这样我们就能同时利用上两个世界的最优之处:Python 带来的开发速度和 C++ 带来的执行速度。

最终形态就是我们提前设定好了计算逻辑,其他的交给系统就行了,具体怎么优化就不用我们去操心。

下图中就是一个简单的例子,我们定义计算的逻辑a*b+3这个逻辑,其中node表示计算内容,箭头表示依赖关系。

computation_graph1

下图中我们就利用TF-like API去实现一个简单的 t = s o f t m a x ( W ∗ x ) t=softmax(W*x) t=softmax(Wx)的过程,这个过程需要的数据(x、W)和算子(matmult、softmax)都已经提前定义好了。

computation_graph2

接下来是设置损失函数的计算部分:

computation_graph3

然后设定与自动求导相关的梯度下降部分:

computation_graph4

接下来是设定梯度更新的方式:

computation_graph5

在设定玩所有的计算逻辑后,这里正式开始计算的过程,只有执行完sess.run这句后,整个计算图才开始真正的进行计算了。

computation_graph6

上面关于自动求导的具体过程并没有展示,这个过程将在下一节中进行讲解,不过关于自动求导的具体流程也可以在CS231n这门课中见到,具体在Backpropagation and Neutal Networks这一节中。

numpy 与 TF-program 的比较

之前我们使用了numpy与TF-like API的方式模拟了一个简单的Logistic Regression的过程,也就是实现利用一个简单的全连接网络去识别手写数字集MNIST的过程,这个过程中我们使用了两种不同的方式去构建,用计算图来说就是动态图(numpy)与静态图(TF) ,而用语言类型来说就是命令式编程(numpy)和声明式编程(TF)

其实上述的numpy的例子也可以使用Pytorch做演示,因为Pytorch是一个类numpy的深度学习库,其操作的算子逻辑和numpy几乎一致,可以说是一个利用动态图结构的领域语言。

也就是说关于numpy与 TF-program 的比较,可以等同于关于动态图和静态图的比较,两者各有优缺点,但是如果追求性能和开发效率的话,静态图更胜一筹,但是如果追求灵活性和可拓展性,那么动态图的优势就展现出来了。

discuss_numpy_and_tf

未完待续

这节课的末尾提出了一些后续要讲的内容,首当其冲的就是计算图的优化。

计算图优化在TVM中这个深度学习编译器中占了很大的篇幅,正如下面所说,我们建立了计算图,因为这个计算图是静态的,所以我们可以在底层对其进行尽可能地优化,从而加快神经网络运行的速度,那么如何去优化呢?这可就是一个大学问,总之就是我们可优化的空间很大,而关于优化的具体细节放在之后进行描述。

TIM截图20190512165609

另外一点,数据并行也是重点解决的问题之一,毕竟现在的数据越来越多,显卡计算能力虽然每年提升,但是内存(具体点就是显存)的提升有限。那么如何更高效更快地训练大量的数据,直接的途径就是并行分布式训练,如何处理并行期间出现的问题也是一个重点的方向。

parallel_scheduling

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/328408.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搜索经典题——填充 9*9矩阵

题目:给定一个九行九列矩阵,填充矩阵元素,要求: 1、每一行每一列,每个小九宫格(图片画粗的地方就是)不能包含相同元素 2、每一行,每一列,每个小九宫格均会完整出现1-9的数…

Python进程池multiprocessing.Pool

环境: 鲲鹏920:192核心 内存:756G python:3.9 python单进程的耗时 在做单纯的cpu计算的场景,使用单进程核多进程的耗时做如下测试: 单进程情况下cpu的占用了如下,占用一半的核心数: 每一步…

第二百六十九回

文章目录 概念介绍设置方法示例代码内容总结 我们在上一章回中介绍了Card Widget相关的内容,本章回中将介绍国际化设置.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里说的国际化设置是指在App设置相关操作,这样可以让不同国家的…

SAP PI之Rest adapter

一,简介 REST风格接口是以http为传输协议,以xml或json或text为有效负载。下图展示了REST到XI再返回的一个过程,一个REST接口包含的信息有:服务URL、URL中带的参数、http方法(post/get/put等)、http头部、body部分的有效载荷。而X…

2023年全球软件质量效能大会(QECon北京站):核心内容与学习收获(附大会核心PPT下载)

此次大会的主题为“智能时代的质量新篇章”。来自全球的软件质量与效能专家、企业领袖、技术研发人员等齐聚一堂,共同探讨软件质量与效能的新理念、新技术、新实践。 一、大会的核心内容 1、智能时代软件质量的新挑战与机遇 随着人工智能、大数据等技术的快速发展…

react、Vue打包直接运行index.html不空白方法

react vue 在根目录下创建 vue.config.js 文件,写入 module.exports {publicPath: ./, }

【SpringCloud】这一次终于使用MQ解决了Eureka服务下线延迟感知问题

前言 其实,“通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题”是一种解,但不是最优解 1.痛点 上一篇文章的标题是: 通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题 当时在文章的末尾就…

matlab 直道转向时方向盘最小转角算法

1、内容简介 略 33-可以交流、咨询、答疑 2、内容说明 汽车主动转向,直道转向时方向盘最小转角算法,一个m脚本和simulink的计算结果 略 3、仿真分析 略 4、参考论文 汽车主动转向关键技术研究

黑马程序员_多线程

基础知识 什么是线程 被包含在进程之中, 可以调度的最小单位应用软件中互相独立,可以同时运行的功能 什么是进程 程序的基本执行实体 总结: 什么是多线程? 有了多线程,可以让程序同时做多件事情 多线程有什么作用&…

DC电源模块在新能源领域的应用前景

BOSHIDA DC电源模块在新能源领域的应用前景 DC电源模块在新能源领域有着广阔的应用前景。随着可再生能源技术的发展和普及,如太阳能和风能等的应用逐渐增多,DC电源模块在这些领域的应用越来越重要。 首先,DC电源模块可以用于太阳能发电系统…

车载音频EMI的产生及典型音频功放AW836XX的解决方案

之前针对 eCall的文章中有提到D类音频功放需要关注EMI问题(点击文章回看《车载eCall系统音频应用解决方案》),在此展开此问题并寻求解决方案。 1. EMI定义与分类 电磁干扰(Electromagnetic Interference,EMI&#xff…

geemap学习笔记049:下载Landsat数据时遇到的一个问题

前言 最近在下载Landsat 8 地面反射率数据(Surface Reflectance)时,遇到了一个问题,无论是使用geemap.ee_export_image_to_drive() 函数还是geemap.download_ee_image() 函数下载的数据,易康都打不开,显示…

【CSDN博客系列】自定义模块

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

还在为crontab表达式发愁吗,快使用这个工具

是不是每次要定义cron表达式的时候,都去百度翻找资料,cron表达式难写难记真是苦天下程序员久已。有没有什么不拥记的办法就轻松掌握呢?最近发现这个CrontabGuru神器,强烈推荐,真是广大程序员的福音了。 简介 Crontab…

电脑技巧:安装手机与Win10电脑怎样互传文件,看完你就会了

目录 一、Windows网络邻居功能 二、数据线传输 三、蓝牙连接 大家在日常工作当中,会遇到需要实现手机和Win10电脑之间的文件传输,今天小编给大家推荐使用Win10系统自带的网络邻居功能来实现手机与电脑之间数据的传输,希望对大家日常办公提…

喜讯!无垠智能模糊测试系统入选“2023软件供应链优秀成果”

近日,中国信通院信息通信软件供应链安全社区正式公布了“2023软件供应链优秀成果”,其中,云起无垠的无垠智能模糊测试系统凭借其自主研发的创新成果,成功入选该名单。 图 获奖成果 自发起以来,软件供应链优秀成果案例…

html画动态桃心

html画动态桃心 效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetwindows-1252"><title></title><style>* {padding: 0;margin…

从uptime看linux平均负载

从前遇到系统卡顿只会top。。top看不出来怎么搞呢&#xff1f; Linux系统提供了丰富的命令行工具&#xff0c;以帮助用户和系统管理员监控和分析系统性能。在这些工具中&#xff0c;uptime、mpstat和pidstat是非常有用的命令&#xff0c;它们可以帮助你理解系统的平均负载以及资…

电子行业除镍树脂深度出水0.02ppm

项目名称 电子行业贴片电容废水除镍项目 工艺选择 两级串联运行 工艺原理 亚氨基二乙酸和重金属离子通过螯合作用形成稳定的配位键&#xff0c;实现选择性吸附重金属 项目背景 贴片电容&#xff0c;也被称为多层片式陶瓷电容器&#xff08;MLCC&#xff09;&#xff0c;…

SQL Server Management Studio创建数据表

文章目录 一、建表注意事项1.1 数据类型1.2 建立数据表的基本SQL语法 二、实例说明2.1 创建数据表2.2 实例2 三、标识列和主键示例&#xff1a; 一、建表注意事项 1.1 数据类型 可以看这个去了解数据类型&#xff1a; 1.2 建立数据表的基本SQL语法 建立数据表的基本 SQL 语…