深度学习(动手学深度学习pytorch)1

目录

  • 预备知识
    • 数据操作
    • 数据预处理
    • 线性代数
    • 微积分

预备知识

数据操作

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

你可能感兴趣的:(深度学习,深度学习,pytorch,python)