理解深度学习需要熟悉一些简单的数学概念:Tensors(张量)、Tensor operations 张量操作、differentiation微分、gradient descent 梯度下降等等。

“Hello World”----MNIST 手写数字识别

#coding:utf8
import keras
from keras.datasets import mnist
from keras import models
from keras import layers
from keras.utils import to_categorical
# 加载MNIST数据集
(train_images,train_labels),(test_images,test_labels) = mnist.load_data() # 定义网络架构
network = models.Sequential()
network.add(layers.Dense(512,activation="relu",input_shape=(28*28,)))
network.add(layers.Dense(10,activation="softmax")) # 定义网络优化:优化算法、损失函数以及评价指标
network.compile(optimizer='rmsprop',loss="categorical_crossentropy",metrics=['accuracy']) # 数据预处理:images 缩放到[0,1]之间
train_images = train_images.reshape(60000,28*28)
train_images = train_images.astype('float32') / 255 test_images = test_images.reshape(test_images.shape[0],28*28)
test_images = test_images.astype('float32') / 255 # 数据预处理:labels:one-hot 编码
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels) # 模型训练
network.fit(train_images,train_labels,epochs=5,batch_size=128) # 模型测试
test_loss, test_acc = network.evaluate(test_images,test_labels)
print('test accuracy:',test_acc)
# test accuracy: 0.9727

由上面的程序,我们了解了如何构建网络以及如何进行网络训练来识别手写字体

神经网络的数据表示

当下几乎所有的机器学习框架都使用tensors张量作为基本的数据结构。Tensor本质上是一个数据容器,大多数为数值型数据,也就是说tensor是存储数字的容器。矩阵是二维的张量,张量是任意维数的矩阵的推广(tensor的一个维度通常称为一个轴axis,而不是dimension)。

Scalars(0D tensors)标量--0维张量

只包含一个数字的张量tensor叫做标量scaler(或者0D tensor). 在numpy中,一个float32,或float64类型的数字是一个标量。可以通过tensor的ndim属性查看tensor的维度;张量的维度为0,同时维度也称为秩rank。

>>> import numpy as np
>>> x = np.array(12)
>>> x
array(12)
>>> x.ndim
0

向量(一维张量 1D)

一维数组称为向量,或一维张量。一维张量有一个轴axis;

>>> x = np.array([13, 31, 7, 14])
>>> x
array([13, 31, 7, 14])
>>> x.ndim
1

上述向量有5个条目,因此称为5维向量。5维向量和5维张量并不相同。5维向量指一个轴5个元素。5维张量有5个轴。

矩阵(二维张量 2D)

向量数组为一个矩阵,即二维张量。一个矩阵有二个轴。

>>> x = np.array([[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]])
>>> x.ndim
2

三维张量以及更高维张量

矩阵数组称为三维张量,可以看做是数字的立方体。

>>> x = np.array([[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]],
[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]],
[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]]])
>>> x.ndim
3

3维张量数组形成一个4维张量,以此类推。深度学习中,一般操作0D~4D的张量。

核心属性

tensor张量由3个重要的属性:

  • Number of axes轴的个数(秩)。3D tensor有3个轴。可以通过tensor的ndim属性查看轴的个数。
  • Shape形状:数字元组,描述张量各个轴上的维度。张量维度为(),向量维度为(5,),2D张量维度(3,5),3D张量维度(3,3,5).
  • Data type数据类型(dtype属性):张量中数字的数据类型,如float32,uint8,float64等等。

数据批量data batches

深度学习中数据张量的第一轴(axis 0)通常是样本轴(样本维度)---表示样本量的数目。MNIST数据集中,样本是数字图片。

此外,深度学习处理数据过程中并不一次性对整个数据集进行处理,通常会将数据集划分成若干个批量batches。比如:MNIST中128的小批量样本:

batch = train_images[:128]

生活中遇到的数据张量

  • 向量型数据vector data--2维张量 ,形状(samples,features)
  • 时间序列数据或序列型数据--3维张量,形状(samples,timesteps, features)
  • 图片--4维张量,形状(samples, height, width, channels)或者(samples, channels, height, width)
  • 视频--5维张量。形状(samples. frames, height, width, channels) 或者(samples, frames, channels, height, width)

Tensors 操作

所有的计算机程序最终都简化为二进制输入上的二进制操作(AND, OR, NOR 等),同时,深度学习网络中所有的转换也可以简化为数据张量上的张量操作,如 加、乘等。

逐元素操作element-wise operations

relu操作和加法运算是逐元素操作:独立应用于待计算张量中的每个条目。

比如加法运算的for-loop实现:

