【无标题】

系列文章目录

PyTorch张量(Tensor)对象的一些常见方法和函数的使用,以及损失的计算方式。


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、.tolist()?

将PyTorch张量转换为Python列表,该列表包含了与原始张量相同的数据内容

该方法非常有用,这样可以使数据更易于处理和使用,例如进行可视化、计算统计量、保存到文件等操作。

import torch

# 创建一个PyTorch张量
tensor = torch.tensor([1, 2, 3, 4, 5])

# 将张量转换为Python列表
tensor_list = tensor.tolist()

print(tensor_list)
# [1, 2, 3, 4, 5]

 一、squeeze()和unsqueeze()函数的用法?

.unsqueeze(1)将一维的标签张量转换为二维的标签张量,以便与其他张量进行运算或匹配。新插入的维度可以理解为扩展了样本维度。

而squeeze() 函数的作用是去除张量中维度大小为1的维度,从而降低张量的维度。

import torch

labels = torch.tensor([1, 2, 3, 4])  # 一维张量,形状为(4,)
expanded_labels = labels.unsqueeze(1)  # 在第一个维度之后插入新的维度
print(expanded_labels.shape)  # 输出: (4, 1)
print(expanded_labels)

# tensor([[1],
         [2],
         [3],
         [4]])

 

二、detach()函数

1. 计算损失时

初始化 mean_loss 为零张量,使用了加权平均的方法,将当前步骤的损失 loss 与之前的平均损失 mean_loss 进行加权平均计算。在以下示例中detach() 函数用于将计算图截断,将 loss 的梯度计算与计算图分离,以确保在更新 mean_loss 时不会影响梯度的计算。

mean_loss = torch.zeros(1).to(device) 
for step, data in enumerate(data_loader):
        images, labels = data
        # 模型前向传播
        pred = model(images.to(device))
        loss = loss_function(pred, labels.to(device))
        loss.backward()
        mean_loss = (mean_loss * step + loss.detach()) / (step + 1)

print(torch.zeros(1))的结果将打印一个张量对象,其值为0:tensor([0.])。可以进行各种张量操作,如加法、乘法等。mean_loss 需要参与到 PyTorch 的张量计算中,如进行反向传播、梯度更新等。不同于普通的标量变量。

技术其初始值为零张量,但在实际的训练过程中,mean_loss 通常会根据损失函数和梯度进行更新。

2.理解代码中的损失计算方式

由于训练数据集可能非常大,无法一次性加载到内存中进行训练,因此使用批处理的方式进行训练。每个批次的样本被用于模型的前向传播和损失计算,并且梯度是根据这个批次的损失进行计算和更新的。

batch_size = 32
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=nw)
train_steps = len(train_loader)train_steps的结果将是将训练数据集的总样本数除以批次大小(batch_size)得到的结果向上取整。
这是因为在每个训练步骤中,数据加载器会生成一个批次的样本供模型进行训练。

train_steps的结果表示了一个 epoch 中的训练步数,即模型将通过多少个批次的样本进行训练。

一个 epoch 的总损失是所有批次的损失之和。
 如果将总损失除以train_steps,就相当于将总损失平均分配给每个训练步骤,得到了每个训练步骤的平均损失。通过计算平均损失,可以减少批次大小和训练数据集大小对损失值的影响,使得不同批次、不同数据集大小之间的损失可比性更强。这有助于更好地理解和比较模型的训练效果。



以下代码中关于计算的是“什么”损失?立即答:每个批次的平均损失。常见的做法:
train_steps = len(train_loader)
for epoch in range(epochs):
    # train
    net.train()
    running_loss = 0.0
    train_bar = tqdm(train_loader, file=sys.stdout)
    for step, data in enumerate(train_bar):
        images, labels = data
        optimizer.zero_grad()
        outputs = net(images.to(device))
        loss = loss_function(outputs, labels.to(device))
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
print('[epoch %d] train_loss: %.3f '  %
            (epoch + 1, running_loss / train_steps))
running_loss是全部数据的累计损失,但在打印 train_loss时,它被除以 train_steps,表示的是每个批次的平均损失。这样做的目的是为了更好地评估每个批次的训练效果,尽量消除批次大小对损失值的影响,使得不同批次之间的损失可比性更强。

 2.len()函数

返回一个对象的长度或元素的个数

对于数据加载器(train_loader)(数据加载器会自动将数据集按照指定的批次大小划分为多个批次,并在每个训练步骤中提供一个批次供模型使用),len()返回的是加载器中的批次数量,而不是每个批次中的样本数量,即数据集中样本的总数除以批次大小。


总结

以上就是今天要讲的内容,谢谢观看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值