网站开发软件三剑客,关于网站建设的好处,自己搭建视频播放网站,网站网页宽度多少合适目录 一、前言二、数组变形2.1 更改数组的形状2.1.1 reshape2.1.2 resize2.1.3 T(转置)2.1.4 ravel2.1.5 flatten2.1.6 squeeze2.1.7 transpose 2.2 合并数组2.2.1 append2.1.2 concatenate2.1.3 stack 三、批量处理四、通用函数4.1 math 与 numpy 函数的性能比较4.2 循环与向量… 目录 一、前言二、数组变形2.1 更改数组的形状2.1.1 reshape2.1.2 resize2.1.3 T(转置)2.1.4 ravel2.1.5 flatten2.1.6 squeeze2.1.7 transpose 2.2 合并数组2.2.1 append2.1.2 concatenate2.1.3 stack 三、批量处理四、通用函数4.1 math 与 numpy 函数的性能比较4.2 循环与向量运算比较 五、广播机制六、小结 PyTorch是一个开源的Python机器学习库基于Torch用于自然语言处理等应用程序 一、前言 本文为PyTorch深度学习中[Numpy基础]的下篇主要讲解数组变形、批量处理、通用函数和广播机制的相关知识。 上期回顾 深度学习入门PyTorch深度学习——Numpy基础 (上) 二、数组变形 在机器学习以及深度学习的任务中通常需要将处理好的数据以模型能接收的格式输入给模型然后由模型通过一系列的运算最终返回一个处理结果。 然而由于不同模型所接收的输人格式不一样往往需要先对其进行一系列的变形和运算从而将数据处理成符合模型要求的格式。在矩阵或者数组的运算中经常会遇到需要 把多个向量或矩阵按某轴方向合并或展平(如在卷积或循环神经网络中在全连接层之前需要把矩阵展平) 的情况。 下面介绍几种常用的数据变形方法。
2.1 更改数组的形状 修改指定数组的形状是Numpy中最常见的操作之一常见的方法有很多下表列出了一些常用函数。
函数描述arr.reshape重新将向量arr维度进行改变不修改向量本身arr.resize重新将向量arr 维度进行改变修改向量本身arr.T对向量arr进行转置arr.ravel对向量arr进行展平即将多维数组变成1维数组不会产生原数组的副本arr.flatten对向量arr进行展平即将多维数组变成1维数组返回原数组的副本arr.squeeze只能对维数为1的维度降维。对多维数组使用时不会报错但是不会产生任何影响arr.transpose对高维矩阵进行轴对换 下面我们来看一些实例。
2.1.1 reshape 改变向量的维度(不修改向量本身)
import numpy as np
arr -np.arange(10)
print(arr)
#将向量arr维度变换为2行5列print(arr.reshape(2,5))
#指定维度时可以只指定行数或列数其他用-1代替
print(arr.reshape(5,-1))
print(arr.reshape(-1,5))输出结果
[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 1][2 3][4 5][6 7][8 9]]
[[0 1 2 3 4][5 6 7 8 9]]值得注意的是reshape函数不支持指定行数或列数所以 -1在这里是必要的 。且所指定的行数或列数一定要能被整除例如上面代码如果修改为arr.reshape(3,-1)即为错误的。 2.1.2 resize 改变向量的维度(修改向量本身)
import numpy as np
arrnp.arange(10)
print(arr)
#将向量arr维度变换为2行5列arr.resize(2,5)
print(arr)输出结果
[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4][5 6 7 8 9]]2.1.3 T(转置) 向量转置
import numpy as np
arrnp.arange(12).reshape(3,4)
#向量arr为3行4列
print(arr)
#将向量arr进行转置为4行3列
print(arr.T)输出结果
[[0 1 2 3][4 5 6 7][8 9 10 11]]
[[0 4 8][1 5 9][2 6 10][3 7 11]]2.1.4 ravel 向量展平
import numpy as np
arrnp.arange(6).reshape(2,-l)
print(arr)
# 并按照列优先展平
print(按照列优先,展平)
print (arr.ravel(F))
# 按照行优先展平
print(按照行优先展平)
print(arr.ravel())输出结果:
[0 1 2 3 4 5]
# 按照列优先展平
[ 0 3 1 4 2 5]
# 按照行优先展平
[0 1 2 3 4 5]2.1.5 flatten 把矩阵转换为向量这种需求经常出现在卷积网络与全连接层之间。
import numpy as np
anp.floor(10*np.random.random((3,4)))
print(a)
print(a.flatten())输出结果
[[4. 0. 8. 5.][1. 0. 4. 8.][8. 2. 3. 7.]]
[4. 0. 8. 5. 1. 0. 4. 8. 8. 2. 3. 7.]2.1.6 squeeze 这是个主要用来降维的函数把矩阵中含1的维度去掉。在PyTorch中还有一种与之相反的操作———torch.unsqueeze这个后面再来介绍。
arrnp.arange(3).reshape(3,1)
print(arr.shape) #(3,1)
print(arr.squeeze().shape) #(3,)
arr1np.arange(6).reshape(3,1,2,1)
print(arrl.shape) #(3,1,2,1)
print(arr1.squeeze().shape) #(3,2)2.1.7 transpose 对高维矩阵进行轴对换这个在深度学习中经常使用比如把图片中表示颜色顺序的RGB改为GBR。
import numpy as np
arr2np.arange(24).reshape(2,3,4)
print(arr2.shape) #(2,3,4)
print(arr2.transpose(1,2,0).shape) #(3,4,2)2.2 合并数组 合并数组也是最常见的操作之一下表列举了常见的用于数组或向量合并的方法。
函数描述np.append内存占用大np.concatenate没有内存问题np.stack沿着新的轴加入一系列数组np.hstack堆栈数组垂直顺序(行)np.vstack堆栈数组垂直顺序(列)np.dstack堆栈数组按顺序深入沿第3维)np.vsplit将数组分解成垂直的多个子数组的列表 说明 1append、concatenate 以及 stack 都有一个 axis参数用于控制数组的合并方式是按行还是按列。 2对于append和 concatenate待合并的数组必须有相同的行数或列数(满足一个即可)。 3stack 、hstack 、 dstack 要求待合并的数组必须具有相同的形状(shape)。下面选择一些常用函数进行说明。
2.2.1 append 合并一维数组
import numpy as np
anp.array([1,2,3])
bnp.array([4,5,6])
cnp.append(a,b)
print(c)
#[1 2 3 4 5 6]合并多维数组
import numpy as np
anp.arange(4).reshape(2,2)
bnp.arange(4).reshape(2,2)
# 按行合并
cnp.append(a,b,axis0)
print(按行合并后的结果)
print(c)
print(合并后数据维度,c.shape) # 按列合并
dnp.append(a,b,axisl)
print(按列合并后的结果)
print(d)
print(合并后数据维度,d.shape)输出结果
按行合并后的结果
[[0 1][2 3][0 1][2 3]]
合并后数据维度 (4,2)
按列合并后的结果
[[0 1 0 1][2 3 2 3]]
合并后数据维度 (2,4)2.1.2 concatenate 沿指定轴链接数组或矩阵
import numpy as np
anp.array([[1,2],[3,4]])
bnp.array([[5,6]])
cnp.concatenate((a,b),axis0)
print(c)
dnp.concatenate((a,b.T),axis1)
print(d)输出结果
[[12][3 4][5 6]]
[[1 2 5][3 4 6]]2.1.3 stack 沿指定轴堆叠数组或矩阵
import numpy as np
anp.array([[1, 2],[3, 4]])
bnp.array([[5, 6],[7, 8]])
print(np.stack((a,b),axis0))输出结果
[[[1 2][3 4]][[5 6][7 8]]]三、批量处理 在深度学习中由于源数据都比较大所以通常需要用到批处理。如利用批量来计算梯度的随机梯度法(SGD)就是一个典型应用。深度学习的计算一般比较复杂并且数据量一般比较大如果一次处理整个数据较大概率会出现资源瓶颈。 为了更有效地计算一般将整个数据集分批次处理。与处理整个数据集相反的另一个极端是每次只处理一条记录。这种方法也不科学一次处理一条记录无法充分发挥GPU、Numpy的平行处理优势。 因此在实际使用中往往采用批量处理(Mini-Batch)的方法。 如何把大数据拆分成多个批次呢 可采用如下步骤: 1得到数据集 2随机打乱数据 3定义批大小 4批处理数据集 下面我们通过一个示例来具体说明:
import numpy as np
# 生成10000个形状为2x3的矩阵
data_trainnp.random.randn(10000,2,3)
#这是一个3维矩阵第1个维度为样本数后两个是数据形状print(data_train.shape)
# (10000,2,3)
# 打乱这10000条数据
np.random.shuffle(data_train)
# 定义批量大小
batch_size100
# 进行批处理
for i in range(0,len(data_train),batch_size):x_batch_sumnp.sum(data_train[i:ibatch_size])print(第{}批次该批次的数据之和:(}.format(i,x_batch_sum))最后5行结果
第9500批次该批次的数据之和:17.63702580438092
第9600批次该批次的数据之和:-1.360924607368387
第9700批次该批次的数据之和:-25.912226239266445
第9800批次该批次的数据之和:32.018136957835814
第9900批次该批次的数据之和:2.9002576614446935【说明】批次从0开始所以最后一个批次是9900。 四、通用函数 Numpy提供了两种基本的对象即 ndarray 和 ufunc 对象。前文已经介绍了ndarray本节将介绍Numpy的另一个对象通用函数(ufunc)。 ufunc是universal function的缩写它是一种能对数组的每个元素进行操作的函数。许多ufunc函数都是用C语言级别实现的,因此它们的计算速度非常快。此外它们比 math 模块中的函数更灵活。 math模块的输入一般是标量但Numpy中的函数可以是向量或矩阵而利用向量或矩阵可以避免使用循环语句这点在机器学习、深度学习中非常重要。 下表为Numpy中常用的几个通用函数。
函数使用方法sqrt计算序列化数据的平方根sin,cos三角函数abs计算序列化数据的绝对值dot矩阵运算log,log10,log2对数函数exp指数函数cumsum,cumproduct累计求和、求积sum对一个序列化数据进行求和mean计算均值median计算中位数std计算标准差var计算方差corrcoef计算相关系数
4.1 math 与 numpy 函数的性能比较
import time
import math
import numpy as npx[i * 0.001 for i in np.arange (1000000)]
starttime.clock()
for i,t in enumerate(x):
x[i]math.sin(t)
print(math.sin:,time.clock()-start)x[i*0.001 for i in np.arange (1000000)]np.array(x)
starttime.clock()np.sin(x)
print(numpy.sin:,time.clock()-start)打印结果
math.sin:0.5169950000000005
numpy.sin:0.053811999999998864.2 循环与向量运算比较 充分使用Python的 Numpy库中的内建函数(Built-in Function)来实现计算的向量化可大大地提高运行速度。Numpy库中的内建函数使用了SIMD指令。如下使用的向量化要比使用循环计算速度快得多。如果使用GPU其性能将更强大不过Numpy不支持GPU… PyTorch支持GPU后面有机会将介绍PyTorch 如何使用GPU来加速算法。
import time
import numpy as np
x1np.random.rand(1000000)
x2np.random.rand(1000000)
# 使用循环计算向量点积
tictime.process_time()
dot0
for i in range(len(xl)):dotx1[i]*x2[i]
toctime.process_time()
print(dotstr(dot)\n for loop----- Computation time str(1000*(toc-tic))ms )
# 使用numpy函数求点积
tictime.process_time()
dot0
dotnp.dot(x1,x2)
toctime.process_time()
print(dotstr(dot)\n verctor version---- Computation time str(1000*(toc-tic))ms)输出结果
dot250215.601995for loop----- Computation time798.3389819999998 msdot250215.601995
verctor version---- Computation time1.885051999999554 ms从运行结果上来看使用for 循环的运行时间大约是向量运算的400倍。因此在深度学习算法中一般都使用向量化矩阵进行运算。 五、广播机制 Numpy 的 Universal functions 中要求输人的数组shape是一致的当数组的shape不相等时则会使用广播机制。不过调整数组使得shape一样需要满足一定的规则否则将出错。这些规则可归纳为以下4条。 1让所有输入数组都向其中 shape最长的数组看齐不足的部分则通过在前面加1补齐如: a: 2×3×2 b:3×2 则b向a看齐在b的前面加1变为:1×3×2 2输出数组的shape是输入数组shape的各个轴上的最大值 3如果输人数组的某个轴和输出数组的对应轴的长度相同或者某个轴的长度为1时这个数组能被用来计算否则出错 4当输入数组的某个轴的长度为1时沿着此轴运算时都用(或复制)此轴上的第一组值。 广播在整个Numpy中用于决定如何处理形状迥异的数组涉及的算术运算包括(,-,*,/…)。这些规则说得很严谨但不直观下面我们结合图形与代码来进一步说明。 目的:AB其中A为4×1矩阵,B为一维向量 3,)。 要相加需要做如下处理: 根据规则1B需要向看齐,把B变为(1,3 ) 根据规则2输出的结果为各个轴上的最大值即输出结果应该为4,3矩阵那么A如何由4,1变为(4,3矩阵B又如何由1,3变为(4,3矩阵? 根据规则4用此轴上的第一组值(要主要区分是哪个轴)进行复制(但在实际处理中不是真正复制否则太耗内存而是采用其他对象如ogrid对象进行网格处理)即可,详细处理过程如下图所示。 代码实现
import numpy as np
Anp.arange(0,40,10).reshape(4,1)
Bnp.arange(0,3)
print(A矩阵的形状:{},B矩阵的形状:{},format(A.shape,B.shape))
CAB
print(c矩阵的形状:{}.format(C.shape))
print(C)运行结果
A矩阵的形状:(4,1)B矩阵的形状:(3,)
c矩阵的形状:(4,3)
[[0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]六、小结 本章主要介绍了Numpy模块的常用操作尤其涉及对矩阵的操作这些操作在后续程序中经常使用。Numpy内容很丰富这里只列了一些主要内容如果你想了解更多内容可登录Numpy的官网(http://www.Numpy.org/)查看更多内容。 最近在学习深度学习的优化算法不知道大家想最先看哪一个…请在下方投个票吧