赞
踩
线性代数(如矩阵乘法、矩阵分解、行列式以及其他方阵数学等)是任何数组库的重要组成部分,NumPy中实现了线性代数中常用的各种操作,并形成了numpy.linalg线性代数相关的模块。本节主要介绍如下函数:
diag
:以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0)。dot
:矩阵乘法。trace
:计算对角线元素的和。det
:计算矩阵行列式。eig
:计算方阵的特征值和特征向量。inv
:计算方阵的逆。In [130]
- # 矩阵相乘
- a = np.arange(12)
- b = a.reshape([3, 4])
- c = a.reshape([4, 3])
- # 矩阵b的第二维大小,必须等于矩阵c的第一维大小
- d = b.dot(c) # 等价于 np.dot(b, c)
- print('a: \n{}'.format(a))
- print('b: \n{}'.format(b))
- print('c: \n{}'.format(c))
- print('d: \n{}'.format(d))
a:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
b:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
c:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
d:
[[ 42 48 54]
[114 136 158]
[186 224 262]]
In [131]
- # numpy.linalg 中有一组标准的矩阵分解运算以及诸如求逆和行列式之类的东西
- # np.linalg.diag 以一维数组的形式返回方阵的对角线(或非对角线)元素,
- # 或将一维数组转换为方阵(非对角线元素为0)
- e = np.diag(d)
- f = np.diag(e)
- print('d: \n{}'.format(d))
- print('e: \n{}'.format(e))
- print('f: \n{}'.format(f))
d:
[[ 42 48 54]
[114 136 158]
[186 224 262]]
e:
[ 42 136 262]
f:
[[ 42 0 0]
[ 0 136 0]
[ 0 0 262]]
In [132]
- # trace, 计算对角线元素的和
- g = np.trace(d)
- g
In [133]
- # det,计算行列式
- h = np.linalg.det(d)
- h
1.3642420526593978e-11
In [134]
- # eig,计算特征值和特征向量
- i = np.linalg.eig(d)
- i
(array([ 4.36702561e+02, 3.29743887e+00, -2.00728619e-14]),
array([[ 0.17716392, 0.77712552, 0.40824829],
[ 0.5095763 , 0.07620532, -0.81649658],
[ 0.84198868, -0.62471488, 0.40824829]]))
In [135]
- # inv,计算方阵的逆
- tmp = np.random.rand(3, 3)
- j = np.linalg.inv(tmp)
- j
array([[ -5.81993172, 15.83159278, -11.18756558],
[ 3.67058369, -6.46065502, 4.50665723],
[ 2.11102657, -5.91510414, 5.31932688]])
NumPy可以方便的进行文件读写,如下面这种格式的文本文件:
In [4]
- # 使用np.fromfile从文本文件'housing.data'读入数据
- # 这里要设置参数sep = ' ',表示使用空白字符来分隔数据
- # 空格或者回车都属于空白字符,读入的数据被转化成1维数组
- d = np.fromfile('./work/housing.data', sep = ' ')
- d
array([6.320e-03, 1.800e+01, 2.310e+00, ..., 3.969e+02, 7.880e+00,
1.190e+01])
NumPy提供了save
和load
接口,直接将数组保存成文件(保存为.npy格式),或者从.npy文件中读取数组。
In [137]
- # 产生随机数组a
- a = np.random.rand(3,3)
- np.save('a.npy', a)
-
- # 从磁盘文件'a.npy'读入数组
- b = np.load('a.npy')
-
- # 检查a和b的数值是否一样
- check = (a == b).all()
- check
使用ndarray数组可以很方便的构建数学函数,并利用其底层的矢量计算能力快速实现计算。下面以神经网络中比较常用激活函数Sigmoid和ReLU为例,使用Numpy计算激活函数Sigmoid和ReLU的值,并使用matplotlib画出图形,代码实现如下。
In [138]
- # ReLU和Sigmoid激活函数示意图
- import numpy as np
- %matplotlib inline
- import matplotlib.pyplot as plt
- import matplotlib.patches as patches
-
- #设置图片大小
- plt.figure(figsize=(8, 3))
-
- # x是1维数组,数组大小是从-10. 到10.的实数,每隔0.1取一个点
- x = np.arange(-10, 10, 0.1)
- # 计算 Sigmoid函数
- s = 1.0 / (1 + np.exp(- x))
-
- # 计算ReLU函数
- y = np.clip(x, a_min = 0., a_max = None)
-
- #########################################################
- # 以下部分为画图程序
-
- # 设置两个子图窗口,将Sigmoid的函数图像画在左边
- f = plt.subplot(121)
- # 画出函数曲线
- plt.plot(x, s, color='r')
- # 添加文字说明
- plt.text(-5., 0.9, r'$y=\sigma(x)$', fontsize=13)
- # 设置坐标轴格式
- currentAxis=plt.gca()
- currentAxis.xaxis.set_label_text('x', fontsize=15)
- currentAxis.yaxis.set_label_text('y', fontsize=15)
-
- # 将ReLU的函数图像画在右边
- f = plt.subplot(122)
- # 画出函数曲线
- plt.plot(x, y, color='g')
- # 添加文字说明
- plt.text(-3.0, 9, r'$y=ReLU(x)$', fontsize=13)
- # 设置坐标轴格式
- currentAxis=plt.gca()
- currentAxis.xaxis.set_label_text('x', fontsize=15)
- currentAxis.yaxis.set_label_text('y', fontsize=15)
-
- plt.show()
<Figure size 576x216 with 2 Axes>
图片是由像素点构成的矩阵,其数值可以用ndarray来表示。将上述介绍的操作用在图像数据对应的ndarray上,可以很轻松的实现图片的翻转、裁剪和亮度调整,代码实现如下。
In [1]
- # 导入需要的包
- import numpy as np
- import matplotlib.pyplot as plt
- from PIL import Image
-
- # 读入图片
- image = Image.open('./work/pic1.jpg')
- image = np.array(image)
- # 查看数据形状,其形状是[H, W, 3],
- # 其中H代表高度, W是宽度,3代表RGB三个通道
- image.shape
(404, 640, 3)
In [2]
- # 原始图片
- plt.imshow(image)
<matplotlib.image.AxesImage at 0x7f0a345583d0>
<Figure size 640x480 with 1 Axes>
In [3]
- # 垂直方向翻转
- # 这里使用数组切片的方式来完成,
- # 相当于将图片最后一行挪到第一行,
- # 倒数第二行挪到第二行,...,
- # 第一行挪到倒数第一行
- # 对于行指标,使用::-1来表示切片,
- # 负数步长表示以最后一个元素为起点,向左走寻找下一个点
- # 对于列指标和RGB通道,仅使用:表示该维度不改变
- image2 = image[::-1, :, :]
- plt.imshow(image2)
<matplotlib.image.AxesImage at 0x7f0a3448c810>
<Figure size 640x480 with 1 Axes>
In [4]
- # 水平方向翻转
- image3 = image[:, ::-1, :]
- plt.imshow(image3)
<matplotlib.image.AxesImage at 0x7f0a34480690>
<Figure size 640x480 with 1 Axes>
- # 保存图片
- im3 = Image.fromarray(image3)
- im3.save('im3.jpg')
- # 高度方向裁剪
- H, W = image.shape[0], image.shape[1]
- # 注意此处用整除,H_start必须为整数
- H1 = H // 2
- H2 = H
- image4 = image[H1:H2, :, :]
- plt.imshow(image4)
- # 宽度方向裁剪
- W1 = W//6
- W2 = W//3 * 2
- image5 = image[:, W1:W2, :]
- plt.imshow(image5)
- # 两个方向同时裁剪
- image5 = image[H1:H2, \
- W1:W2, :]
- plt.imshow(image5)
- # 调整亮度
- image6 = image * 0.5
- plt.imshow(image6.astype('uint8'))
- # 调整亮度
- image7 = image * 2.0
- # 由于图片的RGB像素值必须在0-255之间,
- # 此处使用np.clip进行数值裁剪
- image7 = np.clip(image7, \
- a_min=None, a_max=255.)
- plt.imshow(image7.astype('uint8'))
- #高度方向每隔一行取像素点
- image8 = image[::2, :, :]
- plt.imshow(image8)
- #宽度方向每隔一列取像素点
- image9 = image[:, ::2, :]
- plt.imshow(image9)
- #间隔行列采样,图像尺寸会减半,清晰度变差
- image10 = image[::2, ::2, :]
- plt.imshow(image10)
- image10.shape
飞桨使用张量(Tensor)表示数据。Tensor可以理解为多维数组,具有任意的维度,如一维、二维、三维等。不同Tensor可以有不同的数据类型 (dtype) 和形状 (shape),同一Tensor的中所有元素的数据类型均相同。Tensor是类似于Numpy数组(ndarray)的概念。飞桨的Tensor高度兼容Numpy数组,在基础数据结构和方法上,增加了很多适用于深度学习任务的参数和方法,如:反向计算梯度,指定运行硬件等。
如下述代码声明了两个张量类型的向量xx和yy,指定CPU为计算运行硬件,要自动反向求导。两个向量除了可以与Numpy类似的做相乘的操作之外,还可以直接获取到每个变量的导数值。
- import paddle
- x = paddle.to_tensor([1.0, 2.0, 3.0], dtype='float32', place=paddle.CPUPlace(), stop_gradient=False)
- y = paddle.to_tensor([4.0, 5.0, 6.0], dtype='float32', place=paddle.CPUPlace(), stop_gradient=False)
- z = x * y
- z.backward()
- print("tensor's grad is: {}".format(x.grad))
此外,飞桨的张量还可以实现与Numpy的数组转换,代码实现如下。
In [ ]
- import paddle
- import numpy as np
-
- tensor_to_convert = paddle.to_tensor([1.,2.])
-
- #通过 Tensor.numpy() 方法,将张量转化为 Numpy数组
- tensor_to_convert.numpy()
-
- #通过paddle.to_tensor() 方法,将 Numpy数组 转化为张量
- tensor_temp = paddle.to_tensor(np.array([1.0, 2.0]))
虽然飞桨的张量可以与Numpy的数组互相转换,但实践时频繁地转换会导致无效的性能消耗。目前飞桨Tensor支持的操作已经超过NumPy,推荐读者在使用飞桨完成深度学习任务时,优先使用Tensor完成各种数据处理和组网操作。更多飞桨张量的介绍,可以参考“飞桨官网文档-Tensor介绍”。
tanh是神经网络中常用的一种激活函数,其定义如下:
请参照讲义中Sigmoid激活函数的计算程序,用NumPy实现tanh函数的计算,并画出其函数曲线。
提交方式:请用NumPy写出计算程序,并画出tanh函数曲线图,xx的取值范围设置为[-10., 10.]。
假设使用np.random.randn生成了随机数构成的矩阵:
p = np.random.randn(10, 10)
请写一段程序统计其中有多少个元素大于0?
提示:可以试下使用q=(p>0)q = (p > 0),观察qq是什么的数据类型和元素的取值。
提交方式:提交计算的代码,能够直接运行输出统计出来的结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。