【一】零基础入门深度学习:用numpy实现神经网络训练

标签: Python  深度学习  python

本课程是零基础入门深度学习课程,主要面向没有深度学习技术基础或者基础薄弱的同学,帮助大家实现从0到1的跨越。从本课程中,你将学习到:

  1. 深度学习基础知识

  2. numpy实现神经网络构建和梯度下降算法

  3. 计算机视觉领域主要方向的原理、实践

  4. 自然语言处理领域主要方向的原理、实践

  5. 个性化推荐算法的原理、实践

1.深度学习基础知识

对于深度学习初学者来说,容易遇到三个入门级问题:

  1. 人工智能、机器学习、深度学习三者之间关系是什么?

  2. 一般的机器学习方法是什么?

  3. 为什么那么多人看好深度学习,其未来的发展趋势是什么?

本次课程在第一讲中则优先解决这些问题。首先对第一个问题,以人工智能、机器学习、深度学习三者的关系开始。三者覆盖的技术范畴是逐层递减的,人工智能是最宽泛的概念,机器学习则是实现人工智能的一种方式,也是目前较有效的方式。深度学习是机器学习算法中最热的一个分支,在近些年取得了显著的进展,并代替了多数传统机器学习算法。所以,三者的关系可用下图表示,人工智能 > 机器学习 > 深度学习。

其次,对于第二个问题,一般的机器学习方法是什么?

课程以“机器从牛顿第二定律实验中学习知识”为案例,生动的讲解了机器学习(监督学习)到底是怎样的一种技术方法。

举例类比,机器如一个机械的学生一样,只能通过尝试答对(最小化损失)大量的习题(已知样本)来学习知识(模型参数w),期望用学习到的知识w组成完整的模型H(\theta ,X),能回答不知道答案的考试题(未知样本)。最小化损失是模型的优化目标,实现损失最小化的方法称为优化算法,也称为寻解算法(找到使得损失函数最小的参数解)。参数\theta和输入X组成公式的基本结构称为假设。

在中学期间,倾斜滑动法计算重力加速度时,基于对物体重量和作用力数据的观测,我们提出的是线性假设,即作用力和加速度是线性关系。牛顿第二定律的验证过程也是机器学习的参数确定过程。由此可见,模型假设,评价函数(损失/优化目标)和优化算法是构成一个模型的三个部分。

最后以讲解历史课的形式,对深度学习的历史做了简单的介绍,

在深度学习框架出现之前,机器学习工程师处于手工业作坊生产的时代。为了完成建模,工程师需要储备大量数学知识,并为特征工程工作积累大量行业知识。每个模型是极其个性化的,建模者如同手工业者一样,将自己的积累形成模型的“个性化签名”。而今,“深度学习工程师”进入了工业化大生产时代。只要掌握深度学习必要但少量的理论知识,掌握Python编程即可以在深度学习框架实现极其有效的模型,甚至与该领域最领先的实现模型不相上下。建模这个被“老科学家”们长期把持的建模领域面临着颠覆,也是新入行者的机遇。

2.numpy实现神经网络构建和梯度下降算法

实践出真知,理论知识说的天花乱坠也不如多写几行代码。了解到大多数用户即使使用一些深度学习框架搭建出了一个神经网络,但是对神经网络和梯度下降算法理解并不深刻。针对学员的诉求,本次课程增加了使用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函数(代表“前向计算”)完成上述从特征和参数到输出预测值的计算过程。

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=(y-z)^2

上式中的Loss(简记为: L) 通常也被称作损失函数,它是衡量模型好坏的指标,在回归问题中均方误差是一种比较常见的形式。

由于实现的房价预测模型的权重是随机初始化的,这个权重参数处在模型极小值的概率几乎为0,我们需要使用梯度下降算法不断更新权重,直到该权重处于模型的极小值或最小值附近。

numpy实现梯度下降算法

当使用深度学习框架实现的时候,这部分是不需要我们手动实现的。但是不代表我们不需要去了解它,本次课程以瞎子下坡的方式为例,讲解了梯度下降的基本原理和使用numpy实现梯度下降。

前文已提到,构建机器学习模型的首要是从一个假设空间,构建算法,去达到这个假设空间的最优值。以下图为例,

从随机初始化的点达到坡底(最优值)的过程,特别类似于一位想从山峰走到坡谷的盲人,他看不见坡谷在哪(无法逆向求解出Loss导数为0时的参数值),但可以伸脚探索身边的坡度(当前点的导数值,也称为梯度)。那么,求解Loss函数最小值可以“从当前的参数取值,一步步的按照下坡的方向下降,直到走到最低点”实现。

现在我们要找出一组的值[w_{5},w_{9}],使得损失函数最小,实现梯度下降法的方案如下:

  • 随机的选一组初始值,例如[w_{5},w_{9}]=[-100.0,-100.0]: 

  • 选取下一个点[w_{5}^{'},w_{9}^{'}]使得 L(w_{5}^{'},w_{9}^{'})<L(w_{5},w_{9})

  • 重复上面的步骤2,直到损失函数几乎不再下降

上面我们讲过了损失函数的计算方法,公式定义损失函数如下:

