在开篇之初,我们提到了最简单的AI算法:线性回归 (Linear Regression)。让我们重温一下一元线性回归算法的公式:
先计算出所有输入点的坐标平均值:
然后可以得到方程 y=ax+b的系数a和b:
在这个过程中,需要计算6次向量运算,虽然工程师使用CUDA能够很方便地调用GPU,来计算向量加法或点乘(卷积)运算,但工程师依然需要掌握算法本身。
实际上,一元线性回归是最简单的AI算法。各类AI算法还有很多:
Linear regression 线性回归
Logistic regression 罗吉斯回归
Decision tree 决策树
SVM algorithm 支撑向量机
Naive Bayes algorithm 朴素贝叶斯
KNN algorithm K-近邻演算法
K-means 欧几里得距离聚类
Random forest algorithm 随机森林算法
Dimensionality reduction algorithms 降维算法
Gradient boosting algorithm 梯度提升算法
……
看到这里,读者们是不是觉得,你们和小H一样,感觉到有一只瞌睡虫从鼻孔飞进了自己的脑子,并且觉得自己眼睛里被滴入了眼药水,不,是502胶水……
幸好,我们不需要了解这些算法的细节。实际上,为了避免工程师们重复发明轮子,并且浪费时间在研究这些算法的细节上,Google推出了一个机器学习框架——Tensorflow。
Tensorflow是基于CUDA实现的真正的“机器学习”开发框架。让我们举一个例子:
import tensorflow as tf
import numpy as np
# 使用 NumPy 生成假数据(phony data), 总共 100 个点.
x_data = np.float32(np.random.rand(2, 100)) # 随机输入
y_data = np.dot([0.100, 0.200],
x_data) + 0.300
# 构造一个线性模型
#
b = tf.Variable(tf.zeros([1]))
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0))
y = tf.matmul(W, x_data) + b
# 最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
# 初始化变量
init = tf.initialize_all_variables()
# 启动图 (graph)
sess = tf.Session()
sess.run(init)
# 拟合平面
for step inxrange(0, 201):
sess.run(train)
if step % 20 == 0:
print step, sess.run(W), sess.run(b)
# 得到最佳拟合结果 W: [[0.100 0.200]], b: [0.300]
这段代码来自Tensorflow的官方文档,调用tensorflow使用迭代法,在三维空间中,对随机生成的100个点进行拟合,最终得到一个平面,也就是完成了调参。
我们对这段python代码进行解读:
在第1行引入了tensorflow的类库后,9-11行利用tensorflow类库定义线性模型,随后13行定义残差为均方误差(mean square error),14行中利用所谓的“梯度下降法”进行拟合,最终进行200次迭代,每20次输出一次迭代过程数据,得到拟合结果,工作流程如下图:
我们发现,在利用Tensorflow开发的机器学习代码中,程序员完全不需要自己实现任何算法的细节,只需要调用Tensorflow提供的模型就可以了。
基于Tensorflow开发的AI/ML应用架构如下图:
图中,CUDA对高级语言层面屏蔽了CPU与GPU硬件之间交互的细节,使得开发者可以通过调用CUDA库实现将并行运算交给GPU处理;而Tensorflow又调用CUDA库,将常见的机器学习算法进行封装,使得数学水平没有那么好的工程师们也可以简单快速地开发AI/ML应用。
让我们再回到《大模型与AI底层技术揭秘 (2) 人妖之间的国度》中提到的“算盘打出原子弹”的故事。实际上,这是一个典型的分布式并发计算的场景。Tensorflow也提供了分布式训练的能力。
Tensorflow的分布式训练的控制平面是基于grpc的。
如图,右边的机器(worker)没有GPU,而左边的机器(ps)有GPU。在Tensorflow中可以指定将数据传给worker来计算。
分布式训练的流程如下图:
图中,各个GPU各自拉取训练样本和参数进行训练,计算后更新参数。我们发现,这一计算过程中涉及到大量的数据通信:
在自动驾驶等训练场景,集群中每天的数据通信量可达PB之巨。
NVidia为了保障分布式训练场景下,海量数据的搬运,也设计了一套IO加速体系。请看下期。