张量
一、张量的轴、阶和形状
张量是机器学习程序中的数字容器,本质上就是各种不同维度的数组,我们把张量的维度称为轴(axis),轴的个数称为阶(rank)(也就是俗称的维度,但是为了把张量的维度和每个阶的具体维度区分开,这里统一把张量的维度称为正脸那个的阶,Numpy中把它叫做数组的秩)
张量的形状(shape)就是张量的阶,加上每个阶的维度(每个阶的元素数目)
张量都可以通过Numpy来定义、操作。因此把Numpy数学函数库里面的数组用好,就可以搞定机器学习里面的数据结构。
二、标量——0D(阶)张量
仅包含一个数字的张量叫做标量(scalar),既0阶张量或0D张量。
标量的功能主要在于程序流程控制、设置参数值等。
下面创建一个NumPy标量:
import numpy as np #导入NumPy
X = np.array(5) # 创建0D张量,也就是标量
print("X的值",X)
print("X的阶",X.ndim) #ndim属性显示张量轴的个数
print("X的数据类型",X.dtype) # dtype属性显示张量数据类型
print("X的形状",X.shape) # shape属性显示张量形状
此处标量的形状为(),既标量的阶为0.
Numpy中,不管是阶的索引,还是数组的索引,永远是从0开始的。
三、向量——1D(阶)张量
由一组数字组成的数组叫做向量(vector),也就是一阶张量,或称1D张量。一阶张量只有一个轴。
下面创建一个NumPy向量:
X = np.array([5,6,7,8,9]) #创建1D张量,也就是向量
print("X的值",X)
print("X的阶",X.ndim) #ndim属性显示张量轴的个数
print("X的形状",X.shape) # shape属性显示张量形状
创建向量的时候要把数字元素放进方括号里面,形成一个包含5个元素的1D张量。需要再次强调的是,机器学习中把5个元素的向量称为5维向量。千万不要把5维向量和5阶向量混淆。
创建一个一维向量:
X = np.array([5]) # 1维的向量,就是1D数组里面只有一个元素
1.机器学习中的向量数据
向量非常的重要。在机器学习中,普通的连续数值数据集中的每一个独立样本都是一个向量,因此普通的连续数值数据集也可以叫做向量数据集。而数据集中的标签列也可以视为一个向量。
向量数据集是说数据集中的每一行或每一列,都可以视为向量,但是数据集整体是一个矩阵。
载入波士顿房价数据集查看:
from keras.datasets import boston_housing # 波士顿房价数据集
(X_train, y_train), (X_test, y_test) = boston_housing.load_data()
print("X_train的形状:", X_train.shape)
print("X_train中第一个样本的形状:", X_train[0].shape)
print("y_train的形状:", y_train.shape)
这个是Keras内置的波士顿房价数据集,是一个2D的普通数值数据集。
X_train是一个2D矩阵,是404个样本数据的集合。
X_train[0]代表的是X_train训练集的第一行数据,是一个13维向量(也是1D张量)。也就是说,训练集的每行数据都包含13个特征。
2.向量的点积
两个向量之间可以进行乘法运算,而且不止一种,有点积和叉积,其运算法则不同。
点积运算法则:就是两个相同维度的向量对应元素先相乘,后相加。
用代码展示:
python
weight = np.array([1,-1.8,1,1,2]) # 权重向量(也就是多项式的参数)
X = np.array([1,6,7,8,9]) # 特征向量(也就是一个特定样本中的特征值)
y_hat = np.dot(X,weight) # 通过点积运算构建预测函数
print('函数返回结果:', y_hat) # 输出预测结果
下面语句也可以实现相同的功能:
y_hat = weight.dot(X) # X.dot(weight)也可以实现同样结果
注意向量点积的结果是一个值,也就是一个标量,而不是一个向量。
四、矩阵——2D(阶)张量
矩阵是一组一组向量的集合。矩阵中的个元素横着、竖着、斜着都能构成不同的向量。而矩阵,也就是二阶张量,或称2D张量,其形状维(m,n)
矩阵里面横向的元素称为“行”,纵向的元素称为“列”。
1.机器学习中的矩阵数据
矩阵式2D张量,形状维(样本,特征)。第一个轴式样本轴,第二个式特征轴。
print("X_train的内容:", X_train) #X_train是2D张量,即矩阵
每一行实际包括13个特征,输出时通过省略号忽略了中间8个特征列的输出。整个张量(404行)。
2.矩阵的点积
矩阵之间也可以进行点积,是把第一个矩阵的行向量,和第二个矩阵的列向量进行点积,然后把结果标量放进新矩阵,作为结果矩阵中的一个元。
当相乘时,第一个矩阵的列数必须等于第二个矩阵的行数,既(m,n)的矩阵成语形状维(n,m)的矩阵,得到一个矩阵(m,m)。如果形状不符合规格,则不能进行点积运算。
五、序列数据——3D(阶)张量
在矩阵数据的基础上再增加一个阶,就形成了3D张量。
NumPy的3D张量数据结构是这样定义的:
# 创建3D张量
X = np.array([[[1, 22, 4, 78, 2],
[2, 59, 6, 56, 1],
[3, 31, 8, 54, 0]],
[[4, 56, 9, 34, 1],
[5, 78, 8, 35, 2],
[6, 34, 7, 36, 0]],
[[7, 45,5, 34, 5],
[8, 53, 6, 35, 4],
[9, 81, 4, 36, 5]]])
在实际应用中,序列数据集才是机器学习中的3D张量。而时间序列是最为常见的序列数据集。
对于时间序列数据来说,就是时间戳,也叫时间步。
因为增加了时戳,所以表里面的行列结构显得更为复杂。
第一个轴:样本轴,如:一年记录下来的数据共365个,也就是365维
第二个轴:时间步轴,如:每天一共是24小时,每小时4个15分钟,共96维
第三个轴:特征轴,如:一共是温度、湿度、风力3个维度
也就是说,时序数据集的形状为3D张量:(样本、时戳、标签)。
文字序列数据的形状维3D张量:(样本、序号、字编码)
六、图像数据——4D(阶)张量
图像数据本身包括高度、宽度,再加上一个颜色深度通道。MNIST数据集中是灰度图像只有一个颜色深度通道;而GRB格式的彩色图像,颜色深度通道的维度为3.
因此,对于图像数据集来说,长、宽、深再加上数据集大小这个维度 ,就形成了4D张量,其形状为(样本、图像高度、图像宽度、颜色深度),如MNIST特征数据集的形状(60000,28,28,1)。
在机器学习中,不是对上千万个数据样本同时进行处理,那样的话机器也受不了,而是一批一批地并行处理。
七、视频数据——5D(阶)张量
机器学习的初学者很少有机会见到比4D更高阶的张量,如果有,视频数据的结构是其中的一种。
视频可以看作是由一帧一帧的彩色图像组成的数据集。
每一帧都保存在一个形状为(高度、宽度、颜色深度)的3D张量中。
一系列帧则保存在一个形状为(帧、高度、宽度、颜色深度)的4D张量中。
因此,视频数据集需要5D张量才放得下,其形状为(样本、帧、高度、宽度、颜色深度)。
可以想象,视频数据的数据量是非常大的。面对这种规模的数据,普通的机器学习模型会感到手足无措,只有深度学习模型才能够搞定。
‘
八、数据的维度和空间的维度
1.数据的维度
维度是指在一个数据轴上的许多点,也就是样本的个数或者特征的个数。一万个不同的特征,就是一万维;而一万个数据样本,也同样可以称为一万维。
为了标准化叙述,我们把张量的每一个数据轴,统称为阶。因此,我们说一阶(1D)向量,二阶向量,三阶向量,而不是说维。
2.空间的维度
当维度很大的时候我们无法想象是什么样子的,但是我们可以采用应用降维算法处理数据,把数据降维到二维以内。
多维特征的函数图象是存在的,多元凸函数也一定可以梯度下降到全局最低点。
九、Python中的张量运算
通过代码和结果来展现Python中运算:
1.张量创建
import numpy as np # 导入NumPy数学工具集
list=[1,2,3,4,5] # 创建列表
array_01=np.array([1,2,3,4,5]) # 列表转化成数组
array_02=np.array((6,7,8,9,10)) # 元组转化成数组
array_03=np.array([[1,2,3],[4,5,6]]) # 列表转化成2D数组
print ('列表:', list)
print ('列表转化为数组:', array_01)
print ('元组转化为数组:', array_02)
print ('2D数组:', array_03)
print ('数组的形状:', array_01.shape)
# print ('列表的形状:', list.shape) # 列表没有形状,程序会报错
array_04=np.arange(1,5,1) # 通过arange函数生成数组
array_05=np.linspace(1,5,5) # 通过linspace函数生成数组
print (array_04)
print (array_05)
2.通过索引和切片访问张量中的数据
array_06 = np.arange(10)
print (array_06)
index_01 = array_06[3] # 索引-第4个元素
print ('第4个元素', index_01)
index_02 = array_06[-1] # 索引-最后一个元素
print ('第-1个元素', index_02)
slice_01 = array_06[:4] # 从0到4切片
print ('从0到4切片', slice_01)
slice_02 = array_06[0:12:4] # 从0到12切片,步长为2
print ('从0到12切片,步长为4', slice_02)
from keras.datasets import mnist #需要打开internet选项)
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print (X_train.shape)
X_train_slice = X_train[10000:15000,:,:]
array_07 = np.array([[1,2,3],[4,5,6]])
print (array_07[1:2],'它的形状是', array_07[1:2].shape)
print (array_07[1:2][0], '它的形状又不同了', array_07[1:2][0].shape)
3.张量的整体操作和逐元素运算
array_07 += 1 # 数组内全部元素加1
print (array_07)
for i in range(array_07.shape[0]):
for j in range(array_07.shape[1]):
array_07[i,j] += 1
print (np.sqrt(array_07)) #打印每一个元素的平方根
4.张量的变形和转置
print (array_07,'形状是', array_07.shape)
print (array_07.reshape(3,2), '形状是', array_07.reshape(3,2).shape)
array_07 = array_07.reshape(3,2) #进行赋值才能改变数组本身
array_07 = array_07.T # 矩阵的转置
array_06 = np.arange(10)
print (array_06,'形状是', array_06.shape,'阶为', array_06.ndim)
array_06 = array_06.reshape(10,1)
print (array_06,'形状是', array_06.shape,'阶为', array_06.ndim)
5.Python中的广播
array_08 = np.array([[0,0,0], [10,10,10], [20,20,20], [30,30,30]])
array_09 = np.array([[0,1,2]])
array_10 = np.array([[0],[1],[2],[3]])
list_11 = [[0,1,2]]
print ('array_09的形状:', array_09.shape )
print ('array_10的形状:', array_10.shape )
array_12 = array_09.reshape(3)
print ('array_12的形状:', array_12.shape )
array_13 = np.array([1])
print ('array_13的形状:', array_13.shape )
array_14 = array_13.reshape(1,1)
print ('array_14的形状:', array_14.shape )
print ('08 + 09结果:',array_08 + array_09)
print ('08 + 10结果:',array_08 + array_10)
print ('08 + 11结果:',array_08 + list_11)
print ('08 + 12结果:',array_08 + array_12)
print ('08 + 13结果:',array_08 + array_13)
print ('08 + 14结果:',array_08 + array_14)
6.向量和矩阵的点积运算
向量:
vector_01 = np.array([1,2,3])
vector_02 = np.array([[1],[2],[3]])
vector_03 = np.array([2])
vector_04 = vector_02.reshape(1,3)
print ('vector_01的形状:', vector_01.shape)
print ('vector_02的形状:', vector_02.shape)
print ('vector_03的形状:', vector_03.shape)
print ('vector_04的形状:', vector_04.shape)
print ('01和01的点积:', np.dot(vector_01,vector_01))
print ('01和02的点积:', np.dot(vector_01,vector_02))
print ('04和02的点积:', np.dot(vector_04,vector_02))
print ('01和数字的点积:', np.dot(vector_01,2))
print ('02和03的点积:', np.dot(vector_02,vector_03))
print ('02和04的点积:', np.dot(vector_02,vector_04))
# print ('01和03的点积:', np.dot(vector_01,vector_03)) # 程序会报错
# print ('02和02的点积:', np.dot(vector_02,vector_02))
矩阵:
matrix_01 = np.arange(0,6).reshape(2,3)
matrix_02 = np.arange(0,6).reshape(3,2)
print(matrix_01)
print(matrix_02)
print ('01和02的点积:', np.dot(matrix_01,matrix_02))
print ('02和01的点积:', np.dot(matrix_02,matrix_01))
print ('01和01的点积:', np.dot(matrix_01,matrix_01))
总结:
- 机器学习中的数据结构称为张量,下面是几种重要的张量格式,用于处理不同类型的数据集。
·普通向量数据集结构:2D张量,形状为(样本,标签)
·时间序列数据集或序列数据集:3D张量,形状为(样本,时戳,特征)
·图像数据集:4D 张量,形状为(样本、图像高度、图像宽度、颜色深度) - Python语句操作方面,NumPy数组的操作都是重点内容。
·张量的切片操作
·用reshape进行张量变形
·Python的广播功能
·向量和矩阵的点积操作之异同,向量的点积得到的是一个数
·要记得不定时检查张量的维度
转载:https://blog.csdn.net/sjjsaaaa/article/details/115915942