深度学习火了那么多年,到底怎么搞?使用Numpy快速入门
人工智能越来越火,甚至成了日常生活无处不在的要素。人工智能是什么?深度学习、机器学习又与人工智能有什么关系?作为开发者如何进入人工智能领域?
近期我们将连载一个深度学习专题,由百度深度学习技术平台部主任架构师毕然分享,让你快速入门深度学习,参与到人工智能浪潮中。
从本专题中,你将学习到:
- 深度学习基础知识
- Numpy实现神经网络构建和梯度下降算法
- 计算机视觉领域主要方向的原理、实践
- 自然语言处理领域主要方向的原理、实践
- 个性化推荐算法的原理、实践
本文是专题第一篇,会涉及三个知识点:
- 人工智能、机器学习、深度学习三者的关系,并简要介绍了深度学习的发展历史以及未来趋势。
- 介绍构建深度模型的五个步骤,并使用Numpy实现神经网络。
- 原理介绍和代码实践并行,详细介绍了使用Numpy实现梯度下降算法。
深度学习介绍
对于深度学习初学者来说,容易遇到三个入门级问题:
- 人工智能、机器学习、深度学习三者之间关系是什么?
- 一般的机器学习方法是什么?
- 为什么那么多人看好深度学习,其未来的发展趋势是什么?
首先对第一个问题,以人工智能、机器学习、深度学习三者的关系开始。三者覆盖的技术范畴是逐层递减的,人工智能是最宽泛的概念,机器学习则是实现人工智能的一种方式,也是目前较有效的方式。
深度学习是机器学习算法中最热的一个分支,在近些年取得了显著的进展,并代替了多数传统机器学习算法。所以,三者的关系可用下图表示,人工智能 > 机器学习 > 深度学习。
图1:人工智能、机器学习和深度学习三者之间的概念范围
其次,对于第二个问题,一般的机器学习方法是什么?
举例类比,机器如一个机械的学生一样,只能通过尝试答对(最小化损失)大量的习题(已知样本)来学习知识(模型参数w),期望用学习到的知识w组成完整的模型,能回答不知道答案的考试题(未知样本)。
最小化损失是模型的优化目标,实现损失最小化的方法称为优化算法,也称为寻解算法(找到使得损失函数最小的参数解)。参数和输入X组成公式的基本结构称为假设。
在中学期间,倾斜滑动法计算重力加速度时,基于对物体重量和作用力数据的观测,我们提出的是线性假设,即作用力和加速度是线性关系。牛顿第二定律的验证过程也是机器学习的参数确定过程。由此可见,模型假设,评价函数(损失/优化目标)和优化算法是构成一个模型的三个部分。
图2:学习确定参数的方法
关于第三个问题。在深度学习框架出现之前,机器学习工程师处于手工业作坊生产的时代。为了完成建模,工程师需要储备大量数学知识,并为特征工程工作积累大量行业知识。每个模型是极其个性化的,建模者如同手工业者一样,将自己的积累形成模型的“个性化签名”。
图3:深度学习有悠久的发展历史,但在2010年后才逐渐成熟。
而今,“深度学习工程师”进入了工业化大生产时代。只要掌握深度学习必要但少量的理论知识,掌握Python编程即可以在深度学习框架实现极其有效的模型,甚至与该领域最领先的实现模型不相上下。建模这个被“老科学家”们长期把持的建模领域面临着颠覆,也是新入行者的机遇。
用Python搭建神经网络
实践出真知,理论知识说得天花乱坠也不如多写几行代码,接下来将介绍使用Numpy构建神经网络、实现梯度下降的具体方法。本次实验实现波士顿房价预测的回归模型。
应用于不同场景的深度学习模型具备一定的通用性,均分为五个步骤来完成模型的构建和训练,使用Numpy实现神经网络也不外乎如此,步骤如下:
- 数据处理:从本地文件或网络地址读取数据,并做预处理操作,如校验数据的正确性等。
- 模型设计:完成网络结构的设计(模型要素1),相当于模型的假设空间,即模型能够表达的关系集合。
- 训练配置:设定模型采用的寻解算法(模型要素2),即优化器,并指定计算资源。
- 训练过程:循环调用训练过程,每轮均包括前向计算 、损失函数(优化目标,模型要素3)和后向传播这三个步骤。
- 保存模型:将训练好的模型保存,以备预测时调用。
下面使用Python编写预测波士顿房价的模型,一样遵循这样的五个步骤。正是由于这个建模和训练的过程存在通用性,即不同的模型仅仅在模型三要素上不同,而五个步骤中的其它部分保持一致,深度学习框架才有用武之地。
数据处理与读取
首先进行数据处理,完成数据集划分、数据归一化,以及构建数据读取生成器。代码如下:
- def load_data():
- # 从文件导入数据
- datafile = './work/housing.data'
- data = np.fromfile(datafile, sep=' ')
- # 每条数据包括14项,其中前面13项是影响因素,第14项是相应的房屋价格中位数
- feature_names = [ 'CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', \
- 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV' ]
- feature_num = len(feature_names)
- # 将原始数据进行Reshape,变成[N, 14]这样的形状
- datadata = data.reshape([data.shape[0] // feature_num, feature_num])
- # 将原数据集拆分成训练集和测试集
- # 这里使用80%的数据做训练,20%的数据做测试
- # 测试集和训练集必须是没有交集的
- ratio = 0.8
- offset = int(data.shape[0] * ratio)
- training_data = data[:offset]
- # 计算train数据集的最大值,最小值,平均值
- maximums, minimums, avgs = training_data.max(axis=0), training_data.min(axis=0), \
- training_data.sum(axis=0) / training_data.shape[0]
- # 对数据进行归一化处理
- for i in range(feature_num):
- #print(maximums[i], minimums[i], avgs[i])
- data[:, i] = (data[:, i] - avgs[i]) / (maximums[i] - minimums[i])
- # 训练集和测试集的划分比例
- training_data = data[:offset]
- test_data = data[offset:]
- return training_data, test_data
构建神经网络
将波士顿房价预测输出的过程以“类和对象”的方式来描述,实现的方案如下所示。类成员变量有参数 w 和 b,并写了一个forward函数(代表“前向计算”)完成上述从特征和参数到输出预测值的计算过程。
- class Network(object):
- def __init__(self, num_of_weights):
- # 随机产生w的初始值
- # 为了保持程序每次运行结果的一致性,
- # 此处设置固定的随机数种子
- np.random.seed(0)
- self.w = np.random.randn(num_of_weights, 1)
- self.b = 0.
- def forward(self, x):
- z = np.dot(x, self.w) + self.b
目前已经实现了房价预测模型的前向过程,但是如何知道预测的结果呢,假设预测值为z而真是房价为y,这时我们需要有某种指标来衡量预测值z跟真实值y之间的差距。
对于回归问题,最常采用的衡量方法是使用均方误差作为评价模型好坏的指标,具体定义如下:
上式中的Loss(简记为: L)通常也被称作损失函数,它是衡量模型好坏的指标,在回归问题中均方误差是一种比较常见的形式。
由于实现的房价预测模型的权重是随机初始化的,这个权重参数处在模型极小值的概率几乎为0,我们需要使用梯度下降算法不断更新权重,直到该权重处于模型的极小值或最小值附近。
Numpy实现梯度下降算法
前文已提到,构建机器学习模型的首要是从一个假设空间,构建算法,去达到这个假设空间的最优值。以下图为例,
图4:梯度下降方向示意图
从随机初始化的点达到坡底(最优值)的过程,特别类似于一位想从山峰走到坡谷的盲人,他看不见坡谷在哪(无法逆向求解出Loss导数为0时的参数值),但可以伸脚探索身边的坡度(当前点的导数值,也称为梯度)。
那么,求解Loss函数最小值可以“从当前的参数取值,一步步的按照下坡的方向下降,直到走到最低点”实现。
现在我们要找出一组的值,使得损失函数最小,实现梯度下降法的方案如下:
上面我们讲过了损失函数的计算方法,公式定义损失函数如下:
根据公式,可以计算出L对w和b的偏导数
从导数的计算过程可以看出,因子被消掉了,这是因为二次函数求导的时候会产生因子,这也是我们将损失函数改写的原因
这里我们感兴趣的是和,
则可以在Network类中定义如下的梯度计算函数。
梯度计算公式
借助于Numpy里面的矩阵操作,我们可以直接对所有 一次性的计算出13个参数所对应的梯度来。
公式看不懂没关系。且看下述代码如何实现梯度计算,网络训练和参数更新。
- def gradient(self, x, y):
- z = self.forward(x)
- gradient_w = (z-y)*x
- gradient_w = np.mean(gradient_w, axis=0)
- gradient_wgradient_w = gradient_w[:, np.newaxis]
- gradient_b = (z - y)
- gradient_b = np.mean(gradient_b)
- return gradient_w, gradient_b
- def update(self, graident_w5, gradient_w9, eta=0.01):
- net.w[5] = net.w[5] - eta * gradient_w5
- net.w[9] = net.w[9] - eta * gradient_w9
- def train(self, x, y, iterations=100, eta=0.01):
- points = []
- losses = []
- for i in range(iterations):
- points.append([net.w[5][0], net.w[9][0]])
- z = self.forward(x)
- L = self.loss(z, y)
- gradient_w, gradient_b = self.gradient(x, y)
- gradient_wgradient_w5 = gradient_w[5][0]
- gradient_wgradient_w9 = gradient_w[9][0]
- self.update(gradient_w5, gradient_w9, eta)
- losses.append(L)
- if i % 50 == 0:
- print('iter {}, point {}, loss {}'.format(i, [net.w[5][0], net.w[9][0]], L))
- return points, losses
运行代码后,从下面这个图里可以清晰的看到损失函数的下降过程。
图5:损失函数下降过程
总结一下,本文以机器学习深度学习概述开篇,讲解了深度学习的基础知识,通过使用Numpy实现房价预测模型,详细讲解了构建深度学习模型的五个步骤,以及梯度下降的基本原理、如何使用Numpy实现梯度下降等内容,希望对你入门深度学习有帮助。


更多资讯推荐
- MIT提出Liquid机器学习系统,可像液体一样适应动态变化
-
麻省理工学院(MIT)的研究者开发出了一种新型的神经网络,其不仅能在训练阶段学习,而且还能持续不断地适应。
机器之心 · 2021-02-21 15:47:47
- 规划智慧城市时,别忘了无障碍通行
-
要想成为一个智慧城市甚至一个智慧世界,虽然可能需要时间和有针对性的规划,但我们必须以人为本。
蒙光伟 · 2021-02-21 10:26:41
- 2021关于人工智能的五大趋势
-
数字化变革,比过去10年更多,这主要是由于远程工作的规模,以及企业迅速部署了必要的技术,尤其是与网络安全相关的技术。那,2021关于人工智能的五大趋势会是如何的呢?
Lichu · 2021-02-21 10:21:01
- 使数据中心更智能:人工智能如何发挥作用?
-
随着数据成为维持几乎所有业务运营以获取洞察力和业务成果的先决条件,数据中心正处于这种数字化转型的关键。
Cassie · 2021-02-21 10:14:59
- IBM拟出售Watson Health后,AI医疗还能不能碰
-
医疗服务仍然是一块商业上尚未被完全发掘的市场,看病难/看病贵、医疗资源紧缺、医疗资源不平均等痛点问题长期存在,对应的市场空间理应是巨大的。而Watson Health作为IBM曾寄予厚望的业务方向,为何要在此时萌生退意?它的故事给业界带来哪些启发?眼下的AI医疗市场,究竟是一副什么样的局面呢?
物联传媒 · 2021-02-21 08:41:16
- 抛弃归一化,深度学习模型准确率却达到了前所未有的水平
-
我们知道,在传递给机器学习模型的数据中,我们需要对数据进行归一化(normalization)处理。
机器之心 · 2021-02-20 21:09:12
- 华人博士生首次尝试用两个Transformer构建一个GAN
-
最近,CV 研究者对 transformer 产生了极大的兴趣并取得了不少突破。这表明,transformer 有可能成为计算机视觉任务(如分类、检测和分割)的强大通用模型。
Yifan Jiang · 2021-02-20 21:04:53
- 无监督训练用堆叠自编码器是否落伍?ML博士对比了8个自编码器
-
柏林工业大学深度学习方向博士生 Tilman Krokotsch 在多项任务中对比了 8 种自编码器的性能。
Tilman Krokotsch · 2021-02-20 20:57:16