授课讲师 | 毕然 百度 深度学习 技术平台部主任架构师 授课时间 | 每周二、周四晚20:00-21:00 本课程是百度 官方开设的零基础入门深度学习 课程,主要面向没有深度学习 技术基础或者基础薄弱的同学,帮助大家实现从0到1的跨越。从本课程中,你将学习到: 本周为开讲第一周,百度 深度学习 技术平台部主任架构师毕然老师,利用两次课的时间,讲解了三个知识点: 人工智能 、机器学习 、深度学习 三者的关系,并简要介绍了深度学习 的发展历史以及未来趋势。介绍构建深度模型的五个步骤,并手把手教大家使用numpy实现神经网络 。 原理介绍和代码实践并行,详细介绍了使用numpy实现梯度下降 算法。 本文总结了毕然老师的讲课要点,不免疏漏一些生动的讲课案例,感兴趣的同学可从文末链接中直接观看课程。 为什么那么多人看好深度学习 ,其未来的发展趋势是什么? 本次课程在第一讲中则优先解决这些问题。首先对第一个问题,以人工智能 、机器学习 、深度学习 三者的关系开始。三者覆盖的技术范畴是逐层递减的,人工智能 是最宽泛的概念,机器学习 则是实现人工智能 的一种方式,也是目前较有效的方式。深度学习 是机器学习 算法中最热的一个分支,在近些年取得了显著的进展,并代替了多数传统机器学习 算法。所以,三者的关系可用下图表示,人工智能 > 机器学习 > 深度学习 。
图1:人工智能 、机器学习 和深度学习 三者之间的概念范围 课程以“机器从牛顿第二定律实验中学习知识”为案例,生动的讲解了机器学习 (监督学习 )到底是怎样的一种技术方法。 举例类比,机器如一个机械的学生一样,只能通过尝试答对(最小化损失)大量的习题(已知样本)来学习知识(模型参数 w),期望用学习到的知识w组成完整的模型,能回答不知道答案的考试题(未知样本)。最小化损失是模型的优化目标,实现损失最小化的方法称为优化算法,也称为寻解算法(找到使得损失函数 最小的参数 解)。参数 和输入X组成公式的基本结构称为假设。 在中学期间,倾斜滑动法计算重力加速度时,基于对物体重量和作用力数据的观测,我们提出的是线性假设,即作用力和加速度是线性关系。牛顿第二定律的验证过程也是机器学习 的参数 确定过程。由此可见,模型假设,评价函数(损失/优化目标)和优化算法是构成一个模型的三个部分。 最后以讲解历史课的形式,对深度学习 的历史做了简单的介绍,
图3:深度学习 有悠久的发展历史,但在2010年后才逐渐成熟。 在深度学习 框架出现之前,机器学习 工程师处于手工业作坊生产的时代。为了完成建模,工程师需要储备大量数学知识,并为特征工程 工作积累大量行业知识。每个模型是极其个性化的,建模者如同手工业者一样,将自己的积累形成模型的“个性化签名”。而今,“深度学习 工程师”进入了工业化大生产时代。只要掌握深度学习 必要但少量的理论知识,掌握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]这样的形状
data = 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函数(代表“前向计算”)完成上述从特征和参数 到输出预测值的计算过程。 def __init__(self, num_of_weights): self.w = np.random.randn(num_of_weights, 1) z = np.dot(x, self.w) + self.b
目前已经实现了房价预测模型的前向过程,但是如何知道预测的结果呢,假设预测值为而真是房价为,这时我们需要有某种指标来衡量预测值跟真实值之间的差距。对于回归问题,最常采用的衡量方法是使用均方误差作为评价模型好坏的指标,具体定义如下: 上式中的(简记为: ) 通常也被称作损失函数 ,它是衡量模型好坏的指标,在回归问题中均方误差是一种比较常见的形式。 由于实现的房价预测模型的权重 是随机初始化的,这个权重 参数 处在模型极小值的概率几乎为0,我们需要使用梯度下降 算法不断更新权重 ,直到该权重 处于模型的极小值或最小值附近。
当使用深度学习 框架实现的时候,这部分是不需要我们手动实现的。但是不代表我们不需要去了解它,本次课程以瞎子下坡的方式为例,讲解了梯度下降 的基本原理和使用numpy实现梯度下降 。 前文已提到,构建机器学习 模型的首要是从一个假设空间,构建算法,去达到这个假设空间的最优值。以下图为例,
从随机初始化的点达到坡底(最优值)的过程,特别类似于一位想从山峰走到坡谷的盲人,他看不见坡谷在哪(无法逆向求解出Loss导数 为0时的参数 值),但可以伸脚探索身边的坡度(当前点的导数 值,也称为梯度)。那么,求解Loss函数最小值可以“从当前的参数 取值,一步步的按照下坡的方向下降,直到走到最低点”实现。 现在我们要找出一组的值,使得损失函数 最小,实现梯度下降 法的方案如下: 借助于numpy里面的矩阵操作,我们可以直接对所有 一次性的计算出13个参数 所对应的梯度来 公式看不懂没关系,本次课程主要以理论和实践结合的方案进行。且看下述代码如何实现梯度计算,网络训练和参数 更新。 def gradient(self, x, y): gradient_w = np.mean(gradient_w, axis=0) gradient_w = gradient_w[:, np.newaxis] 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): for i in range(iterations): points.append([net.w[5][0], net.w[9][0]]) gradient_w, gradient_b = self.gradient(x, y) gradient_w5 = gradient_w[5][0] gradient_w9 = gradient_w[9][0] self.update(gradient_w5, gradient_w9, eta) print('iter {}, point {}, loss {}'.format(i, [net.w[5][0], net.w[9][0]], L))
运行代码后,从下面这个图里可以清晰的看到损失函数 的下降过程。 通过两次课程,以机器学习 深度学习 概述开篇,讲解了深度学习 的基础知识,通过使用numpy实现房价预测模型,详细讲解了构建深度学习 模型的五个步骤,以及梯度下降 的基本原理、如何使用numpy实现梯度下降 等内容,同学们也反馈收获颇多。 下周将继续讲解后续课程,感兴趣同学可以参照文末课程链接进行报名,课程免费,更有MacBook作为课程结业奖品,欢迎参加。