罗晨汛

罗晨汛

移动互联网开发者

1 什么是神经网络

1.1 神经网络的历史

1958年,计算机科学家罗森布拉特(Rosenblatt)就提出了一种具有单层网络特性的神经网络结构,称为“感知器”( perceptron)。感知器出现之后很受瞩目,大家对它的期望很高。然而好景不长 —— 一段时间后,人们发现感知器的实用性很弱。 1969年,AI的创始人之一马文·明斯基(Marvin Minsky)指出简单神经网络只能运用于线性问题的求解。这之后神经网络就逐渐被遗忘了。

直到1985年,杰弗里·辛顿(Geoffrey Hinton,深度学习“三巨头” 之一)特伦斯·谢诺夫斯基( Terrence Sejnowski)提出了一种随机神经网络模型——受限玻尔兹曼机。紧接着, RumelhartHintonWilliams提出了BP算法,即多层感知器的梯度反向传播算法。这也是神经网络的核心算法,人们以此为基础搭建起几乎现代所有的深度网络模型。

因此,可以说神经网络的理论基础在20世纪60年代出现,并在80年代几乎完全形成。 在工程界,当时神经网络也已经有了应用。杨立昆( Yann Le Cun, 深度学习“三巨头”之一)于20世纪80年代末在贝尔实验室研发出了卷积神经网络,他将其应用到手写识别和OCR,并在美国广泛应用于手写邮编、支票的读取。然而后来,另一种理论相当完善的机器学习技术支持向量机( Support Vector Machine,SVM)被发明出来,成为了业界“新宠”,神经网络再一次被遗忘了。

大约2009年,计算机最终有了足够的算力进行深度计算,神经网络开始在语音和图像识别方面战胜传统算法。杰弗里·辛顿杨立昆约书亚 ·本吉奥(Yoshua Bengio)3人联合提出深度学习的概念。这是新瓶装旧酒,名称变了,技术还是一样的技术。然而时代也已经改变,此时深度神经网络开始实证性地在工程界展示出绝对的优势。

2012年年底,基于卷积神经网络模型的Inception结构在ImageNet图片分类竞赛中获胜。此后深度学习火山爆发式发展,科技“巨头”们开始在这个领域投资:计算机视觉、语音识别、自然语言处理、棋类竞赛和机器人技术,这些应用领域的突破一个接着一个出现。

其实,从一开始就不是神经网络不行,而是原来的数据量和计算速度两方面都跟不上。在这个数据泛滥的时代,海量数据的获取不再是什么难事。可以预见,在5G时代,深度学习必然还会有更大发展的空间。

好像这个神经网络的原理和线性回归或者逻辑回归 完全相同,不就是通过不断地训练寻找最佳的参数嘛!” 咖哥答:“你说得简直太正确了!它们本来就是一回事,唯一的不同 是,神经网络的参数多、层级深,需要的数据量也多。”

感知器是神经网络的雏形,最初的神经网络也就是只有一个神经元的感知器,如下图:

ai-ann-nervecell

上图的圆圈就代表一个神经元,它可以接收输入,并根据输入提供一个输出。

Sigmiod函数,在逻辑回归中叫逻辑函数,在神经网络中则称为激活函数,用以类比人类神经系统中神经元的“激活”过程。

  • 输入空间:x,输入值的集合。
  • 输出空间:y,输出值的集合。通常,输出空间会小于输入空间。
  • 特征空间:每一个样本被称作一个实例,通常由特征向量表示,所有特征向量存在的空间称为特征空间。特征空间有时候与输入空间相同,有时候不同。因为有时候经过特征工程之后,输入空间可通过某种映射生成新的特征空间。
  • 假设空间:假设空间一般是对于学习到的模型(即函数)而言的。 模型表达了输入到输出的一种映射集合,这个集合就是假设空间。假设空间代表着模型学习过程中能够覆盖的最大范围。

2 Keras 单隐层网络的应用

  • 序贯(sequential)模型,也可以叫作顺序模型,是最常用的深度网络层和层间的架构,也就是一个层接着一个层,顺序地堆叠.
  • 密集(dense)层,是最常用的深度网络层的类型,也称为全连接层,即当前层和其下一层的所有神经元之间全有连接。

2.1 构建网络

用序贯模型构建网络
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import keras
from keras.models import Sequential
from keras.layers import Dense

