HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

与 DeepLearning 的初次接触(上)

  • 2019-09-27
  • 本文字数:7929 字

    阅读完需:约 26 分钟

与 DeepLearning 的初次接触(上)

随着人工智能近十年来的飞速发展,机器学习、深度学习已从学术研究逐步落实到工业界,特别是近几年机器学习框架,如 TensorFlow、Pytorch、CNTK、Keras 等层出不穷,框架设计越来越面向开发者,特别是 TensorFlow.js 的发布、V8 引擎更高性能新版本的发布等等信息,这些好像在告诉我,将深度学习广泛应用到端已然不远了。

为了不被类似 Alpha 狗等 AI 打败,作为一名程序开发者,学习和了解一些机器学习的知识、最新动态信息还是有必要的,而深度学习作为机器学习的一部分,在工业界已经发挥了重要的作用,所以今天就由浅入深,从理论知识到实战编程,逐步探究人工神经网络为何物。

阅读提示

以下内容面向深度学习初学者,需要具备以下基本素质:

①有任何编程语言的编程经验

②对几何代数相关数学知识有基本理解

③对 TensorFlow、Keras 有所了解(不了解也不会有太大影响)

④对 Jupyter Notebook 有所了解(不了解也不会有太大影响)

内容纲要

以下内容分为四个章节,可能需要 30 分钟阅读时间

第一章节——介绍神经网络重要概念和数学推导

第二章节——实战编写逻辑回归模型

第三章节——使用 TensorFlow 实现浅层神经网络

第四章节——使用 Keras 实现深度神经网络

实战编程内容均通过 Jupyter Notebook 承载。

第一章理清神经网络的基础以及实现步骤

感知机

感知器(英语:Perceptron)是 Frank Rosenblatt 在 1957 年就职于康奈尔航空实验室(Cornell Aeronautical Laboratory)时所发明的一种人工神经网络。它可以被视为一种最简单形式的前馈神经网络,是一种二元线性分类器。


Frank Rosenblatt 给出了相应的感知机学习算法,常用的有感知机学习、最小二乘法和梯度下降法。譬如,感知机利用梯度下降法对损失函数进行极小化,求出可将训练数据进行线性划分的分离超平面,从而求得感知机模型。


**生物学-神经细胞**


!



(神经细胞结构示意图)


感知机是生物神经细胞的简单抽象。神经细胞结构大致可分为:树突、突触、细胞体及轴突。单个神经细胞可被视为一种只有两种状态的机器——激动时为‘是’,而未激动时为‘否’。神经细胞的状态取决于从其它的神经细胞收到的输入信号量,及突触的强度(抑制或加强)。当信号量总和超过了某个阈值时,细胞体就会激动,产生电脉冲。电脉冲沿着轴突并通过突触传递到其它神经元。为了模拟神经细胞行为,与之对应的感知机基础概念被提出,如权量(突触)、偏置(阈值)及激活函数(细胞体)。


**人工神经元**


!



(神经元结构示意图)


在人工神经网络领域中,感知机也被指为单层的人工神经网络,以区别于较复杂的多层感知机(Multilayer Perceptron)。作为一种线性分类器,(单层)感知机可说是最简单的前向人工神经网络形式。尽管结构简单,感知机能够学习并解决相当复杂的问题。感知机主要的本质缺陷是它不能处理线性不可分问题。

(注:以上内容摘自维基百科)


单层感知机的适用和缺陷


适合解决线性问题,如下图



无法解决线性不可分,如常见的 XOR 异或问题,如下图


二分类

目前工业界最能产生价值的是机器学习中的监督学习, 场景有推荐系统,反欺诈系统等等。其中二分类算法应用的尤其之多。



例如上面的图像识别场景, 我们希望判断图片中是否有猫,于是我们为模型输入一张图片,得出一个预测值 y。 y 的取值为 1 或者 0. 0 代表是,1 代表否。

逻辑回归模型

逻辑回归是一个用于二分类(binary classification)的算法。



逻辑回归的 Hypothesis Function(假设函数)



sigmoid 函数



逻辑回归的输出函数



激活函数


也叫激励函数,是为了能够给神经网络加入一些非线性因素,使得神经网络可以更好地解决较为复杂的问题。


常见的激活函数


Sigmoid 函数


tanh 函数


ReLU 函数



损失函数(Lost Function)



代价函数(Cost Function)


为了训练逻辑回归模型的参数参数𝑤和参数𝑏,我们需要一个代价函数,通过训练代价函数来得到参数𝑤和参数𝑏。


代价函数也叫做成本函数,也有人称其为全部损失函数。


损失函数是在单个训练样本中定义的,它衡量的是算法在单个训练样本中表现如何,为了衡量算法在全部训练样本上的表现如何,我们需要定义一个算法的代价函数。


