一、框架概览
深度学习框架:是一个针对深度学习的科学计算库,在深度学习领域,以下是当前市场上几个主流的深度学习框架:
-
TensorFlow
- 上一代框架:起始于静态图时代,为早期深度学习的发展做出了巨大贡献。
- 特点:执行性能优异,但模型构建与调试相对复杂。
-
PyTorch
- 市场主导者:尤其是在处理大规模模型时,其市场占有率接近100%。
- 动态图优势:虽然执行效率稍逊一筹,但编程效率极高,使得模型搭建变得像编写普通Python代码一样简单。
- 稳定性强:API接口长期保持稳定,升级主要集中在内部优化而非外部接口变动。
-
PaddlePaddle
- 国产品牌:由百度推出,作为战略储备,在国内具有一定的影响力。
二、PyTorch与NumPy
NumPy
:是一个通用科学计算库,PyTorch
深度学习框架是一个 NumPy++ ,
- 实现了 NumPy 的所有功能、使用习惯、命名等!
- 实现了自动求导!
- 实现常用的模块(层,优化器…)
三、PyTorch框架详解
3.1 安装PyTorch
根据你的硬件配置选择安装GPU或CPU版本的PyTorch:
- GPU版本
- 前提条件:需要NVIDIA独立显卡(显存≥4G),并确保驱动程序是最新的。
- 安装命令:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
- CPU版本
- 安装命令:
pip3 install torch torchvision -i https://mirrors.aliyun.com/pypi/simple/
- 安装命令:
3.2 常用命令示例
import torch# 查看PyTorch版本
print(torch.__version__)# 检查CUDA是否可用
if torch.cuda.is_available():print("CUDA is available.")# 获取当前设备名称print(torch.cuda.get_device_name())# 将矩阵转换为张量
t = torch.tensor(data=X_train, dtype=torch.float32)# 生成随机数
random_num = torch.randint(low=100, high=1000, size=(1,), dtype=torch.float32)
# 13行1列
rand_tensor = torch.randn(13, 1, dtype=torch.float32)
三、计算体系
现代计算体系分为两大部分:
- 基于CPU+内存的传统计算:数据在内存中存放,通过CPU控制进行计算
- 基于GPU+显存的加速计算:数据在显存中存放,通过GPU进行控制计算
需要注意的是,参与计算的数据必须位于相同的设备中。
示例代码
以下是一些张量的基本操作的例子:
import random
import numpy as np
import torch# 创建一个包含30个随机分数的列表,并转换为NumPy数组和PyTorch张量
scores = [random.randint(a=0, b=100) for _ in range(30)]
type(scores) #输出list
arr = np.array(scores)
#输出array([36, 55, 68, 82, 91, 29, 48, 46, 37, 60, 72, 78, 61, 32, 7, 48, 55,0, 8, 80, 60, 52, 81, 41, 30, 43, 35, 47, 57, 26])
type(arr) #输出numpy.ndarray
t = torch.tensor(data=scores, dtype=torch.float32)
#输出tensor([36., 55., 68., 82., 91., 29., 48., 46., 37., 60., 72., 78., 61., 32.,7., 48., 55., 0., 8., 80., 60., 52., 81., 41., 30., 43., 35., 47.,57., 26.])# 计算方差的不同方式
print(arr.var(), arr.var(ddof=1)) # NumPy默认计算样本方差
#输出(504.938888888889, 522.3505747126438)
print(t.var(), t.var(correction=0)) # PyTorch默认计算总体方差
#输出(tensor(522.3506), tensor(504.9389))np.arange(12).reshape(3, 4)
#输出array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])
torch.arange(12).reshape(3, 4)
#输出tensor([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])# 创建相同形状的NumPy数组和PyTorch张量
np.ones(shape=(2, 3))
#输出array([[1., 1., 1.],[1., 1., 1.]])
torch.ones(2, 3)
#输出tensor([[1., 1., 1.],[1., 1., 1.]])np.linalg.norm(arr) #输出294.4299577149037
torch.linalg.norm(t) #输出tensor(294.4300)# 创建线性空间
np.linspace(start=-5, stop=5, num=100)
#输出array([-5. , -4.8989899 , -4.7979798 , -4.6969697 , -4.5959596 ,-4.49494949, -4.39393939, -4.29292929, -4.19191919, -4.09090909,-3.98989899, -3.88888889, -3.78787879, -3.68686869, -3.58585859,-3.48484848, -3.38383838, -3.28282828, -3.18181818, -3.08080808,-2.97979798, -2.87878788, -2.77777778, -2.67676768, -2.57575758,-2.47474747, -2.37373737, -2.27272727, -2.17171717, -2.07070707,-1.96969697, -1.86868687, -1.76767677, -1.66666667, -1.56565657,-1.46464646, -1.36363636, -1.26262626, -1.16161616, -1.06060606,-0.95959596, -0.85858586, -0.75757576, -0.65656566, -0.55555556,-0.45454545, -0.35353535, -0.25252525, -0.15151515, -0.05050505,0.05050505, 0.15151515, 0.25252525, 0.35353535, 0.45454545,0.55555556, 0.65656566, 0.75757576, 0.85858586, 0.95959596,1.06060606, 1.16161616, 1.26262626, 1.36363636, 1.46464646,1.56565657, 1.66666667, 1.76767677, 1.86868687, 1.96969697,2.07070707, 2.17171717, 2.27272727, 2.37373737, 2.47474747,2.57575758, 2.67676768, 2.77777778, 2.87878788, 2.97979798,3.08080808, 3.18181818, 3.28282828, 3.38383838, 3.48484848,3.58585859, 3.68686869, 3.78787879, 3.88888889, 3.98989899,4.09090909, 4.19191919, 4.29292929, 4.39393939, 4.49494949,4.5959596 , 4.6969697 , 4.7979798 , 4.8989899 , 5. ])
torch.linspace(start=-5, end=5, steps=100)
#输出tensor([-5.0000, -4.8990, -4.7980, -4.6970, -4.5960, -4.4949, -4.3939, -4.2929,-4.1919, -4.0909, -3.9899, -3.8889, -3.7879, -3.6869, -3.5859, -3.4848,-3.3838, -3.2828, -3.1818, -3.0808, -2.9798, -2.8788, -2.7778, -2.6768,-2.5758, -2.4747, -2.3737, -2.2727, -2.1717, -2.0707, -1.9697, -1.8687,-1.7677, -1.6667, -1.5657, -1.4646, -1.3636, -1.2626, -1.1616, -1.0606,-0.9596, -0.8586, -0.7576, -0.6566, -0.5556, -0.4545, -0.3535, -0.2525,-0.1515, -0.0505, 0.0505, 0.1515, 0.2525, 0.3535, 0.4545, 0.5556,0.6566, 0.7576, 0.8586, 0.9596, 1.0606, 1.1616, 1.2626, 1.3636,1.4646, 1.5657, 1.6667, 1.7677, 1.8687, 1.9697, 2.0707, 2.1717,2.2727, 2.3737, 2.4747, 2.5758, 2.6768, 2.7778, 2.8788, 2.9798,3.0808, 3.1818, 3.2828, 3.3838, 3.4848, 3.5859, 3.6869, 3.7879,3.8889, 3.9899, 4.0909, 4.1919, 4.2929, 4.3939, 4.4949, 4.5960,4.6970, 4.7980, 4.8990, 5.0000])
GPU的使用
# 检测GPU是否可用
device = "cuda" if torch.cuda.is_available() else "cpu"
t1 = torch.randn(2, 3)
t1 # 输出tensor([[-0.2833, 0.8345, 1.6734],[ 2.1552, -0.2647, -1.6260]])
t2 = torch.randn(2, 3, device=device)
t2 #输出tensor([[ 1.4996, 0.5895, -1.5476], [ 0.2048, 0.2137, 1.6660]], device='cuda:0')
t1 + t2
#输出异常 RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
t1.to(device=device) + t2 # 输出tensor([[ 1.2162, 1.4240, 0.1258],[ 2.3600, -0.0510, 0.0400]], device='cuda:0')
t1 # 输出tensor([[-0.2833, 0.8345, 1.6734], [ 2.1552, -0.2647, -1.6260]])
t2.cpu() + t1 #输出tensor([[ 1.2162, 1.4240, 0.1258], [ 2.3600, -0.0510, 0.0400]])
t1 #输出tensor([[-0.2833, 0.8345, 1.6734], [ 2.1552, -0.2647, -1.6260]])
t1.cuda() # 输出tensor([[-0.2833, 0.8345, 1.6734], [ 2.1552, -0.2647, -1.6260]], device='cuda:0')
自动求导
def fn(x):"""原函数"""return x ** 2
def dfn(x):"""导函数"""return 2 * x
# 数学:常量
x1 = torch.randn(1)
# 数学:变量
x1 # 输出tensor([-0.4863])
# x2是一个变量,这个变量当前取值为 -0.4370
x2 = torch.randn(1, requires_grad=True)
x2 # 输出tensor([-0.4370], requires_grad=True)
# 当前值
x2.data # 输出tensor([-0.4370])
# 梯度值
print(x2.grad) # 输出None
y = x2 ** 2
y # 输出tensor([0.1909], grad_fn=<PowBackward0>)
y.backward()
x2.grad #输出tensor([-2.6218])
x2.grad.zero_() #输出tensor([0.])
x2.grad # 输出tensor([0.])
使用PyTorch的自动求导实现梯度下降法
steps = 1000
learning_rate = 1e-2
x = torch.randint(low=-1000, high=1001, 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}")
输出:
x初始值为:tensor([-262.], requires_grad=True)
优化了1步,x为:tensor([-256.7600], requires_grad=True)
优化了2步,x为:tensor([-251.6248], requires_grad=True)
优化了3步,x为:tensor([-246.5923], requires_grad=True)
......
优化了716步,x为:tensor([-0.0001], requires_grad=True)
优化了717步,x为:tensor([-0.0001], requires_grad=True)
优化了718步,x为:tensor([-0.0001], requires_grad=True)
优化了719步,x为:tensor([-0.0001], requires_grad=True)
优化了720步,x为:tensor([-0.0001], requires_grad=True)
......
优化了998步,x为:tensor([-4.5912e-07], requires_grad=True)
优化了999步,x为:tensor([-4.4994e-07], requires_grad=True)
优化了1000步,x为:tensor([-4.4094e-07], requires_grad=True)
x最终值为:tensor([-4.4094e-07], requires_grad=True)
深度学习本质
统计学项目:
- 想去研究总体/全量的一些情况,但是不能直接去研究
- 退而求其次,对总体进行采样,试图用采样得到的数据来估计总体
- 人工智能的本质是以小博大!
- 使用样本来估计总体!
对样本的统计量:
- 均值
- 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
实际工作中,数据量非常大,两者没什么区别!!!随便用即可!!!