1.行对应样本,列对应属性
2.张量(n维数组),Numpy包中的ndarray。用torch的arange,下面是生成行向量,从0开始的前十二个整数。shape访问每个轴长度(形状),size访问元素个数,reshape改变形状【可以写-1让它自动计算,如x.reshape(-1,4)】
import torch
x=torch.arange(12)
x
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
x.shape
Out[7]: torch.Size([12])
全置为0或1:
torch.ones((2,3,2))
Out[8]:
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
torch.zeros((2,3,2))
均值为0、标准差为1的标准⾼斯分布(正态分布)中随机采样
torch.randn(3,4)
形状相同
Z = torch.zeros_like(Y)
3.运算
**幂运算以及 + - * /
torch.exp(x)指数
逻辑运算==(返回true or false)
4.连接
行:轴0,形状的第一个元素
列:轴1,形状的第二个元素
torch.cat((X, Y), dim=0)
torch.cat((X, Y), dim=1)
5.求和
X.sum()
根据张量得单元素值
6.⼴播机制(broadcasting mechanism)
两个张量a,b要一起操作,应形状相同。
用 a+b 将其合为一个矩阵(缺失的那些行或列复制补齐)
7.索引
X[-1]表示最后一个
X[1:3]左开右闭
X[0:2, :] = 12第一行和第二行的所有元素
8.节省内存
原地操作
Z[:] = X + Y
或
X+=Y
9.转换
A = X.numpy()
B = torch.tensor(A)
type(A), type(B)
(numpy.ndarray, torch.Tensor)
张量变标量
a = torch.tensor([3.5])
a, a.item(), float(a), int(a)
使用pandas包,pandas可以与张量兼容。
用CSV文件(用python到现在好像只接触过CSV)
1.文件读取
写入:
import os
os.makedirs(os.path.join('D:\Ddesktop\work', 'data'), exist_ok=True)
data_file = os.path.join('D:\Ddesktop\work', 'data', 'house_tiny.csv')
with open(data_file, 'w') as f:
f.write('NumRooms,Alley,Price\n') # 列名
f.write('NA,Pave,127500\n') # 每⾏表⽰⼀个数据样本
f.write('2,NA,106000\n')
f.write('4,NA,178100\n')
f.write('NA,NA,140000\n')
在我的D:\Ddesktop\work中建了一个文件夹data,里面只有一个文件house_tiny.csv,是一个五行三列的数据表。(感觉比C方便)
取:
import pandas as pd
import os
house_tiny=os.path.join('D:\Ddesktop\work', 'data', 'house_tiny.csv')
data=pd.read_csv(house_tiny)
print(data)
2.处理缺失值
插值法填补(第一行,iloc是索引;第二行,统一用同一列的均值填补)
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
文字变数字(结构化?)
Alley_Pave的值设置为1,Alley_nan的值设置为0
inputs = pd.get_dummies(inputs, dummy_na=True)
搜了一下,dummy是模型、仿制品的意思
3.格式转换
还是torch.tensor()
import torch
X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
注意一下这个values,它比data少了一行,粗线的理解是少了标题那一行。
默认向量为列向量(注意torch.arange是行向量,且每个数据样本作为矩阵中的行向量更为常见)
len(x)张量的长度
1.矩阵
很喜欢这一行,方便
A = torch.arange(20).reshape(5, 4)
转置A.T
数据类型
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
副本(克隆)
B=A.clone()
A ⊙ B, a_ij*b_ij,矩阵形状不变
A*B
a = 2
X = torch.arange(24).reshape(2, 3, 4)
a + X, (a * X).shape
2.降维
按行求和
A_sum_axis0 = A.sum(axis=0)
求平均
A.mean(axis=0)
非降维求和(保持轴数不变,keepdims)
1
sum_A = A.sum(axis=1, keepdims=True)
A / sum_A
2
A.cumsum(axis=0)
给我的感觉是多了一行,最后一行是和
tensor([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]])
看到了点积,明天继续,bye!
3.点积
对两个向量求点积
torch.dot(x, y)
其实也等于
torch.sum(x*y)
4.矩阵-向量积
矩阵A(n*m),可以认为是m维向量到n维向量的转换(方阵可以认为是旋转)线性变换
这个视频从几何直观理解上讲解了线性变换https://www.bilibili.com/video/BV1ns41167b9/?is_story_h5=false&p=1&share_from=ugc&share_medium=android&share_plat=android&share_session_id=f11b103d-963d-4676-ae3f-55a9d3c10321&share_source=QQ&share_tag=s_i×tamp=1665932513&unique_k=gHYwlPq
A.shape, x.shape, torch.mv(A, x)
注意A的列维数(1)等于x的长度
5.矩阵-矩阵相乘
torch.mm(A, B)
7.范数
torch.norm(u)
#联想长度,向量二范数
torch.abs(u).sum()
#一范数,绝对值之和
torch.norm(torch.ones((4, 9)))
#矩阵F范数,元素平方和开方,答案为6
拟合模型的任务——1.优化(拟合观测数据的过程)2.泛化(不仅仅适用于训练集,能往外用)
1.理解导数
import numpy as np
from matplotlib_inline import backend_inline
from d2l import torch as d2l
def f(x):
return 3 * x ** 2 - 4 * x
def numerical_lim(f, x, h):
return (f(x + h) - f(x)) / h
h = 0.1
for i in range(5):
print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')
h *= 0.1
输出:
h=0.10000, numerical limit=2.30000
h=0.01000, numerical limit=2.03000
h=0.00100, numerical limit=2.00300
h=0.00010, numerical limit=2.00030
h=0.00001, numerical limit=2.00003
2.自动微分
import torch
x = torch.arange(4.0)
x.requires_grad_(True) # 等价于x=torch.arange(4.0,requires_grad=True)
y = 2 * torch.dot(x, x)
y.backward()
x.grad
粗浅的理解是,y作为因变量,让它存一个函数。反向传播就是对因变量backward(),看导数值就是自变量的grad(梯度)。
上面的代码就是4x
Out[3]: tensor([ 0., 4., 8., 12.])
输出确实如此
# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
3.分离计算(求偏导)
detach()截断反向传播的梯度流
x.grad.zero_()
y = x * x
u = y.detach()
z = u * x
z.sum().backward()
x.grad == u
4.控制流的梯度计算分段(设置好函数,就有梯度,以分段线性函数为例)
def f(a):
b = a * 2
while b.norm() < 1000:
b = b * 2
if b.sum() > 0:
c = b
else:
c = 100 * b
return c
a = torch.randn(size=(), requires_grad=True)
d = f(a)
d.backward()
a.grad == d / a