课程导学
计算机计算能力不断攀升
阿尔法狗击败李世石
人工智能 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 提供的数据类型
mark
- 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 一个简单的线性函数
mark
n 个输入项的神经元这里的 x 是一个 n*1 的矩阵, w 是一个 1*n 的权重矩阵
b 是偏置项
假设 n=5,x 就是一个 5*1 的输入矩阵, 例如:
mark
表示对于一个样本多个维度的描述
其他的用户有可能对应的会取另外的值
这样的一个一个样本组合起来就形成了一个很大的样本空间
W 是一个 1*5 的矩阵, 表示每一项的权重
[0.3 0.8 1.5 1.2 0.5]
mark
b 是一个实数, 也可以看成 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)
在这个曲线中我们可以看到一个高维的 x 向量当做输入的话, 经过 wx 两个矩阵做完内积之后再加上 b 的结果就变成了 z 这样一个线性模型得到的结果 z, 再充当自变量把它叠加到
mark
中, 这样就可以使得输入 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 函数
mark
Relu 激励函数是目前大多数的 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
mark
图片风格变换
mark
基于人工智能, 每个风格都是由艺术家风格基于卷积神经网络
来源: http://www.jianshu.com/p/81b7f901d14c