深度学习框架
- TensorFlow
- 上一代框架
- 静态图起家
- 深度学习前期很重要
- 执行性能高,但是模型搭建和调试困难
- PyTorch
- 现阶段主流,特别是大模型时代,市场占有率100%
- 动态图起家
- 执行性能低,但是编程效率高
- 直接把模型的搭建,编程了Python编程,消除了一切难度
- API很稳定,从0.几到现在,几乎不变
- 升级都是内功修炼,不要求编程人员根据版本的升级而更改代码
- PaddlePaddle
- 百度,国货
- 战略储备
深度学习框架给我们带来了什么?
- 深度学习框架:是一个针对深度学习的科学计算库
- Numpy:是一个通用科学计算库
- 历史演进的角度来说:
- 深度学习框架是一个NumPy++
- 1. 实现了NumPy的所有功能、使用习惯、命名等。
- 2. 实现了自动求导。
- 3. 实现常用的模块(层、优化器……)
- 深度学习框架是一个NumPy++
PyTorch
- 安装
- 官网:PyTorch
1. 打开ANACONDA命令窗口
2. 在终端窗口内,输入命令进行安装
pip3 install torch torchvision torchaudio
3. 测试安装,打开jupyter notebook,输入代码
import torch
#查看版本号
torch.__version__
张量 基本计算
import random
import numpy as np
import torch
#随机生成30个0-100的数,放到列表中
scores = [random.randint(a=0,b=100) for _ in range(30)]
#创建numpy数组,将scores列表放进去,方便使用numpy的各种计算方法
arr = np.array(scores)
t = torch.tensor(data=scores, dtype=torch.float32)
深度学习本质
- 统计学项目:
- 想去研究总体 / 全量的一些情况,但是不能直接去研究
- 退而求其次,对总体进行采样,试图用采样得到的数据来估计总体
- 人工智能的本质是以小博大,使用样本来估计总体
- 对样本的统计量:
- 均值:mu = sum(x) / len(x)
- 方差:sum((x-mu)**2) / len(x)
- 标准差:(sum((x-mu)**2) / len(x))**0.5
- 对总体的统计量:
- 均值:mu = sum(x) / len(x)
- 方差:sum((x-mu)**2) / (len(x)-1)
- 标准差:(sum((x-mu)**2) / (len(x)-1))**0.5
#Numpy默认求的是样本方差,样本是除以n,总体是除以n-1
arr.var(ddof=0)
# 总体方差
arr.var(ddof=1)
#PyTorch默认求的是总体方差
t.var()
#如果想求样本方差,可指定参数correction=0
t.var(correction=0)
实际工作中,数据量非常大,两者没什么区别,随便用即可。
这就是理论数学和工程数学的区别。
计算体系
CPU + 内存
- 数据在内存中存放,通过CPU控制进行计算
- 逻辑计算较快,数据计算较慢
GPU + 显存
- 数据在显存中存放,通过GPU进行控制计算
- 数据计算较快,逻辑计算较慢,所以将矩阵、向量化的计算拉到显存中计算
参与计算的数据,必须存在相同的设备中。
自动求导
"""
1. 理论数学的做法
"""
#原函数
def fn(x):
return x ** 2
#导函数
def dfn(x):
return 2 * x
数值求导
- 不是先求导函数,再去代入变量求导数。
- 求导和代入是一起完成的。
- 如何定义变量和常量?
- 如何标记一个变量?
- requires_grad = True
使用PyTorch的自动求导,实现梯度下降法
steps = 1000
learning_rate = 1e-2
x = torch.randint(low=-1000,
high=1000,
size=(1,),
dtype=torch.float32,
requires_grad=True)
print(f"x的初始值为:{x}")
for step in range(steps):
# 1,先做正向传播
y = x ** 2
# 2, 反向传播(求偏导)
y.backward()
# 3, 梯度下降
x.data -= learning_rate * x.grad
# 4, 清空梯度
x.grad.zero_()
print(f"优化了{step+1}步,x的值为:{x}")
print(f"x的最终值为:{x}")
算法流程:
- 1. 随机初始化 w 和 b:
- 假设函数/模型:
- y = w1 * x1 + w2 * x2 + ... w13 * x13 + b
- 2. 从训练集中,取出一批样本 batch_X, batch_y:
- 把特征 batch_X 带入模型,得到一个预测结果 y_pred
- 此时:y_pred 是 w 和 b 的函数
- 衡量预测结果和真实结果的误差
- loss = loss_fn(y_pred, batch_y)
- 预测的越差,误差越大;预测的越好,误差就越小;
- loss 是 y_pred 的函数,y_pred 又是 w 和 b 的函数
- loss 是 w 和 b 的函数
- 误差的大小是受 w 和 b 的影响
- 模型变好,误差变小:
- 数学问题:
- 求函数的最/极小值
- 当 w 和 b 是多少的时候,loss 可以取得最小值?
- 数学问题:
- 综上所述,模型优化的问题,就变成了一个函数求最小值的问题!
import pandas as pd
"""
原始数据读取
"""
data = pd.read_csv("boston_house_prices.csv",skiprows=1)
data = data.to_numpy()
X = data[:,:-1]
y = data[:,-1]
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)
"""
预处理
标准化
规范化
norm
standard
"""
mu = X_train.mean(axis=0)
sigma = X_train.std(axis=0)
X_train = (X_train - mu)/sigma
X_test = (X_test - mu)/sigma
import torch
"""
定义参数
13:weight
1:bias
"""
# 权重
w = torch.randn(13, requires_grad=True)
# 偏置
b = torch.randn(1, requires_grad=True)
w,b
def model(x):
"""
定义线性回归的处理逻辑
"""
return x @ w +b
steps = 1000
learning_rate = 1e-3
for step in range(steps):
# 1, 正向传播
y_pred = model(X_train)
# 2, 计算损失 MSE
loss = ((y_train - y_pred) ** 2).mean()
# 3, 反向传播
loss.backward()
# 4, 优化一步
w.data -= learning_rate * w.grad
b.data -= learning_rate * b.grad
# 5, 清空梯度
w.grad.zero_()
b.grad.zero_()
print(loss.item())