def naive_add(x, y):
assert len(x.shape) == 2
assert x.shape == y.shape
x = x.copy()
for i in range(x.shape[0]):
for j in range(x.shape[1]):
x[i, j] += y[i, j]
return x

广播broadcasting

上面实现的naive_add加法运算仅支持两个形状相同的二维张量。如果两个加法运算的张量形状不相同会发生什么?小张量会广播匹配到大张量上。广播由两步组成:

  1. 小张量会添加axes广播轴,以匹配大张量的ndim轴维度。
  2. 小张量在新添加的轴方向上重复以匹配大张量的形状。

举例来说,张量X形状为(32, 10),张量y形状为(10, ).两个张量相加。首先,添加一个新轴到张量y上,形状变成(1, 10);然后,在新轴方向上重复y32次,最终张量Y形状为(32,10),X、Y形状相同,可以进行加法运算。

但实际过程中并不会创建新的二维张量,影响计算效率。

def naive_add_matrix_and_vector(x, y):
assert len(x.shape) == 2
assert len(y.shape) == 1
assert x.shape[1] == y.shape[0]
x = x.copy()
for i in range(x.shape[0]):
for j in range(x.shape[1]):
x[i, j] += y[j]
return x

张量点积运算 Dot

dot点积操作最常用、最有用的张量操作。与逐元素操作相反,点积整合输入张量的所有条目。

def naive_vector_dot(x, y):
assert len(x.shape) == 1
assert len(y.shape) == 1
assert x.shape[0] == y.shape[0]
z = 0.
for i in range(x.shape[0]):
z += x[i] * y[i]
return z

tensor reshaping

reshape意味着重新排列张量tensor的行和列以满足特定的形状。Reshape之后的tensor与初始tensor包含的系数数目相同。

>>> x = np.array([[0., 1.],
[2., 3.],
[4., 5.]])
>>> print(x.shape)
(3, 2)
>>> x = x.reshape((6, 1))
>>> x
array([[ 0.],
[ 1.],
[ 2.],
[ 3.],
[ 4.],
[ 5.]])

基于梯度的优化算法

神经网络层对输入进行的数学转换为:

\(output = relu(dot(W, input) + b)\)

张量\(W\)和张量\(b\) 是网络层的参数,被称为网络层的权重系数或者可训练参数。这些权重系数包含着网络从训练数据中学到的信息。

起始这些权重参数用小的随机数赋值(称为随机初始化)。随后,基于反馈信号逐渐调整权重系数。调整过程称为训练过程。

训练过程通常需要反复进行:

  1. 获得训练数据X,y的一个batch 批量;
  2. 前向传播得到批量X上的预测值y_pred;
  3. 计算当前批量下的损失值:计算y_pred和y之间的差异度;
  4. 在损失函数减小的方向上更新权重系数。

随机梯度下降

一个可微分函数,理论上能够找到它的最小值:最小值点导数为0,所以需要找到所有导数为0的点,然后相互比较找到最小值。

神经网络中,意味着找到一组权重值,使损失函数最小。

mini-batch SGD可以描述为以下四步:

  1. 获得训练数据X,y的一个batch 批量;
  2. 前向传播得到批量X上的预测值y_pred;
  3. 计算当前批量下的损失值:计算y_pred和y之间的差异度;
  4. 沿着梯度反方向移动权重系数--例如:\(W -= step * gradient\),损失函数也因此减小。

    随机是指每个小批量batch是随机在数据中挑选的。

    小批量随机梯度下降的一种极端情况是随机梯度下降算法---全部数据形成一个批量,计算结果更准确,但效率比较低。

小结

  • 学习指在训练数据上找到一组权重值使得损失函数最小;
  • 学习过程:在小批量数据上计算损失函数对应权重系数的梯度值;之后权重系数沿着梯度的反方向移动;
  • 学习过程的可能性是基于神经网络是一系列张量操作,因此能够使用导数的链式法则计算损失函数对应权重系数的梯度值;
  • 两个重要的概念:损失函数和优化方法(需要在数据送到网络之前定义);
  • 损失函数:在训练过程中最小化的函数,可以用来评估模型的好坏(越小越好,最小为0);
  • 优化方法:计算梯度的具体方法,之后更新权重系数;比如有:RMSProp、SGD、Momentum等等。

