欢迎关注 “小白玩转Python”,发现更多 “有趣”
NumPy 或 Numeric Python 是一个开放源码的 Python 库,它使复杂的数值操作变得容易。与机器学习和深度学习应用工作涉及复杂的数字操作与大量的数据集。与纯 Python 实现相比,NumPy 使得实现这些操作相对简单和有效。
从核心上说,NumPy 实现了Python(n 维数组)数据结构,类似于常规的 Python 列表。大多数编程语言只有数组的概念。Python 实现了列表,它作为数组工作,但是有区别。
常规 Python 列表和 NumPy 的一个关键区别是,Python 列表可以包含各种数据类型。相反,NumPy 数组只能包含相同数据类型的对象。换句话说,数据结构是同构的。虽然这看起来似乎是一个负面因素,但它允许 NumPy 操作更快,因为它们在进行计算时可以避免转换和约束。
你为什么要关心 NumPy,为什么特别关心深度学习?
在本文中,我将介绍几个特定的用例,但是与其他 Python 数据结构相比,NumPy 最重要的特性之一是速度。比使用常规的 Python 列表数量级更快。由于 NumPy 函数是在 C 中实现的,除了使执行速度更快,还使 NumPy 能够分解大型作业并并行执行多个作业。深度学习涉及处理大型数据集,当处理大型数据集时,NumPy 数组是一种有效的技术。
创建 NumPy 数组
有几种不同的方法可以创建 NumPy 数组,一种简单的方法是使用 array()函数创建它们。
#import NumPy
import numpy as np
#create a NumPy array
a = np.array([1,2,3])
#check the shape of the array
a.shape
#get the dimensions
a.dim
此外,您可以直接从标准的 Python 列表创建。Numpy 数组是智能的。如果将 Python 列表传递给 array()函数,它将自动执行操作并返回 Numpy 数组。您不需要首先显式地转换为 NumPy 数组。
#python List
my_list = [1,2,3,4,5]
#creating a NumPy array from a list
np.array(my_list)
还可以使用 Pandas 的函数.to_numpy()将 Pandas DataFrame 转换为 NumPy 数组
#import Pandas
import pandas as pd
#create a DataFrame
df = pd.DataFrame({"A":[1, 2],"B":[3, 4]})
#convert DataFrame to NumPy array
df.to_numpy()
需要注意的是,由于 NumPy 数组只能包含相同数据类型的元素。默认情况下,在转换 DataFrame 时,返回数组的 dtype 将是 DataFrame 中所有类型的公共 dtype。
NumPy Loves Math
NumPy 数组专门用于处理数学问题。这个库包含了一些数学辅助函数,这些函数可以让你在不需要自己快速写入的情况下完成这些计算。
比较流行的例子包括 sqrt()函数用于求平方根,log()函数用于计算 log,tanh()函数用于计算双曲正切,通常用于深层神经网络中的激活函数。
a = np.array([1,2,3])
#get the square root
np.sqrt(a)
#get log
np.log(a)
#find the tanh
np.tanh(a)
线性代数
NumPy 的 linalg 子模块中有几个内置的线性代数算法可供使用。
一个常用的线性代数函数是 norm() ,一个用来计算向量长度的函数,也称为向量范数或向量大小。在机器学习和深度学习应用中,向量范数作为一种规范化技术被用来解决过度填充问题。NumPy 的 linalg 子模块具有计算向量范数的 norm()函数。
a = np.array([1,2,3])
#getting a norm of the vector
np.linalg.norm(a)
在学习线性代数时,经常会遇到数学上的错误。有些数学运算是不允许的。处理这些错误的一个优雅的方法是使用 linalg.LinAlgError 异常处理,一个从 Python 的异常类派生的通用异常类。
例如,如果我们尝试对一个奇异的矩阵求逆,这个操作是不允许的,并抛出一个错误。
x=np.ones((2,2))
np.linalg.inv(x) #this will throw an error
#exception handling using LinAlgError
try:
np.linalg.inv(x)
except np.linalg.LinAlgError:
print("Linear Algebra Error")
这些线性代数函数可以计算多个矩阵的结果,如果它们堆放在同一个数组上。
广播
NumPy 进行算术计算的基本特征之一是通过广播。广播允许不同形状和大小的 NumPy 数组之间进行操作。
广播是通过比较数组的维度来工作的,广播的有效性主要有两个规则。
维度相等,或者
其中一个维度是1
在 NumPy 中执行元素级操作(如向 np.array 添加标量)时,实际上是在进行广播。
x = np.ones((2,2))
y = np.ones((3,2,1))
a = np.ones((2,3,3))
x+y #Broadcasting will work; trailing dimensions match
x+a #Broadcasting will fail; trailing dimensions do not match
y = np.ones((3,2,1))
NumPy 和 Matrices
NumPy 的真正潜力来自与矩阵相关的工作。Numpy 支持各种易于使用的方法,用于执行标准矩阵操作,如点乘、转置、获得对角线等。
特别是计算度量的点积矩阵乘法,是深度学习中的一项常见任务,尤其是在处理卷积神经网络时。NumPy 函数 dot()计算两个度量的点积。在 NumPy 的后续版本中,还可以使用@运算符计算点积。
x = np.array([[1,2],[3,4]])
y = np.array([[5,6],[7,8]])
#dot product with dot()
x.dot(y)
#dot product with @
x@y
深度学习中接下来两个常用的矩阵运算是逆矩阵和转置矩阵。
让我们先来看一下求逆。什么是求逆?一个数乘以它的倒数等于1。重要的是要记住,并不是所有的矩阵都有一个逆矩阵,在这种情况下,你会得到一个错误。可以使用 linalg.inv()函数得到矩阵的逆。
x = np.array([[1, 2], [3, 4]])
#getting the inverse
np.linalg.inv(x)
矩阵的转置是一个将矩阵翻转过其对角线的算子。也就是说,它切换矩阵的行和列索引。在 NumPy 中,您可以得到带有 T 的矩阵的转置。
x = np.array([[1, 2], [3, 4]])
#getting the transpose
x.T
在深度学习中,特征矢量在实现降维方法时非常有用,比如主成分分析方法(PCA)。
可以使用 linalg.eignvals()函数计算向量或矩阵的特征值。
x = np.array([[1, 2], [3, 4]])
#getting the eigenvectors
np.linalg.eigvals(x)
在处理矩阵时,必须记住不要使用 NumPy 类中的矩阵函数,而是使用规则数组。
改变形状
在使用深度学习时,您经常会遇到需要更改数组或矩阵形状的情况。可以使用 reshape()函数重新定义 NumPy 数组的形状。该函数返回具有新形状的新 NumPy 数组。
x = np.array([[1, 2], [3, 4]])
#Reshape 2X2 to 4X1
x.reshape(4,1)
如果需要更改原始 NumPy 数组的形状,可以使用 resize()函数。它的工作方式类似于 reshape()函数,但是更改原始对象而不是创建新对象。
x = np.array([[1, 2], [3, 4]]
#Resize the original array 2X2 to 4X1
x.resize(4,1)
Flattening 是另一个标准的深度学习操作,用于将数据或输入传递到神经网络的不同层。NumPy 的 flatten()函数将展开一个 ndarray。
x = np.array([[1, 2], [3, 4]]
#flatten the array
x.flatten()
除了使用 flatten()之外,还可以使用 ravel()方法来做同样的事情。flatten()和 ravel()之间的区别是,ravel()可以直接与常规列表一起使用,并返回 NumPy 数组。
x_list = [[1, 2],[3, 4]]
#flatten a list
np.ravel(x_list)
改形的一种形式是向数组添加一个新维度。例如,您可以通过添加带有关键字的新维度 newaxis。
y = np.array([1,2,3,4,5])
#add a new dimension
y[:,np.newaxis]
另一种重塑 NumPy 数组的方法是使用函数拆分它。该函数接受并返回基于指定索引或部分的子数组。
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8])
#split array into 3 ps
np.split(x,3)
用 NumPy 生成数据
NumPy 为数值操作提供了一个强大的工具包; 然而,NumPy 也可以生成数据。
单位矩阵是一个任意阶的正方形矩阵,其中1是主对角线,0是所有其他位置的数据。NumPy 函数创建指定顺序的单位矩阵。
#generate a identity matrix 5
np.identity(5)
在深度学习中,你会遇到需要一个0 & 1矩阵的情况。NumPy 有方便创建该矩阵的函数 zeros()和 ones() ,您可以使用它们来生成全 0 或全 1 矩阵。
#generate a 2X3 matrix of 0s
np.zeros((2,3))
#generate a 2X3 matrix of 1s
np.ones((2,3))
使用 NumPy 的 random.rand()函数,可以创建由随机数元素组成的指定顺序的数组。
#generate a 2X3 matrix of random numbers
np.random.rand(2,3)
#generate a 2X3 matrix of random integers
np.random.randint(2,3)
注意,如果您想要随机整数,可以使用 random.randint()函数来获得一个带有随机整数的 NumPy 数组。
上面讨论的数据生成方法可以与它们的 _like 方法一起使用,比如类似于zeros_like,ones_like 生成数组,它采用作为参数传递给函数的数组的形状。
x = np.array([[1, 2],[3, 4]])
#generate a matrix of 1s based on dimensions of x
np.ones_like(x)
换句话说,当使用函数的 _like 时,我们不指定形状,而是传递一个现有的 NumPy 数组。生成的 NumPy 数组采用传递的数组的形状。
总结性思考
在这篇文章中,我介绍了所有开始深度学习所必要的 NumPy 知识。NumPy 的内容比这里介绍的要多,但是我们在这里介绍的内容应该足以开始在您的深度学习项目中使用 NumPy。当你开始深度学习项目的工作时,你会遇到需要你使用额外技术和学习更多的情况。
· END ·
HAPPY LIFE