其中z^{(i)}是网络对第个i样本的预测值

根据公式,可以计算出Lwb的偏导数

从导数的计算过程可以看出,因子\frac{1}{2}被消掉了,这是因为二次函数求导的时候会产生因子2,这也是我们将损失函数改写的原因.

这里我们感兴趣的是w_{5}w_{9}

则可以在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_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_w5 = gradient_w[5][0]
        gradient_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

运行代码后,从下面这个图里可以清晰的看到损失函数的下降过程。

以机器学习深度学习概述开篇,讲解了深度学习的基础知识,通过使用numpy实现房价预测模型,详细讲解了构建深度学习模型的五个步骤,以及梯度下降的基本原理、如何使用numpy实现梯度下降等内容。

3.计算机视觉领域主要方向的原理、实践

 

4.自然语言处理领域主要方向的原理、实践

 

5.个性化推荐算法的原理、实践

版权声明:本文为qq_41823684原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41823684/article/details/106556381

智能推荐

Java编程思想 第三章:操作符

Java中的操作符和c/c++中的操作符基本一致,因为我之前学习过C语言和C++,所以本章的内容大部分都已熟知,下面只做简单的介绍。 Java操作符及优先级 Java中的操作符包括算术操作符,关系操作符,逻辑操作符,位运算符、自操作运算符、移位运算符、赋值运算符和其他运算符。 算术操作符:包括加减乘除和取余(%),优先级乘除取余高于加减,都是双元运算符,其中加法(+)可以用来连接两个字符串,比如:...

JetBrains 系列开发工具,如何配置 `SCSS` `File Watcher` ,相关输出配置参数详解:webStorm phpStorm IDEA

JetBrains 系列开发工具,如何配置 SCSS File Watcher ,相关输出配置参数详解:webStorm phpStorm IDEA 前言 你目前已经了解了如何使用 SCSS 进行开发,了解了该文章的内容:『 SCSS 日常用法 』 在 JetBrains 系列开发工具中通过 FileWatcher 进行编译的 SCSS 文件都是通过 sass 这个程序进行的。『 如何添加 Fil...

C语言小函数—二进制与十六进制

测试如下 “` int main() { long int num = 15; } “`...

仿微博或微信的文章多图显示(自定义MultiImageView)

按照一般的规矩,先上张图来供大伙看看 如果大致是大伙们需要实现的功能,不烦一观 自定义MultiImageView 工具类 具体使用 app.gradle中添加依赖 implementation 'com.github.bumptech.glide:glide:4.8.0' AndroidManifest.xml中配置联网权限 <uses-permission android:name=&q...

经典进程同步和互斥问题

经典进程同步与互斥问题 前言 一、生产者-消费者问题 1.问题描述 2.问题分析 3.代码 二、读者-写者问题 1.问题描述&&分析 2.代码 三、哲学家进餐问题 1.问题描述&&分析 2.代码 四、理发师问题 1.问题描述&&分析 2.代码 前言 在多道程序设计环境中,进程同步是一个非常重要的问题,下面讨论几个经典的进程同步问题。 一、生产者-消费...

猜你喜欢

java设计模式——ThreadLocal线程单例

1、定义一个ThreadLocal线程单例,代码如下: 2、定义一个多线程类,代码如下: 3、定义一个测试类,代码如下: 4、输出结果,如下图:...

【tensorflow】线性模型实战

线性模型:y = 1.477 * x + 0.089   1. 采样数据 采样噪声eps在均值0,方差0.01的高斯分布中,而后在均匀分布U(0,1)中,区间[-10,10]进行n=100次随机采样:   2. 计算误差 循环计算每个点的预测值与真是值之间差的平方并累加,从而获得训练集上的均芳误差损失值。   3. 计算梯度   4. 梯度更新 对权重w和偏...

常见损失函数和评价指标总结(附公式&代码)

网上看到一篇很实用的帖子关于常见损失函数和评价指标,收藏下来 本文转载于https://zhuanlan.zhihu.com/p/91511706 ------------------------------------------------------------------------------------------------------------------------------...

为什么 4G/5G 的直播延时依然很高

通信技术的发展促进了视频点播和直播业务的兴起,4G 和 5G 网络技术的进步也使得流媒体技术变得越来越重要,但是网络技术并不能解决流媒体直播的高延迟问题。 本文不会介绍网络对直播业务的影响,而是会分析直播中常见的现象 — 主播和观众之间能够感觉到的明显网络延迟。除了业务上要求的延迟直播之外,有哪些因素会导致视频直播的延迟这么高呢? live-streaming  图 1 - ...

springboot 过滤器Filter vs 拦截器Interceptor 详解

1 前言       最近接触到了过滤器和拦截器,网上查了查资料,这里记录一下,这篇文章就来仔细剖析下过滤器和拦截器的区别与联系。 2 拦截器与过滤器之间的区别 从上面对拦截器与过滤器的描述来看,它俩是非常相似的,都能对客户端发来的请求进行处理,它们的区别如下: 作用域不同 过滤器依赖于servlet容器,只能在 servlet容器,web环境下使用 拦截器依赖于sp...