[Deep-Learning-with-Python]神经网络的数学基础的更多相关文章

  1. Deep learning with Python 学习笔记(11)

    总结 机器学习(machine learning)是人工智能的一个特殊子领域,其目标是仅靠观察训练数据来自动开发程序[即模型(model)].将数据转换为程序的这个过程叫作学习(learning) 深 ...

  2. Deep learning with Python 学习笔记(10)

    生成式深度学习 机器学习模型能够对图像.音乐和故事的统计潜在空间(latent space)进行学习,然后从这个空间中采样(sample),创造出与模型在训练数据中所见到的艺术作品具有相似特征的新作品 ...

  3. Deep learning with Python 学习笔记(9)

    神经网络模型的优化 使用 Keras 回调函数 使用 model.fit()或 model.fit_generator() 在一个大型数据集上启动数十轮的训练,有点类似于扔一架纸飞机,一开始给它一点推 ...

  4. Deep learning with Python 学习笔记(8)

    Keras 函数式编程 利用 Keras 函数式 API,你可以构建类图(graph-like)模型.在不同的输入之间共享某一层,并且还可以像使用 Python 函数一样使用 Keras 模型.Ker ...

  5. Deep learning with Python 学习笔记(7)

    介绍一维卷积神经网络 卷积神经网络能够进行卷积运算,从局部输入图块中提取特征,并能够将表示模块化,同时可以高效地利用数据.这些性质让卷积神经网络在计算机视觉领域表现优异,同样也让它对序列处理特别有效. ...

  6. Deep learning with Python 学习笔记(6)

    本节介绍循环神经网络及其优化 循环神经网络(RNN,recurrent neural network)处理序列的方式是,遍历所有序列元素,并保存一个状态(state),其中包含与已查看内容相关的信息. ...

  7. Deep learning with Python 学习笔记(5)

    本节讲深度学习用于文本和序列 用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一 ...

  8. Deep learning with Python 学习笔记(4)

    本节讲卷积神经网络的可视化 三种方法 可视化卷积神经网络的中间输出(中间激活) 有助于理解卷积神经网络连续的层如何对输入进行变换,也有助于初步了解卷积神经网络每个过滤器的含义 可视化卷积神经网络的过滤 ...

  9. Deep learning with Python 学习笔记(3)

    本节介绍基于Keras的使用预训练模型方法 想要将深度学习应用于小型图像数据集,一种常用且非常高效的方法是使用预训练网络.预训练网络(pretrained network)是一个保存好的网络,之前已在 ...

  10. Deep learning with Python 学习笔记(2)

    本节介绍基于Keras的CNN 卷积神经网络接收形状为 (image_height, image_width, image_channels)的输入张量(不包括批量维度),宽度和高度两个维度的尺寸通常 ...

随机推荐

  1. [swift] Async

    Async https://github.com/duemunk/Async Syntactic sugar in Swift for asynchronous dispatches in Grand ...

  2. SparkSql实现Mysql到hive的数据流动

    今天去面试了一波,因为调度系统采用了SparkSql实现数据从Mysql到hive,在这一点上面试官很明显很不满我对于Spark的理解,19年的第一个面试就这么挂了. 有问题不怕,怕的是知道了问题还得 ...

  3. Provisional headers are shown

    问题: Chrome请求出现"Provisional headers are shown": 原因: 这种一般是由于浏览器端的插件或客户端的软件对请求进行了拦截:我们出现的情况,是 ...

  4. Hadoop HBase概念学习系列之RowKey设计(二十九)

    HBase里的RowKey设计,分为随机查询的RowKey设计和连续查询的RowKey设计.

  5. B/S网络概述

    B/S网络架构 随着Web2.0时代的到来,互联网的网络架构已经从传统的C/S架构转变到更加方便快捷的B/S架构.这样的转化简化了人们上网的方式,也加速了互联网行业的发展. B/S架构的好处: 1.客 ...

  6. python pandas dataframe 操作记录

    从数据看select出数据后如何转换为dataframe df = DataFrame(cur.fetchall()) 如何更改列名,选取列,进行groupby操作 df.columns = ['me ...

  7. jupyter notebook设置主题背景,字体和扩展插件

    windows上安装Anaconda (IPython notebook) Anaconda是一个包与环境的管理器,一个Python发行版,以及一个超过1000多个开源包的集合.它是免费和易于安装的, ...

  8. amcharts属性

    Amcharts的特点包含: *动画或静态 *价值轴能够扭转 *线性或对数轴的价值尺度 *提前定义或定制的子弹 *定制描写叙述不论什么数据点 *点击栏目/酒吧(可用于钻孔下来图表) *梯度弥漫 *价值 ...

  9. BZOJ1444:[JSOI2009]有趣的游戏(AC自动机,矩阵乘法)

    Description Input 注意 是0<=P, n , l, m≤ 10. Output Sample Input input 1 3 2 2 1 2 1 2 AB BA AA inpu ...

  10. 全局唯一Id:雪花算法

    雪花算法-snowflake 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有 ...