# 创建了一个序贯 ANN 模型(其实就是一个Python的类)
# 在 Keras中,绝大多数的神经网络都是通过序贯模型所创建的。与之对应的还有另外一种模型,称为函数式API,可以创建更为复杂的网络结构
ann = Sequential()
# 过 add 方法,开始神经网络层的堆叠,顺序模型就是一层层堆叠
# 这里添加的 Dense, 就是我们上面介绍的“密集层网络”,表示层层之间全连接
# ----
# input_dim:输入维度,必须与特征维度相同
# units: 输出维度(也可写成 output_dim)
# activation: 激活函数
ann.add(Dense(units=12, input_dim=12, activation='relu')) # 添加输入层
ann.add(Dense(units=24, activation='relu')) # 添加隐层,此处增加了维度(神经元个数)
ann.add(Dense(units=1, activation='sigmoid')) # 添加输出层

# 显示网络模型
ann.summary()

上面模型输出如下:

序贯ANN模型输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 12) 156

dense_1 (Dense) (None, 24) 312

dense_2 (Dense) (None, 1) 25

=================================================================
Total params: 493
Trainable params: 493
Non-trainable params: 0
_________________________________________________________________

summary 方法显示了神经网络的结构,包括每个层的类型、输出张量的形状、参数数量以及整个网络的参数数量。
这个网络只有3层,493个参数(就是每个神经元的权重等)。

我们可以用代码输出神经网络的形状结构图

图片输出神经网络的形状结构
1
2
3
4
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot

SVG(model_to_dot(ann, show_shapes=True).create(prog='dot', format='svg'))

如下图:

ai-ann-sequential

2.2 编译网络

Sequential模型compile方法对整个网络进行编译时,需要指定以下几个关键参数。

  1. 优化器(optimizer):一般情况下,“adam”或者“rmsprop”都是 很好的优化器选项,但也有其他可选的优化器。等一会我们再稍微深入地说说优化器的选择。
  2. 损失函数(loss):对于二分类问题来说,基本上二元交叉熵函数 (binary_crossentropy)是固定选项;如果是用神经网络解决线性的回归问题,那么均方误差函数是合适的选择。
  3. 评估指标(metrics):这里采用预测准确率 acc(也就是accuracy的缩写,两者在代码中是等价的)作为评估网络性能的标准;而对于回归问题,平均误差函数是合适的选择。准确率,也就是正确地预测占全部数据的比重,是最为常用的分类评估指标。
编译神经网络,指定优化器,损失函数,以及评估标准
1
2
3
ann.compile(optimizer='adam',             # 优化器
loss = 'binary_crossentropy', # 损失函数
metrics = ['acc']) # 评估指标

2.3 训练网络

下面开始训练刚才编译好的神经网络。和其他传统机器学习算法一样,神经网络的拟合过程也是通过fit方法实现的。

1
2
3
4
5
# 通过history变量把训练过程中的信息保存下来,留待以后分析
history = ann.fit(X_train, y_train,# 指定训练集
epochs=30, # 指定训练轮次
batch_size=64, # 指定数据批量
validation_data=(X_test, y_test)) # 指定验证集,这里为了简化模型,直接用测试集数据进行验证

训练后,命令行会输出每次迭代的结果,最终落到最后准备率上。

训练过程中输出的信息包括每轮训练的损失值、准确率等。但是这个输出信息有30轮的数据,很冗长、看起来特别费力。我们可以将之图形化输出,以直观展示ANN训练过程。

3 分类数据不平衡

3.1 什么是不平衡问题

  • 次品问题

假设有一个手机生产厂商,每天生产手机1000部。某一天生产的手机中,出现了2个劣质品。

目前要通过机器学习来分析数据特征(如手机 的重量、形状规格等),鉴定劣质品样本。其中机器学习模型的预测结果显示合格品 999 个,劣质品1个。

从上面的例子中,我们运用之前的知识、其准确率为99.9%。因为准确率就是预测命中的数据个数/数据总数,即 999/1000。1000个样本只猜错一个,可以说是相当准的模型了。

然而从我们的目标来说,这个模型实际上是失败了。这个模型本就是为了检测劣质品而生(劣质品即标签值为1的阳性正样本),但一共有 2个劣质品,只发现了1个,有50%的正样本没有测准。

因此,模型的好与不好,是基于用什么标准衡量。对于这种正样本和负样本比例极度不平衡的样本集,我们需要引进新的评估指标。

3.2 混淆矩阵、精确率、召回率和F1分数

另一个标准是召回率,也叫查全率。你们听说过“召回”这个名词 吧,就是劣质品蒙混过了质检这关,“跑”出厂了,得召回来,销毁掉。 这和精确率是成对出现的概念。

把精确率和召回率结合起来,就得到F1分数。这是一个可以同时体现上面两个评估效果的标准,数学上定义为精确率和召回率的调和均值。它也是在评估这类样本分类数据不平衡的问题时,所着重看重的标准。

3.3 为何分类数据不平衡会带来影响

