文章目录
- 数据转换和数据生成
- 存取数据
- 数据变形和合并
- 算数计算
- 广播机制
- 使用Numpy实现回归实例
numpy的重要性不言而喻,一般不涉及到GPU/TPU计算,都是用numpy,常见的np就是这个玩意。其特点就是快!其实如果不涉及到深度学习,还有一个库是很重要的,scipy,集成了很多的东西。
安装和导入如下:
# pip 安装方式
pip install numpy
# conda 安装方式
conda install numpy
# 导入
import numpy as np
numpy对象一般有三个属性:ndarray.ndim、ndarray.shape、ndarray.dtype。分别表示数据维度,数据形状,数据类型
数据转换和数据生成
将已有数据转化为numpy类型很简单,一般来说直接numpy.array一下就好
lst = [0.30406244, 0.06466714, 0.44950621]
array = np.array(lst)
这里无论是字符串什么东西的都可以直接丢进去,这里提一下读取图片文件,需要涉及到其他的库,常见的有PIL、OpenCV
# PIL
from PIL import Image
import numpy as np
im = np.array(Image.open('图片路径'))
# OpenCV
import cv2
im = cv2.imread('图片路径')
这两种方式都可以读取图片文件,cv2可以直接的转化为numpy类型数据
然后就是数据生成,分为随机生成和有序生成,分为random模块以及arange、linspace模块
这里先介绍一下random
# 设置随机种子
np.random.seed(42)
# 生成矩阵形状为4*4,值在0-1之间的随机数
np.random.random(size=(4,4))
# 生成矩阵形状为4*4,值在low和high之间的随机整数
np.random.randint(low=0, high=1, size=(4,4))
# 生成矩阵形状为4*4,值在low和high之间满足均匀分布的随机数
np.random.uniform(low=0, high=1, size=(4,4))
# 生成矩阵形状为4*4,值在low和high之间满足正态分布的随机数
np.random.normal(loc=0, scale=1, size=(4,4))
这里要注意:正态分布的loc表示的是 μ \mu μ , scale表示的是 σ \sigma σ。
接下来是arange和linspace
np.arange(start, stop, step)
np.linspace(start, stop, num)
arange和linspace的区别就是step和num的区别,其中step是步长,num是数量,分别表示根据步长生成有序数据和数量生成有序数据。
存取数据
numpy和list一样,可以指定行和列来对数据进行切片,但是不同的是可以利用True和False来对数据进行筛选
mu, sigma = 0, 0.1
s = np.random.normal(mu, sigma, 1000)
res = s[(s>0) & (s<1)]
这样可以提取在0-1范围上的所有数据,这里要注意的是,条件必须要带上括号
数据变形和合并
首先是数据形状的修改
arr = np.arange(10)
## reshape 修改np对象维度,不修改矩阵本身
arr = arr.reshape(2,5)
## resize 修改np对象维度,同时修改矩阵本身
arr.resize(2,5)
## T 转置
arr.T
## ravel 把np对象展平,变成一维 C表示行优先,F表示列优先
arr.ravel('C')
## flatten 把np对象展平,变成一维 C表示行优先,F表示列优先
arr.flatten(order="C")
## squeeze 对维数为1的维度进行降维,即清除掉维数为1的维度
arr.squeeze()
## 拓展维度
np.expand_dims(arr, axis=-1)
arr[:, np.newaxis]
## transpose 对高维矩阵进行轴对换
arr.transpose(1,2,0)
数据合并
lst = [1, 2, 3]
lst_ = [3, 4, 5]
## append 拼接数组,维度不能发生变化
res = np.append(lst,lst_)
## concatenate 拼接数组,维度不能发生变化,内存占用要比append低, 推荐使用
lst = np.array([1, 2, 3])
lst_ = np.array([3, 4, 5])
res = np.concatenate((lst, lst_), axis=0)
## stack hstack vstack dstack 堆叠数组
lst = np.array([1, 2, 3])
lst_ = np.array([3, 4, 5])
res = np.stack((lst, lst_), axis=1) # 对应dstack 沿着第三维
res = np.stack((lst, lst_), axis=0) # 对应vstack 沿着列堆叠
res = np.hstack((lst, lst_)) # 沿着行堆叠
算数计算
numpy的算术计算相比与math速度大大提升
sqrt
,sin,cos
,abs
,dot
,log,log10,log2
,exp
,cumsum, cumproduct
,sum
,mean
,median
,std
,var
,corrcoef
广播机制
- 让所有输入数组都向其中shape最长的数组看起,shape中不足的部分都通过在前面加1补齐;
- 输出数组的shape是输入数组shape的各个轴上的最大值;
- 如果输入数组的某个轴和输出数组的对应轴的长度相同或者长度为1时,则可以调整,否则将会出错;
- 当输入数组的某个轴长度为1时,沿着此轴运算时都用(或复制)此轴上的第一组值;
使用Numpy实现回归实例
假设目标函数如下:
y = 3 x 2 + 2 x + 1 y=3x^2+2x+1 y=3x2+2x+1
图像如下:
假设知道最高项为3,设函数为: y = a x 2 + b x + c y=ax^2+bx+c y=ax2+bx+c
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
x = np.linspace(-10, 10, 50)
y = 3 * np.power(x, 2) + 2 * x + 1
a = np.random.random(size=(1, 1))
b = np.random.random(size=(1, 1))
c = np.random.random(size=(1, 1))
def get_predict(x):
global a, b, c
res = (a * np.power(x, 2) + b * x + c).flatten()
return res
def get_loss(y, y_pred):
return np.mean(np.square(y - y_pred))
def grad_param(y, y_pred, lr=1e-4):
global a, b, c
a_grad = 2 * np.mean((y_pred - y) * np.power(x, 2))
b_grad = 2 * np.mean((y_pred - y) * np.power(x, 1))
c_grad = 2 * np.mean(y_pred - y)
a -= lr * a_grad
b -= lr * b_grad
b -= lr * c_grad
return None
def train_one_peoch(x, y):
y_pred = get_predict(x)
loss = np.mean(get_loss(y, y_pred))
grad_param(y, y_pred)
return loss
def main():
loss_lst = []
for i in range(100):
loss = train_one_peoch(x, y)
loss_lst.append(loss)
print("第", i + 1, "次", "训练loss:", loss)
plt.plot(loss_lst)
plt.show()
if __name__ == "__main__":
main()
得到训练后的损失如下: