0- 深度学习之神经网络核心原理与算法-课程介绍
课程导学
计算机计算能力不断攀升。
阿尔法狗击败李世石
人工智能ai。无人驾驶汽车。机器狗。
不会咬人,能自己调整重心(被踢一脚)
人工智能(深度学习)
- 智能音箱: 开灯等
门槛高
- 家用pc通常无法有效胜任
- 需要比较深厚和扎实的数学基础
计算能力比较强的gpu进行加速运算
高等数学,线性代数,泛函分析及其延伸的学科基础
捷径: TensorFlow等框架Torch等热门的开源框架
简单的代码,或者模型描述文件组成一个神经网络。
课程内容及目标
- 常用的软件包和开发环境
- 前馈神经网络,结构,算法和实现
- 热门的深度学习框架: Tensorflow
- 卷积神经网络,结构,算法和实现
- 应用实战
- 与其他框架的比较
可以学习到:深度学习的理论,深度学习的算法原理,深度学习的应用实践
课程知识要求
- linux操作系统的基本操作
- 较为熟练的掌握python(安装包和模块)
- 了解高等数学,线性代数,微积分相关的数学知识
环境参数
python2.7
TensorFlow1.2.1
Linux: 16.04上运行
适合人群
希望对于深度学习了解的技术人员或深度学习初级从业人员
课前准备
开发环境:
Linux: ubuntu16.04
python: Python2.7
Pycharm + linux下vim
GPU
Cuda
pycharm 跨平台的编辑器。
修改文字大小:
font tab占几个空格。
设置本机python解释器路径。
常用软件包
- numpy(矩阵)
- scikit-learn(机器学习)
- theano(深度学习网络)
- TensorFlow(图片识别和图片的分类)
- keras(基于TensorFlow做了一层封装)
Keras高层次封装,使用简单。
使用TensorFlow和keras的对比。卷积神经网络使用theano
- caffe 图片相关:底层c++
- Torch(facebook lua脚本)
Numpy数组
-
ndarray.ndim
: 数组的维数,当这个数为2,就是二维数组(矩阵) -
ndarray.shape
: 数组的维度,例如二维数组中,表示数组的行数和列数 -
ndarray.size
: 数组元素的总个数,等于shape属性中元组元素的乘积 -
ndarray.dtype
: 表示数组中元素类型的对象,可使用标准的python类型创建或指定dtype,也可使用numpy提供的数据类型。
import numpy as np
a = np.array([2, 3, 4])
print(a)
# 元素数据类型
print(a.dtype)
# 数组的维度(3,) 一行三列
print(a.shape)
# 数组的维数 一维
print(a.ndim)
# 数组的元素个数
print(a.size)
print("*********************************")
b = np.array([[1, 2], [3, 4]])
print(b)
# 元素数据类型
print(b.dtype)
# 数组的维度(2,2) 两行两列
print(b.shape)
# 数组的维数 一维
print(b.ndim)
# 数组的元素个数
print(b.size)
print("*********************************")
c = np.array([[1, 2], [3, 4]], dtype=float)
print(c)
print("*********************************")
# np.zeros创建零矩阵
d = np.zeros((3, 4))
print(d)
print("*********************************")
# np.ones创建全1矩阵,每个元素初始化为1.0
e = np.ones((3, 4))
print(e)
print("*********************************")
# 首先创建一个两行三列的数组
b = np.ones((2, 3))
print(b)
# reshape成三行两列的数组
print(b.reshape(3, 2))
print("*********************************")
# 如何组合两个数组
# 1-数乘
a = np.ones((3, 4))
# a中的每一项都乘以2,然后赋值给b
b = a * 2
print(a)
print(b)
print("*********************************")
# 2-水平合并:
# 注意传入参数为元组,否则传入a,b不报错也没有结果
print(np.hstack((a, b)))
print("*********************************")
# 3-垂直合并
print(np.vstack((a, b)))
运行结果:
[2 3 4]
int32
(3,)
1
3
*********************************
[[1 2]
[3 4]]
int32
(2, 2)
2
4
*********************************
[[1. 2.]
[3. 4.]]
*********************************
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
*********************************
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
*********************************
[[1. 1. 1.]
[1. 1. 1.]]
[[1. 1.]
[1. 1.]
[1. 1.]]
*********************************
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
[[2. 2. 2. 2.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]]
*********************************
[[1. 1. 1. 1. 2. 2. 2. 2.]
[1. 1. 1. 1. 2. 2. 2. 2.]
[1. 1. 1. 1. 2. 2. 2. 2.]]
*********************************
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]]
常用软件包(pip过慢)
vi ~/.pip/pip.conf
为pip更换阿里云源。
mark开发环境搭建
软件包安装
pip & numpy & scikit-learn:
sudo apt install python-pip
sudo apt install python-numpy python-scipy
sudo pip install -U scikit-learn
theano & tensorflow & keras:
sudo apt install python-dev python-nose g++ libopenblas-dev git
sudo pip install Theano (gpu)
sudo pip install tensorflow (TensorFlow-gpu)
sudo pip install keras
theano 和 TensorFlow都有两个版本,一个版本可以使用gpu
查看源码
git clone https://github.com/keras-team/keras
神经元
生物神经网络
神经网络是一种人类由于受到生物神经网络细胞结构的启发而研究出的一种算法体系
mark细胞体,细胞体的周围是树突。轴突。
树突和轴突之间相互传递信息,他们之间的接触点就是突触。
信号由一个细胞的轴突通过突触将信号传递给里另一个细胞的树突。
加减乘法,比大小,循环,分支,读写数据
一个简单的神经元
mark有输入有输出
- 由两部分组成: 线性模型,激励函数
- 线性模型: f(x) = x + 1 一个简单的线性函数
n个输入项的神经元。这里的x是一个n*1
的矩阵,w是一个1*n
的权重矩阵。
b是偏置项
假设n=5,x就是一个5*1
的输入矩阵,例如:
表示对于一个样本多个维度的描述。
其他的用户有可能对应的会取另外的值。
这样的一个一个样本组合起来就形成了一个很大的样本空间
W是一个1*5
的矩阵,表示每一项的权重
[0.3 0.8 1.5 1.2 0.5]
markb是一个实数,也可以看成1*1
的矩阵
假设这里的b=0.那么函数f(x) = wx +b
f(x) = 1*0.3 + 50*0.8 + 27*1.5 + 19*1.2 +(-55)*0.5 +0
= 44.7
每一个对应项相乘,内积得到一个数。
某个金融机构评价用户质量好坏的评价函数
mark这里我么省略了激励函数,只保留了线性模型。
这里问题就来了,这个w是谁规定的。
如果真的有这么一个公式,那么其中的w是通过逆向的方法得到的。
假设我们有一些未知的w。
我们拥有大量的数据
mark我们也拥有这些样本数据所对应的分数(多年业务专家标注的)
mark线性回归的方式。
刚才的案例中我们知道b和w 通过x去求y
现在我们知道x和y,去反向求出w和b。
损失函数(Loss函数)
mark这里的wx1 + b 是对应对x1样本的预测y帽子。
减去y得到该样本的残差,也就是与真实值的距离。
累加之后得到整个样本空间的损失。
描述拟合与真实观测的差异之和。残差。
我们要想得到比较好的w和b就得让这个loss函数的值尽可能的小
越小表示这个线性模型预测出的结果与真实值越靠近。表明w和b越合适
激励函数
单个神经元是由线性模型和激励函数组成的。
激活函数。激励函数(Activation Function),跟随在f(x) = wx + b函数之后,用于加入一个非线性的因数。
mark激励函数有许多种,激励函数的名字,曲线,方程。
比较成熟的深度学习框架中提供给我们使用的激励函数是很有限的,只有那么几种。
sigmoid函数
mark横轴代表z,纵轴代表f(z)
mark在这个曲线中我们可以看到一个高维的x向量当做输入的话,经过wx两个矩阵做完内积之后再加上b的结果就变成了z。这样一个线性模型得到的结果z,再充当自变量把它叠加到
中,这样就可以使得输入x与输出f(x)关系和我们之前所说的只有线性部分的话有所不同。
完整的神经元
当一个完整的神经元被定义的时候,它通常是带有"线性模型"和"激励函数"两个部分首尾相接而成的。
mark线性模型输出结果,变成激励函数的输入值。
线性模型接收外界进来的x向量作为刺激,经过线性模型,经过激活函数得到输出。
sigmoid函数是一种比较早出现的激励函数,可以把线性模型的输出值投射到0和
1的区间中去。
通过这种方式我们引入了非线性因素。其中0代表不激活,1代表完全激活。其他值位于两者中间。
为什么要引入非线性因素?
如果仅有线性因素存在的话,最终的结果也一定包含种种的线性因素。
但是一般我们要求解的东西中并不会只包含线性因素。还会包含非线性因素。
如果我们的网络不包含非线性因素,就会严重的欠拟合。求得的关系就会不准确
Tanh函数
mark双曲正切激励函数。RNN时会接触到这个函数。
和sigmoid函数长相接近都是一条s型曲线。将值投射到了-1到1上去。
-1 表示不激活,1表示完全激活。
x和y的关系上来看,sigmoid函数是在x的绝对值大于4之后趋于平稳,极值贴近于0或者1
双曲正切函数当x的绝对值大于2之后,曲线就会非常的平缓。极为贴近极值-1和1
这会影响训练过程中待定系数的收敛问题。
Relu函数
markRelu激励函数是目前大多数的CNN中喜欢使用的激励函数。
mark在x和0之间取最大值。
0左侧部分斜率为0,右侧斜率为1.这也是一个非线性函数。
神经网络
一旦多个神经元首尾相连形成一个网络来协同工作时,就可以称之为神经网络。
mark一般没有人去硬性的规定网络必须有多少层,每层必须有几个神经元节点。
都是在具体的场景中进行尝试,设计出一个适合当前场景的神经网络。
神经网络的历史中有太多的神经网络。都是根据各种工程需求,或者出自大企业的实验室。配合论文,以及与其他网络的对比。
很少能发现严谨的推导过程。大部分还是靠实验和经验对于网络进行调整
神经网络的结构: 输入层 & 隐藏层 & 输出层
输入层位于神经网络的最外层,直接接收输入的向量,不对数据做出任何的处理。
所以输入层通常是不计入神经网络的层数计算的。
隐藏层可以有多层了。深的网络有超过50层的。
深度残差网络中会有超过150层的隐藏层
输出层: 用于输出整个网络处理的值,这个值可能是一个分类向量的值。
一个线性回归类似产生的连续值。根据不同的需求,输出层的构造也会不同。
前一层的神经元介绍到数据进行处理会传输到后一层的一个或多个的神经元中。
那么x输入向量中的任何一个维度的分量都可以看到它经过一层一层的处理经过了哪些神经元,并且输出后又输入了哪些神经元。
深度神经网络 (DNN)
所谓的深度学习实际指的是基于Deep Neural Networks 的学习,也就是深度人工神经网络所进行的学习过程,也称作Deep Learning
这个 Deep指的是神经网络的深度(层数多)
没有特别的规定大于多少层算深度神经网络。暂且把超过两层(也就是一个隐藏层一个输出层)以上的叫做深度神经网络。
识别图片是否漂亮,是否是一个车。特征提取困难
学习到很多层面的信息显得更为智能。
深度学习为什么这么强?
它可以通过大量的线性分类器和非线性分类器的关系组合来完成平时非常棘手的线性不可分问题。
不用再提取特征
- 朴素贝叶斯 决策树 支持向量机SVM 提取特征是一个非常重要的前置工作
需要将大量的样本数据整理出来,提取其中干净有用的数据维度。否则这些基于概率的分类器没法进行工作。
- 神经网络由于巨量的线性分类器的堆叠,以及卷积的使用。
对于噪声的忍耐能力,多通道数据上投射出来的不同特征的敏感程度会自动处理或忽略。
处理线性不可分
svm也有一定的能力来解决线性不可分,但是它是引入高维的一个切割超平面来解决。
mark而神经元的每一个网络都是一个线性分类器,神经网络可以通过线性分类器的组合解决线性不可分的问题。
二维空间。无法使用一根线,将四边形与外面的点进行分割。
但神经网络中就没有关系了。我们大不了画四条线。这就是同时满足四个分类器的分类标准,才能算是我们要求满足的分类1。每条直线的表达式都是形式为y=wx+b的线性分类器。
这也就是神经网络比以前各种分类器厉害的地方。以前的任何一个分类器都没有这种能耐。
神经网络可以有很多层,每层有很多个。神经网络的总体规模可以有几千上万个神经元。
这种情况下我们几乎可以描述出任何的线性不可分的情况。
随着维度的加大,神经网络的维度的加深。图像,视频音频等可以用深度学习来处理。
深度学习的应用
- AlphaGo
- 图片风格变换
基于人工智能,每个风格都是由艺术家风格。基于卷积神经网络。