算法的代价函数是对个 m 样本的损失函数求和,然后除以 m:



损失函数只适用于像这样的单个训练样本,而代价函数是参数的总代价,所以在训练逻辑回归模型时候,我们需要找到合适的和,来让代价函数 的总代价降到最低。


代价函数的解释



由上述推论可得出这两个条件概率公式:



以下类似手写截图均来自吴恩达老师的深度学习课程


可将上述公式,合并成如下公式:



解释合并过程




推导到 m 个训练样本的整体训练的代价函数


计算图

计算图是什么


一个神经网络的计算,都是按照前向或反向传播过程组织的。



首先我们计算出一个新的网络的输出(前向过程),紧接着进行一个反向传输操作。后者我们用来计算出对应的梯度或导数。


计算图解释了为什么我们用这种方式组织这些计算过程。


举例说明



概括一下:计算图组织计算的形式是用蓝色箭头从左到右的计算


使用计算图求导数


进行反向红色箭头(也就是从右到左)的导数计算



在反向传播算法中的术语,我们看到,如果你想计算最后输出变量的导数,使用你最关心的变量对𝑣的导数,那么我们就做完了一步反向传播。


当计算所有这些导数时,最有效率的办法是从右到左计算,跟着这个红色箭头走。


所以这个计算流程图,就是正向或者说从左到右的计算来计算成本函数 J(你可能需要优化的函数)。然后反向从右到左是计算导数。

梯度下降

梯度下降法 (Gradient Descent)


梯度下降法可以做什么?


在你测试集上,通过最小化代价函数(成本函数)𝐽(𝑤, 𝑏)来训练的参数𝑤和𝑏



梯度下降法的形象化说明



在这个图中,横轴表示你的空间参数𝑤和𝑏,在实践中,𝑤可以是更高的维度,但是为了 更好地绘图,我们定义𝑤和𝑏,都是单一实数,代价函数(成本函数)𝐽(𝑤, 𝑏)是在水平轴𝑤和 𝑏上的曲面,因此曲面的高度就是𝐽(𝑤, 𝑏)在某一点的函数值。我们所做的就是找到使得代价 函数(成本函数)𝐽(𝑤, 𝑏)函数值是最小值,对应的参数𝑤和𝑏。


以如图的小红点的坐标来初始化参数𝑤和𝑏。



选出最陡的下坡方向,并走一步,且不断地迭代下去。


朝最陡的下坡方向走一步,如图,走到了如图中第二个小红点处。



可能停在这里也有可能继续朝最陡的下坡方向再走一步,如图,经过两次迭代走到 第三个小红点处。



直到走到全局最优解或者接近全局最优解的地方。



通过以上的三个步骤我们可以找到全局最优解,也就是代价函数(成本函数)𝐽(𝑤, 𝑏)这个凸函数的最小值点。


逻辑回归的梯度下降



反向传播计算 𝑤 和 𝑏 变化对代价函数 𝐿 的影响



单个样本的梯度下降算法



网络向量化


我们已经了解了单个训练样本的损失函数,当使用编程进行计算多个训练样本的代价函数时,一般都会想到使用 loop 循环来计算。


但是在数学科学领域,训练一个模型可能需要非常大量的训练样本, 即大数据集,使用 loop 循环遍历的方式是十分低效的。


线性代数的知识起到了作用,我们可以通过将循环遍历的样本数据,进行向量化,更直接的、更高效的计算,提高代码速度,减少等待时间,达到我们的期望。


注意:虽然有时写循环(loop)是不可避免的,但是我们可以使用比如 numpy 的内置函数或者其他办法去计算。



神经网络实现步骤


在深度学习中,我们一般都会使用第三方框架,如 TensorFlow, Keras,训练过程对我们来说是不可见的。


上面讲了很多的函数、以及其概念、作用,这些神经网络的”组件“,或者说,”组成部分“,如何串联起来呢?以及为什么一开始就会提到 ”前向传播“ 和 ”后向传播“ 这两个概念?


在一个简单神经网络的实现中,简化分为几步:


1、引入外部包


2、加载数据集


3、定义计算图


4、初始化参数


5、一次迭代的前向传播:执行计算图,一层层计算,直到计算到输出层,得到预估值、准确率、损失函数


6、一次迭代的反向传播:对上次得到损失函数求导,使用优化函数(梯度下降算法)从右向左对神经网络的每一层计算调参,直到计算到第一个隐含层,得到优化更新的参数


7、重复(5)(6)为一个迭代,记录多个迭代的信息,训练完毕的模型的最终损失和准确率。


