理解深度学习需要熟悉一些简单的数学概念: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加法运算仅支持两个形状相同的二维张量。如果两个加法运算的张量形状不相同会发生什么?小张量会广播匹配到大张量上。广播由两步组成:
- 小张量会添加axes广播轴,以匹配大张量的ndim轴维度。
- 小张量在新添加的轴方向上重复以匹配大张量的形状。
举例来说,张量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\) 是网络层的参数,被称为网络层的权重系数或者可训练参数。这些权重系数包含着网络从训练数据中学到的信息。
起始这些权重参数用小的随机数赋值(称为随机初始化)。随后,基于反馈信号逐渐调整权重系数。调整过程称为训练过程。
训练过程通常需要反复进行:
- 获得训练数据X,y的一个batch 批量;
- 前向传播得到批量X上的预测值y_pred;
- 计算当前批量下的损失值:计算y_pred和y之间的差异度;
- 在损失函数减小的方向上更新权重系数。
随机梯度下降
一个可微分函数,理论上能够找到它的最小值:最小值点导数为0,所以需要找到所有导数为0的点,然后相互比较找到最小值。
神经网络中,意味着找到一组权重值,使损失函数最小。
mini-batch SGD可以描述为以下四步:
- 获得训练数据X,y的一个batch 批量;
- 前向传播得到批量X上的预测值y_pred;
- 计算当前批量下的损失值:计算y_pred和y之间的差异度;
- 沿着梯度反方向移动权重系数--例如:\(W -= step * gradient\),损失函数也因此减小。
随机是指每个小批量batch是随机在数据中挑选的。
小批量随机梯度下降的一种极端情况是随机梯度下降算法---全部数据形成一个批量,计算结果更准确,但效率比较低。
小结
- 学习指在训练数据上找到一组权重值使得损失函数最小;
- 学习过程:在小批量数据上计算损失函数对应权重系数的梯度值;之后权重系数沿着梯度的反方向移动;
- 学习过程的可能性是基于神经网络是一系列张量操作,因此能够使用导数的链式法则计算损失函数对应权重系数的梯度值;
- 两个重要的概念:损失函数和优化方法(需要在数据送到网络之前定义);
- 损失函数:在训练过程中最小化的函数,可以用来评估模型的好坏(越小越好,最小为0);
- 优化方法:计算梯度的具体方法,之后更新权重系数;比如有:RMSProp、SGD、Momentum等等。
[Deep-Learning-with-Python]神经网络的数学基础的更多相关文章
-
Deep learning with Python 学习笔记(11)
总结 机器学习(machine learning)是人工智能的一个特殊子领域,其目标是仅靠观察训练数据来自动开发程序[即模型(model)].将数据转换为程序的这个过程叫作学习(learning) 深 ...
-
Deep learning with Python 学习笔记(10)
生成式深度学习 机器学习模型能够对图像.音乐和故事的统计潜在空间(latent space)进行学习,然后从这个空间中采样(sample),创造出与模型在训练数据中所见到的艺术作品具有相似特征的新作品 ...
-
Deep learning with Python 学习笔记(9)
神经网络模型的优化 使用 Keras 回调函数 使用 model.fit()或 model.fit_generator() 在一个大型数据集上启动数十轮的训练,有点类似于扔一架纸飞机,一开始给它一点推 ...
-
Deep learning with Python 学习笔记(8)
Keras 函数式编程 利用 Keras 函数式 API,你可以构建类图(graph-like)模型.在不同的输入之间共享某一层,并且还可以像使用 Python 函数一样使用 Keras 模型.Ker ...
-
Deep learning with Python 学习笔记(7)
介绍一维卷积神经网络 卷积神经网络能够进行卷积运算,从局部输入图块中提取特征,并能够将表示模块化,同时可以高效地利用数据.这些性质让卷积神经网络在计算机视觉领域表现优异,同样也让它对序列处理特别有效. ...
-
Deep learning with Python 学习笔记(6)
本节介绍循环神经网络及其优化 循环神经网络(RNN,recurrent neural network)处理序列的方式是,遍历所有序列元素,并保存一个状态(state),其中包含与已查看内容相关的信息. ...
-
Deep learning with Python 学习笔记(5)
本节讲深度学习用于文本和序列 用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一 ...
-
Deep learning with Python 学习笔记(4)
本节讲卷积神经网络的可视化 三种方法 可视化卷积神经网络的中间输出(中间激活) 有助于理解卷积神经网络连续的层如何对输入进行变换,也有助于初步了解卷积神经网络每个过滤器的含义 可视化卷积神经网络的过滤 ...
-
Deep learning with Python 学习笔记(3)
本节介绍基于Keras的使用预训练模型方法 想要将深度学习应用于小型图像数据集,一种常用且非常高效的方法是使用预训练网络.预训练网络(pretrained network)是一个保存好的网络,之前已在 ...
-
Deep learning with Python 学习笔记(2)
本节介绍基于Keras的CNN 卷积神经网络接收形状为 (image_height, image_width, image_channels)的输入张量(不包括批量维度),宽度和高度两个维度的尺寸通常 ...
随机推荐
-
修改数据库表的schema,(表的[dbo.]前缀)
数据库使用过程中遇到这种问题,请看下图
-
Js笔试题之返回只包含数字类型的数组
如js123ldka78sdasfgr653 => [123,78,653] 一般做法 分析: 1.循环字符串每个字符,是数字的挑出来拼接在一起,不是数字的,就给他空的拼个逗号 2.将新字符串每 ...
-
使用系统UITabbarItem自定义图片显示原本颜色和自定义文字颜色
...... ThirdViewController *thirdVC = [[ThirdViewControlleralloc]initWithTitle:@"搜索信息"]; / ...
-
ASP.Net网站部署失败
部署站点时候,出现如下错误 “/”应用程序中的服务器错误. ---------------------------------------------------------------------- ...
-
1008. Image Encoding(bfs)
1008 没营养的破题 #include <iostream> #include<cstdio> #include<cstring> #include<alg ...
-
Mysql高级之游标
原文:Mysql高级之游标 什么是游标?select 语句也许一次性会取出来n条语句,那么游标便可以一次取出来select中的一条记录.每取出来一条,便向下移动一次!可以实现很复杂逻辑! 上面还有有一 ...
-
day05 判断敏感字符
1.判断一个字符是不是敏感字符: in 1.str v ="年龄多大了" if "大" in v: print("敏感") 2.list/t ...
-
String的getBytes()方法 以及 new String()
在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组.这表示在不同的操作系统下,返回的东西不一样! String.getBytes(Stringdecode) ...
-
Java图形化界面设计——布局管理器之GridBagLayout
GridBagLayout 不会随着窗口的变化标签随之发生变化,可固定. ---------------------------------------------------------- impo ...
-
Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) D - Dynamic Problem Scoring
地址:http://codeforces.com/contest/807/problem/D 题目: D. Dynamic Problem Scoring time limit per test 2 ...