什么是tqdm?
tqdm是一个快速、可扩展的Python进度条,可以在Python长循环中添加一个进度提示信息,用户只需要封装任意的迭代器tqdm(iterator)。它可以帮助我们监测程序运行的进度,估计运行的时长,甚至可以协助debug。对于在长时间运行的任务中显示进度很有用,因为它可以让用户知道任务正在进行。
安装pip install tqdm
使用方法
1.传入可迭代对象
import time
from tqdm import *
for i in tqdm(range(1000)):
time.sleep(0.01) #进度条每0.01s前进一次,总时间为1000*0.01=10s
使用trange,trange(i)是 tqdm(range(i))的简单写法
import time
from tqdm import trange
for i in trange(1000):
time.sleep(0.01)
2.为进度条设置描述
在for循环外部初始化tqdm,可以打印其他信息
import time
from tqdm import tqdm
pbar = tqdm(["a","b","c","d"])
for char in pbar:
pbar.set_description("Processing %s" % char) # 设置描述
time.sleep(1) # 每个任务分配1s
# 结果如下
0%| | 0/4 [00:00<?, ?it/s]
Processing a: 0%| | 0/4 [00:00<?, ?it/s]
Processing a: 25%|██▌ | 1/4 [00:01<00:03, 1.01s/it]
Processing b: 25%|██▌ | 1/4 [00:01<00:03, 1.01s/it]
Processing b: 50%|█████ | 2/4 [00:02<00:02, 1.01s/it]
Processing c: 50%|█████ | 2/4 [00:02<00:02, 1.01s/it]
Processing c: 75%|███████▌ | 3/4 [00:03<00:01, 1.01s/it]
Processing d: 75%|███████▌ | 3/4 [00:03<00:01, 1.01s/it]
Processing d: 100%|██████████| 4/4 [00:04<00:00, 1.01s/it]
3.tqdm的write方法
bar = trange(10)
for i in bar:
time.sleep(0.1)
if not (i % 3):
tqdm.write("Done task %i" % i)
# 结果如下
Done task 0
0%| | 0/10 [00:10<?, ?it/s]
0%| | 0/10 [00:00<?, ?it/s]
10%|████████▎ | 1/10 [00:00<00:01, 8.77it/s]
20%|████████████████▌ | 2/10 [00:00<00:00, 9.22it/s]
Done task 3
0%| | 0/10 [00:10<?, ?it/s]
30%|████████████████████████▉ | 3/10 [00:00<00:01, 6.91it/s]
40%|█████████████████████████████████▏ | 4/10 [00:00<00:00, 9.17it/s]
50%|█████████████████████████████████████████▌ | 5/10 [00:00<00:00, 9.28it/s]
Done task 6
0%| | 0/10 [00:10<?, ?it/s]
60%|█████████████████████████████████████████████████▊ | 6/10 [00:00<00:00, 7.97it/s]
70%|██████████████████████████████████████████████████████████ | 7/10 [00:00<00:00, 9.25it/s]
80%|██████████████████████████████████████████████████████████████████▍ | 8/10 [00:00<00:00, 9.31it/s]
Done task 9
0%| | 0/10 [00:11<?, ?it/s]
90%|██████████████████████████████████████████████████████████████████████████▋ | 9/10 [00:01<00:00, 8.37it/s]
100%|██████████████████████████████████████████████████████████████████████████████████| 10/10 [00:01<00:00, 9.28it/s]
4.在深度学习中如何使用
下面是一段手写数字识别代码
(1)下载训练集数据集
import torch.cuda
from torch import nn #导入神经网络模块
from torch.utils.data import DataLoader #数据包管理工具
from torchvision import datasets #数据处理工具,专门用于图像处理的包
from torchvision.transforms import ToTensor #数据转换,张量
'''下载训练集数据集(包含训练图片和标签)'''
#datasets.MNIST来加载MNIST数据集作为训练数据集。
#root='data':指定数据集存储的根目录,可以根据需要进行更改。
#train=True:表示加载训练数据集
#download=True:如果数据集在指定路径中不存在,将自动从官方源下载并保存。
#transform=ToTensor():指定数据转换操作,将图像数据转换为PyTorch中的Tensor张量格式。
training_data = datasets.MNIST(
root='data',
train=True,
download=True,
transform=ToTensor(), #张量
) #对于pythorch库能够识别的数据一般是tensor张量
test_data = datasets.MNIST(
root='data',
train=False,
download=True,
transform=ToTensor()
)
创建数据DataLoader
train_dataloader = DataLoader(training_data,batch_size=64) #64张图片为一个包
test_dataloader = DataLoader(test_data,batch_size=64)
for X,Y in train_dataloader: #X表示打包好的每一个数据包
print(f'Shape of X[N,C,H,W]:{X.shape}')
print(f'Shape of Y:{Y.shape}{Y.dtype}')
break
'''判断当前设备是否支持GPU,其中mps是苹果m系列芯片的GPU'''
device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
print(f'Using {device} device')
补充:
bath_size:将数据集分成多份,每一份为bath_size个数据
优点:可以减少内存的使用,提高训练的速度
64: 表示批次大小(batch size),即该张量包含了64个样本。
1: 表示通道数(channel),在这里是灰度图像,所以通道数为1。
28: 表示图像的高度(height),即每个图像有28个像素点的高度。
28: 表示图像的宽度(width),即每个图像有28个像素点的宽度。
(2)创建神经网络模型
class NeuralNetwork(nn.Module): #定义了一个名为 NeuralNetwork 的类,继承自 nn.Module 类,这是 PyTorch 中用于构建神经网络的基类。
def __init__(self):
super().__init__() #调用父类(nn.Module)的构造函数,确保初始化神经网络的基类。
self.flatten = nn.Flatten() #创建一个展开对象 flatten,用于将输入的图像数据展平成一维向量
self.hidden1 = nn.Linear(28*28,128) #创建了第一个全连接层,输入大小为 28*28(即图像展开后的长度),输出大小为 128。
self.hidden2 = nn.Linear(128,64) #创建了第二个全连接层,输入大小为 128,输出大小为 64。
self.hidden3 = nn.Linear(64,256) # 创建了第三个全连接层,输入大小为 64,输出大小为 64。
self.out = nn.Linear(256,10) #创建了输出层,输入大小为 64,输出大小为 10,用于分类任务。
def forward(self,x): # 定义了模型的前向传播过程,指定了数据在网络中流动的路径和操作。
x = self.flatten(x) #将输入的图像数据 x 进行展平操作。
x = self.hidden1(x) #将展平后的数据 x 传入第一个全连接层 hidden1 进行线性变换和激活函数操作。
x = torch.relu(x) # 使用 ReLU (Rectified Linear Unit) 激活函数对 hidden1 层的输出进行非线性化
x = self.hidden2(x) # 将 hidden1 层的输出 x 传入第二个全连接层 hidden2 进行线性变换和激活函数操作。
x = torch.sigmoid(x)
x = self.hidden3(x)
x = torch.relu(x)
x = self.out(x)
return x
model = NeuralNetwork().to(device) # 创建一个神经网络模型的实例,将其移动到指定的设备上,
(3)模型训练和测试
# 定义训练函数,输入参数包括数据加载器,模型,损失函数和优化器
def train(dataloader,model,loss_fn,optimizer):
model.train() # 设定模型为训练模式
batch_size_num = 1 # 初始化批次编号为1
for x,y in dataloader: # 遍历数据加载器,每次提供一批数据
x,y = x.to(device),y.to(device) # 将数据移到指定设备,例如GPU
pred = model.forward(x) # 通过模型计算预测结果
loss = loss_fn(pred,y) # 计算预测结果与实际结果的损失值
optimizer.zero_grad() # 清空优化器的梯度缓存
loss.backward() # 反向传播,计算梯度
optimizer.step() # 使用优化器更新模型参数
loss_value = loss.item() # 获取损失值的item,以便后续操作
# 打印损失值和批次编号
# print(f'loss:{loss_value:>7f}[num:{batch_size_num}]')
batch_size_num += 1 # 批次编号加1,以便在每个批次后更新批次编号。
# 定义损失函数,这里使用交叉熵损失函数
loss_fn = nn.CrossEntropyLoss()
# 定义优化器,这里使用Adam优化器,学习率为0.0015
optimizer = torch.optim.Adam(model.parameters(),lr=0.0015) #可以用Adam 最好的模型
# 调用训练函数进行模型训练
train(train_dataloader,model,loss_fn,optimizer)
# 定义测试函数,输入参数包括数据加载器,模型和损失函数
def test(dataloader,model,loss_fn):
size = len(dataloader.dataset) # 获取测试集的数量
num_batches = len(dataloader) # 获取数据加载器的批次数量
model.eval() # 设定模型为评估模式,关闭dropout等影响结果的因素
test_loss,correct = 0,0 # 初始化测试损失和正确率
with torch.no_grad(): # 关闭梯度计算,节省内存,因为这里不需要反向传播计算梯度
for x,y in dataloader: # 遍历数据加载器,每次提供一批数据用于测试
x,y = x.to(device),y.to(device) # 将数据移到指定设备,例如GPU
pred = model.forward(x) # 通过模型计算预测结果
test_loss += loss_fn(pred,y).item() # 计算预测结果与实际结果的损失值并累加到总损失中
correct += (pred.argmax(1) == y).type(torch.float).sum().item() # 计算预测正确的数量并累加到总数中
test_loss /= num_batches # 平均损失值,得到最终的测试损失
correct /= size # 平均正确率,得到最终的测试正确率
return test_loss, correct # 返回测试损失和正确率作为测试结果
(4)训练深度学习模型
# 定义训练的轮数,即迭代次数
epochs = 5
# 导入进度条模块,tqdm可以让我们在训练过程中看到每个epoch的进度
from tqdm import tqdm
# 循环进行指定轮数的训练
for epoch in range(epochs):
# for data,targets in tqdm(train_loadr,leave=False) # 进度显示在一行
for data,targets in tqdm(train_dataloader):
# 将数据移动到指定设备,如果可能的话。例如,如果你使用GPU进行计算,这将会把数据移到GPU上。
data = data.to(device=device)
targets = targets.to(device=device)
# 正向传播,模型对输入的数据进行计算,得到预测的结果
scores = model(data)
# 计算损失,这个损失是模型预测的结果与实际目标之间的差距
loss = loss_fn(scores,targets)
# 反向传播,根据损失计算出梯度,这个过程是在每个训练步骤中计算损失对模型参数的梯度
optimizer.zero_grad() # 清空之前的梯度缓存
loss.backward() # 计算梯度
# 使用优化器更新模型参数,这个过程是根据前面计算的梯度来更新模型参数,实现下降学习。
optimizer.step() # 使用优化器更新模型参数