8、使用(7)中得到的训练过程数据,绘制训练集、测试集关于迭代次数与损失的关系曲线图以及迭代次数与准确率关系的曲线图,进行分析,以调整超参数。

第二章逻辑回归(Logistic Regression)实现猫咪识别器

导入所需的 package


import numpy as npimport matplotlib.pyplot as pltimport h5pyfrom PIL import Imagefrom loadH5File import load_data
%matplotlib inline
复制代码


加载数据集 (cat / non-cat)


train_set_x, train_set_y, test_set_x, test_set_y, classes = load_data()
复制代码


train_x (209, 64, 64, 3) test_x (50, 64, 64, 3)train_y (1, 209) test_y (1, 50)
复制代码

查阅训练集中的一张图片

一张正确分类的图片


index = 7plt.imshow(train_set_x[index])print ("y = " + str(train_set_y[:,index]) + ", it's a '" + classes[np.squeeze(train_set_y[:,index])].decode("utf-8") +  "' picture.")
复制代码


y = [1], it's a 'cat' picture.
复制代码



一张错误分类的图片


index = 10plt.imshow(train_set_x[index])print ("y = " + str(train_set_y[:,index]) + ", it's a '" + classes[np.squeeze(train_set_y[:,index])].decode("utf-8") +  "' picture.")
复制代码


y = [0], it's a 'non-cat' picture.png
复制代码


猫咪图片数据处理过程示意


实现输入数据扁平变形和标准化(也叫归一化)


将训练集和测试集中的 x 维度切分为(num_px * num_px * 3, m)的形式


reshape 目的:实现矩阵乘法计算


  • x 维度切分为(num_px * num_px * 3, m)的形式。

  • y 维度切分为(1, m)的形式。


标准化目的:预处理的数据被限定在一定的范围内(比如[0,1]或者[-1,1]),从而消除奇异样本数据导致的不良影响。


num_px = train_set_x.shape[1]m_train = train_set_x.shape[0]m_test = test_set_x.shape[0]
# 重塑输入数据train_x_flatten = train_set_x.reshape(train_set_x.shape[0], -1).Ttest_x_flatten = test_set_x.reshape(test_set_x.shape[0], -1).T
print('train_x', train_x_flatten.shape, 'test_x', test_x_flatten.shape) print('train_y', train_set_y.shape, 'test_y', test_set_y.shape)
# 标准化输入数据train_set_x = train_x_flatten/255test_set_x = test_x_flatten/255
复制代码


train_x (12288, 209) test_x (12288, 50)train_y (1, 209) test_y (1, 50)
复制代码


实现激活函数



def sigmoid(z):    '''    计算 z 的非线性输出值
Arguments: z -- 一个标量或者一个 numpy array
Return: s -- sigmoid(z) ''' s = 1 / (1 + np.exp(-z))
return s
复制代码

实现初始化参数函数

如图小红点的坐标来初始化参数𝑤和𝑏。



def initialize_with_zeros(dim):    """    将 w 构造为一个 shape 为 (dim, 1) 的零值向量,将 b 设置为 0
Argument: dim -- 行向量 w 的大小
Returns: w -- 初始化后的行向量, shape 为 (dim, 1) b -- 初始化后的标量 (表示偏差) """
w = np.zeros(shape=(dim, 1)) b = 0
assert(w.shape == (dim, 1)) assert(isinstance(b, float) or isinstance(b, int))
return w, b
复制代码


实现代价函数(前向传播)和梯度下降函数(反向传播)


前向传播



反向传播



def propagate(w, b, X, Y):    '''    实现前向传播和反向传播
Arguments: w -- 权重, 一个行向量 (num_px * num_px * 3, 1) b -- 偏差, 一个标量 X -- 标准化后的 X 矩阵 (num_px * num_px * 3, number of examples)
Return: cost -- 逻辑回归的成本函数(负值) dw -- w 的梯度下降,shape 同 w db -- b 的梯度下降,shape 同 b
''' m = X.shape[1]
# 前向传播 A = sigmoid(np.dot(w.T, X) + b) cost = -1 / m * np.sum(Y * np.log(A) + (1-Y) * np.log(1-A))
# 反向传播 dw = 1 / m * np.dot(X, (A-Y).T) db = 1 / m * np.sum(A-Y)
assert(dw.shape == w.shape) assert(db.dtype == float) cost = np.squeeze(cost) assert(cost.shape == ())
grads = {"dw": dw, "db": db}
return grads, cost
复制代码

实现调参函数

以梯度下降算法不断更新参数,使其达到更优。



