神经网络基础:张量
Time: 2021-06-10
前言
考虑到接触的数据以张量为主,之前对数据的不了解,导致整个过程都不知道在算什么,因此专门总结了一下关于张量的理解和使用。
内容包括:张量数据形式、张量运算、numpy数据运算、numpy数据求平均值和标准差、numpy数据标准化
数据形式:张量
在进行深度学习的编程中,训练集、测试集或者标签,常见的数据形式是张量。
张量:具有维度的数据容器。
0D张量:即单独一个数字,是一个标量。
1D张量:数组数据,每个元素是一个标量数字。
2D张量:列表数据,每个元素是一个数组。
3D张量:列表数据,每个元素是一个2D张量。
-
Python中张量的属性:
- ndim:维度
- dtype:数据类型,是指每个标量数字的
- shape:形状,返回的值是(最外层元素个数,下一层元素个数,再下一层的元素个数,… , 最终1D张量的元素个数)
例如:
import numpy as np m = np.array([[[1,2,3,6,7],[1,2,3,6,7],[0,0,0,6,7]], [[3,5,7,6,7],[9,27,39,6,7],[60,0,0,6,7]], [[3,5,7,6,7],[9,27,39,6,7],[60,0,0,6,7]], [[3,5,7,6,7],[9,27,39,6,7],[60,0,0,6,7]]]) print(m.shape, m.dtype, m.ndim) ### 得到结果如下 ### (4, 3, 5) int32 3
-
Python中张量运算
-
使用Python模块Numpy,Numpy提供的常见模块功能如下:
array:构建多维数组;
zeros:构建全部元素为0的多维数组
ones:构建全部元素为1的多维数组
asarray:将不同维度的数组转化为numpy所可以进行运算的数组
d=[1,2,3,4,5] d2=np.asarray(d) print(d, d2) ### 得到结果如下 ### [1, 2, 3, 4, 5] [1 2 3 4 5] ### 可见,list数据与numpy的array数据是不同的
-
张量的批处理:
对于numpy的assay数据,可以对其多维度进行分片:
m = np.array([[[1,2,3,6,7],[1,2,3,6,7],[0,0,0,6,7]], [[3,5,7,6,7],[9,27,39,6,7],[60,0,0,6,7]], [[3,5,7,6,7],[9,27,39,6,7],[60,0,0,6,7]], [[3,5,7,6,7],[9,27,39,6,7],[60,0,0,6,7]]]) print(m[1:4,:,:3]) ### 所得结果如下: [[[ 3 5 7] [ 9 27 39] [60 0 0]] [[ 3 5 7] [ 9 27 39] [60 0 0]] [[ 3 5 7] [ 9 27 39] [60 0 0]]] print(m[:,:,:3]) ### 所得结果如下: [[[ 1 2 3] [ 1 2 3] [ 0 0 0]] [[ 3 5 7] [ 9 27 39] [60 0 0]] [[ 3 5 7] [ 9 27 39] [60 0 0]] [[ 3 5 7] [ 9 27 39] [60 0 0]]]
可见该分片操作选取相应维度指定a:b,保留的a到b-1元素。
-
张量的变形:
对于numpy的assay数据,可以使用reshape方法进行张量的变形:
print(m.reshape([4,15])) # 或者表示为 print(m.reshape([m.shape[0],m.shape[1]*m.shape[2]])) ### 所得结果如下: [[ 1 2 3 6 7 1 2 3 6 7 0 0 0 6 7] [ 3 5 7 6 7 9 27 39 6 7 60 0 0 6 7] [ 3 5 7 6 7 9 27 39 6 7 60 0 0 6 7] [ 3 5 7 6 7 9 27 39 6 7 60 0 0 6 7]]
-
张量运算:
逐元素加减:必须对拥有相同的shape的numpy的array数据进行使用,直接用加号运算。(使用减号同理)。
逐元素相乘:使用乘法符号*进行运算。
点积(矩阵乘法):使用numpy的dot方法。
a2 = np.array([[2,2,2,2,2],[2,2,2,2,2]]) ax = np.array([[1,1],[1,1],[1,1],[1,1],[1,1]]) a3 = np.dot(a2,ax) print(a3) ### 结果如下: [[10 10] [10 10]]
-
Numpy数据运算
-
每个元素同时加减乘除x:
直接对numpy格式数据与相应的数字x进行加减乘除。代码如下:
import numpy as np data = np.array([[1,2,3],[4,5,6]]) print(data+3) # 得到[[4 6 6] [7 8 9]] print(data-3) # 得到[[-2 -1 0] [1 2 3]] print(data*3) # 得到[[3 6 9] [12 15 18]]
-
二维数据与一维数据之间的运算:
二维numpy数组与一维numpy数据直接进行加减乘除,也是逐元素运算。是二维数据每一个行向量与一维数据对应进行逐元素运算。
注意二维数组的列数与一维数组的长度要相同。
代码如下:
import numpy as np data_2d = np.array([[1,2,3,4,5],[0,0,0,0,0],[1,1,1,1,1]]) data_1d = np.array([2,10,4,6,8]) print(data_2d+data_1d) # 所得结果为:[[ 3 12 7 10 13] [ 2 10 4 6 8] [ 3 11 5 7 9]] print(data_2d-data_1d) # 所得结果为:[[ -1 -8 -1 -2 -3] [ -2 -10 -4 -6 -8] [ -1 -9 -3 -5 -7]] print(data_2d*data_1d) # 所得结果为:[[ 2 20 12 24 40] [ 0 0 0 0 0] [ 2 10 4 6 8]]
运算所得结果仍然是一个二维numpy数组。
同理,三维的numpy数组与二维numpy数组、一维numpy数组之间也存在这样的运算关系。
-
数据求平均值
numpy数据对象的mean方法返回该组数据的平均值:
import numpy as np data1 = np.array([1,2,3,4,5]) data2 = np.array([[1,2,3],[4,5,6]]) print(data1.mean(axis=0)) # 得到结果为:3, 即(1+2+3+4+5)/5=3 print(data2.mean(axis=0)) # 得到结果为:[2.5 3.5 4.5], 即(1+4)/2=2.5、(2+5)/2=3.5、(3+6)/2=4.5
其中axis参数是用于指定对那一个维度求解平均值。
常见的是二维数据和三维数据:
-
对于二维数据axis=0时mean为:分别对每一列数据求和并求出每一列数据的平均值。所得为一行行向量,没列元素是原数据对应列的平均值。
-
对于三维数据axis=0时mean为:分别对每个二维数据求和。例如一组图片[100,10,10]共有100张每张10 * 10象素,此时求出结果为一个10 * 10的数组,即这100张图片每张图片对应象素点的平均值图片。
理解axis参数:axis就是指定待求平均值数据的维度,即沿着该维度求和,对于二维数组,axis=0就是列。对于三维数据,axis=0就是表示批量那个维度。可见axis=0是该数据的最外围的那一个维度。
-
-
数据求标准差
numpy数据对象的std方法返回该数据的标准差:
import numpy as np data1 = np.array([1,2,3,4,5]) data2 = np.array([[1,2,3],[4,5,6]]) print(data1.std(axis=0)) # 得到结果为:1.4142135623730951 print(data2.std(axis=0)) # 得到结果为:[1.5 1.5 1.5]
同理,axis用于指定,选取那一维度的数据,用于求标准差。比如在这里data2.std(axis=0)就表示按照列选取数据计算计算标准差,于是计算了[1,4]、[2,5]、[3,6]这三组数据的标准差,得到一个行向量,每一列的元素就是对应那一列的数据的标准差。
标准差计算公式:
σ = ∑ i = 1 m ( x i − x ˉ ) 2 m \sigma = \sqrt{\frac{\sum^m_{i=1}(x_i-\bar x)^2}{m}} σ=m∑i=1m(xi−xˉ)2
注意此方法计算的是总体标准差,不是样本标准差(样本标准差分母是m-1)。 -
数据标准化
对于以numpy数据形式表示的 样本数据 ,经常会需要对数据进行标准化。
按照普遍的经验,将取值范围差异很大的数据输入到神经网络,往往训练出来的测试效果非常不理想。
数据标准化:对输入数据的每个特征(通常:每一行代表一个样本,每个样本每一列代表一个特征),减去特征平均值,再除以标准差,得到特征平均值为0,标准差为1的数据。
实现方法:原数据减去平均值,除以标准差。
代码如下:
import numpy as np train_dtat = np.array([ [1,15,200,7,5], [9,88,101,5,33], [17,50,144,13,12] ]) mean = train_data.mean(axis=0) train_data = train_data - mean std = train_data.std(axis=0) train_data = train_data/std
Thanks!
PS: 毕竟,霜星酱水平有限,如果发现任何错误还请及时邮箱告知我,我会去改哦!
101,5,33],
[17,50,144,13,12]
])
mean = train_data.mean(axis=0)
train_data = train_data - mean
std = train_data.std(axis=0)
train_data = train_data/std
Thanks!
PS: 毕竟,霜星酱水平有限,如果发现任何错误还请及时邮箱告知我,我会去改哦!