之所以分类数据不平衡会影响机器学习模型的预测结果,是因为许多模型的输出类别是基于阈值的,如逻辑回归中小于0.5的为反例,大于等于 0.5的则为正例。因此,在数据不平衡时,默认的阈值会导致模型输出倾向 于数据多的类别。

3.4 解决不平衡问题

3.4.1 特征缩放

对于神经网络而言,特征缩放(feature scaling)极为重要。神经网络不喜欢大的取值范围,因此需要将输入神经网络的数据标准化,把数据约束在较小的
区间,这样可消除离群样本对函数形状的影响。

对数据进行标准化。其步骤是:对于输入数据的每个特征(也就是输入数据矩阵中的一整列),减去特征平均值,再除以标准差,之后得到的特征平均值为0,标准差为1。

使用StandardScaler工具进行标准化
1
2
3
4
5
from sklearn.preprocessing import StandardScaler # 导入特征缩放器

sc = StandardScaler() # 特征缩放器
X_train = sc.fit_transform(X_train) # 拟合并应用于训练集
X_test = sc.transform (X_test) # 训练集结果应用于测试集

4 深度神经网络

通过正向传播和反向传播,神经网络实现了内部参数的调整。下面我们说说神经网络中的可调超参数。

4.1 可调超参数

4.2 优化器

优化器相当于是用来调解神经网络模型的“手柄”,它在前面的代码中曾经出现过。

编译神经网络, 指定优化器、损失函数, 以及评估指标
1
2
3
ann.compile(optimizer = 'adam',        # 优化器
loss = 'binary_crossentropy', # 损失函数
metrics = ['acc'])    # 评估指标

编译神经网络时的optimizer = 'adam'中的adam,就是一个优化器。

4.2.1 为什么需要优化器

神经网络中不仅存在局部最低点,还存在鞍点。因此在

4.2.2 有哪些优化器

1. 神经网络权重参数随机初始化

分类问题回归问题,是机器学习两大主要应用。

分类问题覆盖面很广泛:比如二元分类,根据考试成绩推断是否被录取、根据消费记录判断信用卡是否可以申请,以及预测某天是否将发生地震等;有多元分类,如消费群体的划分、个人信用的评级等;还有图像识别语音识别等,在本质上也是很多个类别的分类问题。

本章讲的专用于分类的机器学习算法,叫逻辑回归(logistic regression),简称Logreg

阅读全文 »

1 MVC 模式

MVC, 全名 Model View Controller, 是软件工程中的一种软件设计模式 (常用于架构层面),把软件系统分为三个基本部分:模型 (Model)视图 (View)控制器 (Controller)。分层的好处很明显,把一团软件代码分成职责分明的层次,每一层有其专注的领域层与层之间也有明确的接口,实现上可以分层实现,哪层实现的不好重构之对整体也影响不大 。具有耦合性低,重用性高、生命周期成本低等优点。

  • Model(模型): 简而言之即 数据模型模型不是数据本身(比如数据库里的数据),而是抽象的描述数据的构成和逻辑关系 。通常模型包括了数据表的各个字段(比如人的年龄和出生日期)和相互关系(单对单,单对多关系等),以及一些数据层面的业务逻辑。Web 开发框架会根据模型的定义来自动生成数据表。
  • Controller (控制器):应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据(比如增加或更新数据表)。
  • View (视图): 主要用于显示数据,用来展示用户可以看到的内容或提供用户可以输入或操作的界面。数据来源于哪里?用户输入的数据给又谁?为了降低系统的耦合程序,中间就会抽像出控制器一层做为两者的桥接。

MVC 最大的优点是实现了软件或网络应用开发过程中数据、业务逻辑和用户界面的分离,使软件开发更清晰,也是维护变得更容易。这与静态网页设计中使用 html 和 css 实现了内容和样式的分离是同一个道理。

DjangoMVT 设计模式由 Model (模型) , View (视图)Template (模板) 三部分组成,分别对应单个 app 目录下的 models.py, views.pytemplates 文件夹。它们看似与 MVC 设计模式不太一致,其实本质是相同的。MVT 模式其实是一种特殊的 MVC 模式的实现

阅读全文 »

Django 是一个开放源代码的 Web 应用框架,由 Python 写成。采用了 MTV 的框架模式,即模型 M,视图 V 和模版 T。

有趣的是,这套框架是以比利时的吉普赛爵士吉他手 Django Reinhardt 来命名的。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统) 软件,并于 2005 年 7 月在 BSD 许可证下发布。所以使用了 Django 后我们会发现,其“集成管理后台”、“模板页面”等设计思想偏向于帮助人们快速实现一个 CMS(毕竟其前身就是一个CMS,并从中抽象而得之)。