def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):    '''    运行梯度下降算法,优化调整 w, b 参数
Arguments: w -- 权重, 一个行向量 (num_px * num_px * 3, 1) b -- 偏差, 一个标量 X -- 标准化后的 X 矩阵,shape 为 (num_px * num_px * 3, number of examples) Y -- 一个由 0, 1 组成(其中 0 表示 non-cat, 1 表示 cat)的列向量, shape 为 (1, number of examples) num_iterations -- 迭代次数/优化更新次数 learning_rate -- 梯度下降的学习率/更新步长 print_cost -- 是否打印损失,默认不打印
Returns: params -- 一个包含了权重 w 和 偏差 b 的字典 grads -- 一个包含了权重 w 和 偏差 b 的梯度的字典 costs -- 一个保留了所有更新计算过的损失值的列表,用于绘制学习曲线 '''
costs = []
for i in range(num_iterations):
# 调用 propagate 函数计算 w, b 的梯度以及损失 grads, cost = propagate(w, b, X, Y)
dw = grads["dw"] db = grads["db"]
# 更新 w, b,优化调整参数 w = w - learning_rate * dw b = b - learning_rate * db
# 保存当次更新的损失 if i % 100 == 0: costs.append(cost)
# 每训练100次,打印一次损失 if print_cost and i % 100 == 0: print("Cost after iteration %i: %f" % (i, cost))
params = {"w": w, "b": b}
grads = {"dw": dw, "db": db}
return params, grads, costs
复制代码


2019-09-27 13:041026

评论

发布
暂无评论
发现更多内容

通过python封装1688商品跨境属性API接口文档

tbapi

Python爬虫 1688API 1688商品跨境属性接口

IDC 23Q3 数据发布 XSKY 对象存储软件市场份额继续蝉联第一!

XSKY星辰天合

相比于 Jira,极狐GitLab 的敏捷项目管理是怎样的?

极狐GitLab

TDengine 创始人陶建辉在汽车 CIO&CDO 论坛发表演讲,助力车企数字化转型

TDengine

tdengine 时序数据库

LED透明屏在舞台中的应用

Dylan

技术 设计 体验 LED显示屏 led显示屏厂家

左耳听风 - 高效沟通「读书打卡 day 09」

Java 工程师蔡姬

读书笔记 程序员 个人成长 沟通 职业发展

使用Docker安装MongoDB数据库

emanjusaka

mongodb Docker 迁移

到店商详架构变迁

京东科技开发者

IT行业,抢滩大模型

脑极体

AI IT

发现一款提高工作效率的利器——ONLYOFFICE办公软件

袁袁袁袁满

人工智能 Office 自动化办公

如何在 Ubuntu / Raspbian 上安装 PostgreSQL

HoneyMoose

vivo智能活动中台-悟空系统建设之路

vivo互联网技术

低代码 活动中台 AIGC技术探索

Pod/Node CPU 故障注入

腾讯云混沌演练平台

k8s 混沌工程

2024年上海等保测评机构有几家?分别叫做什么名字?

行云管家

网络安全 等保测评 等保测评机构 上海

申请开启|成为亚马逊云科技 Community Builder,共建云端社区!

亚马逊云科技 (Amazon Web Services)

数据库

淘宝商品列表数据怎么导出

tbapi

淘宝电商 淘宝商品数据接口 taobao agent system

如何做标准化?| 京东云技术团队

京东科技开发者

高效云运维工具就是行云管家!不用加班神器!

行云管家

云计算 云服务 云运维 云管家

C-Shopping基于Next.js,开源电商平台全新亮相

Geek_9da61c

nodejs nextjs Redux Tailwind reactjs

【深入挖掘Java技术】「源码原理体系」盲点问题解析之HashMap工作原理全揭秘(下)

洛神灬殇

Java hashmap HashMap底层原理 2024年第十四篇文章

流式传输 VR 和 AR 内容——实时云渲染服务

3DCAT实时渲染

实时渲染 实时云渲染 云流化

电商通讯服务

cts喜友科技

通信 通讯

修复uni-simple-router@2.0.7版本query参数为null时的bug

达摩

uni-app Vue uni-simple-router

2024-01-17:lc的30. 串联所有单词的子串

福大大架构师每日一题

福大大架构师每日一题

行云部署前端架构解析-前言 | 京东云技术团队

京东科技开发者

重磅发布!基于百度飞桨的《人工智能基础及应用》书籍正式上线

飞桨PaddlePaddle

人工智能 机器学习 深度学习 百度飞桨

云图说丨安全云脑:开箱即用的安全运营体验

华为云开发者联盟

安全 华为云 华为云开发者联盟 华为云云图说 安全云脑

IPQ6010: Leading a new chapter in smart home and IoT fields

wallysSK

了解一下Java21的VirtualThread

袁世超

虚拟线程 Java21

与 DeepLearning 的初次接触(上)_AI&大模型_江伯_InfoQ精选文章