Django 的主要目的是简便、快速的开发数据库驱动的网站。它强调代码复用,多个组件可以很方便的以 “插件” 形式服务于整个框架,Django 有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包。这使得 Django 具有很强的可扩展性。它还强调快速开发和 DRY (Do Not Repeat Yourself) 原则。Django 框架的核心组件有:

  1. 用于创建模型的对象关系映射;
  2. 为最终用户设计较好的管理界面;
  3. URL 设计;
  4. 设计者友好的模板语言;
  5. 缓存系统

也因为其良好的设计与简单、快速的特点,常用于快速构造中大型内部系统。

阅读全文 »

1 And Design Pro 是什么?

And Design Pro(官网),我们一般也将之简称为 antd pro,是Ant Design 的升级版。如果你接触过Ant Design(常简称之为 antd),antd 是基于Ant Design 设计体系React UI 组件库,主要用于研发企业级中后台产品。

antd pro 则在其之上,增加了 umiJS 的扩展加成,提供了路由、国际化、权限管理等功能,从而成为一整套企业级的中后台前端解决方案,从 AntD 官网介绍可以看出:

Ant Design Pro 是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案,致力于在设计规范和基础组件的基础上,继续向上构建,提炼出典型模板/业务组件/配套设计资源,进一步提升企业级中后台产品设计研发过程中的『用户』和『设计者』的体验。随着『设计者』的不断反馈,我们将持续迭代,逐步沉淀和总结出更多设计模式和相应的代码实现,阐述中后台产品模板/组件/业务场景的最佳实践,也十分期待你的参与和共建。

也就是说,And Design Pro 是不仅是一套前端开发框架,更是一整套的中后台前端解决方案,在力求提供开箱即用的开发体验,为此我们提供完整的脚手架,涉及国际化,权限,mock,数据流,网络请求等各个方面。为这些中后台中常见的方案提供了最佳实践来减少学习和开发成本。

本章我们会了解 antd pro 的大概,了解antd pro是什么、目录结构大概,然后创建一个基础项目并运行之。

阅读全文 »

编码是将信息从一种新式或格式转变为另一种形式的过程,在计算机硬件中,编码就是利用代码来表示各组数据资料,使计算机能够读懂这行代码并对信息进行分析和处理。

统一代码规范,就是统一代码的组织方式,让团队以最优的、一致的方式及组织代码,从而减少额外的阅读代码的负担。

阅读全文 »

PM2 是一个带有负载均衡功能的 Node 应用进程管理器。是管理 node 服务器的良好工具。其具有以下主要特性:

  • 内建负载均衡(使用 Node cluster 集群模块)
  • 后台运行
  • 具有 Ubuntu 和 CentOS 的启动脚本
  • 停止不稳定的进程(避免无限循环)
  • 控制台检测
  • 提供 HTTP API
  • 远程控制和实时的接口 API(Nodejs 模块,允许和 PM2 进程管理器交互)

官网 ==>

阅读全文 »

苏格拉底是古希腊著名的思想家、哲学家、教育家。他和他的学生柏拉图,以及柏拉图的学生亚里士多德并称为 “古希腊三贤”,被后人广泛地认为是西方哲学的奠基者。

而苏格拉底提出了著名的人生哲学终极三问:“我是谁、我从哪里来、我要到哪里去?”

为何这会被称为终极三问?因为这些问题表面上简单,其实很难回答上来。我是谁?很多时候你以为你知道你是谁,其它你只知道自己的标签。我是一个程序员、我是一名父亲、我是一名党员,那么终究到底除却这些标签后,你还是谁呢?你是从哪里来的,你要到哪里去?

技术也是一样的,我们常常只对一个技术留于表面,比如我们知道 面向对象编程,那什么是 面向对象,他的本质是什么,这个技术或机制是怎么设计出来的,为什么要这样设计,我们常常选择性忽略这些问题或满足于对其的一知半解。而 技术三问系列 就是这样的一个自醒的专题,我希望在这里记录下我对这门技术的认识,并要求自己不断地追求探索,企图了解更多其中的奥妙与真谛。

其中对于每一个技术点我都希望遵循这样的结构(下面的 XX 代表每章要讲的内容,有些摘录的文章会直接抄录原文的内容,注明是【转】的,并给出原文作者与地址):

  1. 是什么:XX 是什么,尽自己最大能力说明 xx 的作用、本质、及是如何产生、实现、应用的。
  2. 为什么:XX 是为了解决什么问题,解决这个问题有些什么现有的方法,为什么要用 XX。
  3. 怎么样:XX 的设计与实现是怎样的,XX 是怎样工作来解决问题的。
  4. 还能怎样:进阶应用,怎样优化 XX,还有哪些延伸的应用。
  5. 操作:命令、代码、步骤记录。更 贴近实际项目与产品,尽量结合实际工作中的经验、工具、流程。
阅读全文 »
0%