相信大家都在各个不同的资源平台开始接触到大模型和深度学习这类方法概念,但是很多非科班出身的工程师都还是对这些概念比较模糊,或者说感到比较抽象。笔者认为,要想真正理解一门理论知识,一次性的实践操作相较于理论知识的累积来的更加实际、直接,也更容易为人所理解。基于此,本文将为深度学习读者介绍一款特别好用的GPU共享云资源代码实操平台,并将基于深度学习的一些基本知识点结合到代码编辑中,以一个能够运行的实例为大家展示如何将你写的代码放到这个云资源平台上进行运行。
对于大模型这类高阶深度学习而言,分类任务主要对应离散类型预测,回归任务主要对应连续类型预测问题。 其实际的问题构成要素主要包括如下:
样本(Sample)也就是我们很多开发工程师所提到的数据。这里包括了对应的标签和属性,属性描述样本本身的性能,而标签则是对样本进行归类。对应到如上函数而言,其属性就是函数输出y,而标签则对应的是输入x。学习模型的过程就是训练,让模型“学会”从输入特征推导出输出的规则。比如一般神经网络正向传播的过程就是建立以w,b为参数的方程,而训练则是去通过不断的迭代遍历整个样本参数不断减少损失值,最终实现不断调整优化模型参数w,b的值。在机器学习中,参数个数一般会比样本个数少。测试(Testing)过程就是对我们已经计算出参数的过程进行评价。最后得到的模型就可以对新输入的样本进行学习输出,即基于样本的标签进行属性预测。
接下来我们来了解一下Pytorch的三个基本概念:
变量Variiable表达参数parameter,用于搭建Moudle模型。当矩阵和向量无法描述的更高维度属性信息时,就可以是使用张量Tensor来进行描述。因此,Tensor可以看成是对标量、向量、矩阵的更加泛化的定义,用于描述机器学习中的样本及模型。张量Tensor可以用于描述任意维度的样本,实际是对标量、向量、矩阵实现的更加高维和泛化的表示形式。为什么会在机器学习中采用张量的表示形式呢?这是因为我们的整个学习过程对于输入数据的维度大小是不确定的。接下来就是需要重点关注的变量variable信息,这其实也是表示的参数信息。即当模型参数未知时,其对应的就是一个变量信息。接下来就我们需要在机器学习中需要用到的nn.module模块。你可以看成是搭建深度学习索要用到的积木元素。
那么,基于pytorch的编码中,对于tensor的操作主要包括哪些呢?
实际上,Tensor的基本操作中包括了数据类型、创建、属性、运算、操作、numpy的相互转化。当然这些相关概念本身是比较抽象的,如果要捋清楚他们之间的关联度,需要充分的结合实例代码来进行分析。本系列文章将结合一个实例来简单逐渐讲清以上Tensor操作将如何进行。
这里我们将介绍两款适用于AI大模型学习和调试的工具链。
1、AI编程工具链Cursor
首先,是代码编辑工具链Cursor。令我比较惊奇的是,对于AI编辑器来说,竟然有40%的程序员从来没用过,而用过的那60%也有很多人是用不好的。还有一个令人震惊的消息,那就是真正使用较为广泛的人群中,这块AI代码编辑器竟然是AI产品经理用的更广泛。也就是在23年底和24年初,整个AI业界对cursor使用人群快速增长。而后续一众大佬们的推荐,更是让cursor彻底出圈。甚至在推特上有报道一个年仅8岁的孩子在不到一天时间内通过利用cursor就开发出一款聊天机器人,这你敢信吗?前特斯拉自动驾驶开发负责人关于cursor更是给予了较高的评价。他认为未来就像是不断地tab、tab、tab。这种不仅是以插件形式构建的编辑器框架。
对于初学者而言,可以考虑先基于cursor中的chat模式进行泛化提问沟通,让我们的指令变得更加明确,后续便可以通过composer去根据理解按步骤给出提示词让Composer帮你生成更加专业和针对性的结果,而不是直接Composer模式反复尝试。那样会做很多无用功。如果是相对复杂的AI项目,那么你在跟chat沟通完成后,可以进行功能需求拆解,并将这些拆解的内容通过notepad单独记录下来。然后按照需求步骤,在composer需求框中选择对应的notepad去完成对应的需求。当然,如果composer执行对应notepad需求有问题时,可以记录对应的问题项,然后去chat模式下提问解决对应的问题。
只要我们善于用自然语言描述需求,则可以很好的生成代码,笔者自己现在也是能不写代码就尽量不写。偷懒是一方面,锻炼与AI沟通的能力也是另一方面。没错,我把它称之为与AI的沟通能力,个人认为,AI将会带来新一轮的技术平权:即他给了闷头卷技术的人一榔头,同时也给了外行想要入局的人一座枣山。实际上,在整个过程中,程序员们无需在干以前那种底层的脏活累活(比如花大量实践去找一些代码模块的bug),但是对于开发者而言需求从更高的维度去审视和规划整体的需求和架构,因此,对于整个利用AI进行问题分析、分解与处理的能力要求是跨层的。过程中,模型可能存在幻觉(这里的幻觉就像盖房子一样的砖头和地基,虽然有料,但是没有指导说明说,这就根本垒不起来一座高楼),而沟通能力的需求表达和架构能力的需求拆解则可以很大程度上规避这种AI模型对的幻觉问题。
2、AI并行代码运行工具链Kaggle
其次,便是大模型要求比较高的运行环境,考虑到很多深度学习初学者,并没有这么高配置的硬件调试环境。因此,本文将推荐一款非常实用云平台运行环境,可以帮助开发初学者初识AI大模型的基本原理、运行过程,这确实比简单枯燥的看论文,看文字性的推文来的更加贴合实际,也更容易为人所理解。老实说,没有实践的理论解析是缺乏灵魂的,也很容易被人所忘记。结合有效的工具链进行理论理解,并开发自己的demo跑起来真是一个不错的选择。本文将详细讲解一款业内比较火的云资源高算力调试平台kaggle,用于运行我们基于理论知识所编辑的第一段代码。
Kaggle 是一个面向数据科学家和机器学习从业者的在线平台,提供了数据集、代码分享、竞赛、学习资源以及云端计算环境(Kernels)。以下是对 Kaggle 界面的详细介绍,包括主要功能和页面布局。
Kaggle编辑界面的主要组成部分通常包括代码顶部导航栏可以快速访问核心功能:Code(代码)、Datasets(数据集)、Competitions(竞赛)、Discussions(讨论)、Learn(学习)。
Kernels(Notebooks) 作为Kaggle 的在线编程环境,基于 Jupyter Notebook。支持 Python 和 R 语言,提供免费的 GPU 和 TPU 资源,可以导入外部数据集或使用 Kaggle 数据集。这些资源限制对于免费用户来说,每周可以有30 小时的 GPU 使用时间以及 20 小时的 TPU 使用时间。初学者足足够了。要想用好Kaggle,个人认为只要掌握如下几个要素就可以了。
(1) Code(代码): 提供用户分享的 Jupyter Notebook(称为 Kernels),支持 Python 和 R 语言。特点是可以直接在浏览器中运行代码,支持 GPU 和 TPU 加速,可以 Fork 他人的代码并修改。
(2) Datasets(数据集): 提供海量的公开数据集,涵盖各个领域(如医疗、金融、图像、文本等)。特点是数据集可以直接在 Kernels 中使用,支持数据集的版本管理,提供数据预览和描述信息。
(3) Competitions(竞赛): 是Kaggle 的核心功能之一,提供机器学习竞赛。
(4) Discussions(讨论): 按主题分类,如竞赛、数据集、代码等。用户可以在讨论区提问、分享经验和交流。
(5) Learn(学习): 提供免费的机器学习课程和教程。
代码实例编程了解kaggle
接下来,本文将通过代码逐一解析每个部分的功能和使用方法,特别是针对深度学习开发者的常用操作,比如PyTorch模型的编写、数据加载、训练循环等。考虑学习过程中可能遇到的痛点,比如环境配置问题、代码调试困难、资源限制等,并在解析中给出解决方案或最佳实践。例如,如何利用Kaggle的Notebook魔法命令简化代码,如何处理内存不足的情况,或者如何有效利用GPU资源等等。
Kaggle 编辑界面核心组件代码编辑器具备多模式支持特性:支持 Python 3、R、Julia,默认 PyTorch/TensorFlow 环境预装。深度学习专用功能可以通过如下指令启动:
!pip install torch torchvision torchaudio --index-url
https://download.pytorch.org/whl/cu118
3、AI编程语言Pytorch
最后,就是为什么选择pytorch作为编程语言工具链来深度了解AI 大模型,那时因为pytorch相对于Tensorflow而言,具有简洁性(即编程同python几乎一致)、动态计算的特性,几乎所有的深度学习模型库都是完全封装好的,只需要了解规则+简单调用即可。但是相对于Tensorflow而言,pytorch部署就显得不是那么方便。不过对于非professional的初学者而言,这已经足够了。笔者之前有幸听过多期基于英伟达芯片做AI模型部署的课程,老实说,没有结合实际应用和调试,很容易忘,光学习的理论也显得比较苍白无力。
现在我们将以代码实例的方式来初步接触pytorch在kaggle上跑我们深度学习大模型项目。
1)安装必要的库(Kaggle 环境中通常已经安装 PyTorch)
!pip install torch torchvision
在 Notebook 中动态下载数据集,可以使用 Kaggle API。在 Notebook 中运行以上命令安装 Kaggle API,以上就可以直接利用Kaggle的内置数据集了。
2)导入库
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torchvision.models import resnet50
from tqdm import tqdm
3)检查 GPU 是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
运行结果如下:
可以看到,整个云计算资源是通过检查设备有效性后利用共享GPU的CUDA资源进行并行计算的。
在kaggle的云资源上可选的GPU资源主要有三种:
1.GPU T4 x2:
- 适合中小型模型的训练和推理。
- 如果需要混合精度计算或双卡并行,可以选择 T4 x2。
2.GPU P100:
- 适合大型模型的训练和推理。
- 如果需要高显存带宽或单卡性能,可以选择 P100。
3.TPU VM v3-8:
- 适合超大型模型的训练和推理。
- 如果使用 TensorFlow 或 JAX 框架,并且需要大规模并行计算,可以选择 TPU VM v3-8。
整个深度学习代码流程包含如下几个重要的模块,简单的讲就是数据训练+验证。过程中可以设置多个超参数。比如遍历数据集的次数epoch,处理batch size,学习率等等。我们通过手动调整这些超参数可以很明显的看到整个训练过程效率、性能的balance。从而更好地理解类似感知大模型是怎样运行的,想要介入深度学习的朋友对于很多从书本上看到的理论知识也将在此编译和结果过程中得到具象化的输出。
4)定义超参数
batch_size = 64
#batch_size 是每次训练时输入模型的样本数量。控制每次更新模型参数时使用的数据量。batch_size 决定了每次从数据集中加载多少样本。例如,CIFAR-10 训练集有 50,000 张图像,batch_size=64 表示每次加载 64 张图像。常见取值范围通常为 32、64、128、256 等,具体取决于显存大小和数据集规模。
如下两图所示,当设置不同的batchsize大小时,很明显的时GPU的利用率会存在较大的差异。当设置为128时,GPU整个是全时段100%跑起来的,而设置为32时,则GPU利用率只有平均70%左右。
较大的 batch_size 可以提高 GPU 的利用率,加快训练速度。较小的 batch_size 可以提供更多的梯度更新次数,有助于模型收敛。如果 batch_size 太大,可能会导致显存不足。如果 batch_size 太小,可能会导致训练不稳定。
可以看出,当超参数batch_size 从128改小为32时,整个GPU的利用率从100%降到75%,说明整个运行过程中运行时间相较而言长了许多。
learning_rate = 0.001
#learning_rate学习率是优化器更新模型参数的步长。作用是控制模型参数在每次更新时的变化幅度。影响模块主要涉及优化器 (optim.Adam)和模型训练。
learning_rate 决定了每次梯度下降时参数更新的幅度。例如,learning_rate=0.001 表示每次更新时,参数值会朝着梯度方向移动 0.001 倍。通常为 0.1、0.01、0.001、0.0001 等,具体取决于模型和任务。较大的 learning_rate 可以加快训练速度,但可能导致模型无法收敛或震荡。较小的 learning_rate 可以使训练更稳定,但可能导致训练速度过慢。
num_epochs = 10
# num_epochs 是模型遍历整个数据集的次数,控制模型训练的总轮数。例如,CIFAR-10 训练集有 50,000 张图像,num_epochs=10 表示模型会遍历整个数据集 10 次。较多的 num_epochs 可以让模型更好地学习数据特征,但可能导致过拟合。较少的 num_epochs 可以加快训练速度,但可能导致模型欠拟合。通常为 10、20、50、100 等,具体取决于数据集规模和模型复杂度。
注解:在深度学习中,超参数是模型训练过程中需要手动设置的参数,它们直接影响模型的训练过程和性能。
num_epochs 是模型遍历整个数据集的次数。作用是控制模型训练的总轮数。
5)数据预处理
transform = transforms.Compose([
transforms.Resize((224,
224)),
# ResNet 需要输入大小为 224x224
transforms.ToTensor(),
transforms.Normalize((0.5,
0.5, 0.5), (0.5, 0.5, 0.5))
# 归一化
])
- transforms.Resize((224, 224)):对于预训练模型,通常需要将输入图像调整为模型期望的大小。数据预处理是深度学习中非常重要的一步,它直接影响模型的训练效果和性能。ResNet 等预训练模型通常需要固定大小的输入(如 224x224)。CIFAR-10 图像的原始大小为 32x32,需要通过 Resize 放大到 224x224。调整图像大小可能会引入一些失真,但对模型性能的影响通常较小。
- transforms.ToTensor():PyTorch 模型期望输入为 Tensor 格式。因此,首先需要将 PIL 图像或 NumPy 数组转换为 PyTorch 的 Tensor 格式。将图像的像素值从 [0, 255] 的整数范围转换为 [0.0, 1.0] 的浮点数范围。PyTorch 的 Tensor,形状为 (C, H, W),数据类型为 torch.float32,因此,需要调整图像的维度顺序为 (C, H, W)(通道、高度、宽度)。转换后的 Tensor 可以直接输入到模型中,几乎所有的图像预处理流程都会包含 ToTensor。
- transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)):对图像的每个通道进行归一化,使数据分布更有利于模型训练。归一化可以将数据分布调整为零均值和单位方差,有助于模型训练。对于预训练模型,归一化参数通常需要与模型训练时使用的参数一致。归一化公式为:output = (input - mean) / std。在这里,mean = (0.5, 0.5, 0.5),std = (0.5, 0.5, 0.5)。归一化后的像素值范围为 [-1.0, 1.0]。
6)加载 CIFAR-10 数据集
在 PyTorch 中,加载 CIFAR-10 数据集非常简单,可以通过 torchvision.datasets.CIFAR10 来实现。以下是对加载 CIFAR-10 数据集的详细解释,包括路径设置、数据集加载方法以及相关参数。
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
root的作用是指定数据集的存储路径。默认值./data,表示当前目录下的 data 文件夹。也可以将以上路径省略的部分补充完整。在 Kaggle 中,通常使用 /kaggle/working 或 /kaggle/input 作为数据存储路径。
train的作用是指定加载训练集还是测试集。取值为True时:加载训练集(50,000 张图像)。取值为False时:加载测试集(10,000 张图像)。downloa作用是指定是否下载数据集。取值为True:如果数据集不存在,则自动下载。为False时,不下载数据集,仅从本地加载。如果数据集已经下载到 root 路径下,则不会重复下载。transform是指定数据预处理操作,在上面的代码中,已经定义了transform的操作。一个 transforms.Compose 对象,包含一系列数据预处理操作(如 Resize、ToTensor、Normalize 等)。如果不指定 transform,数据集将返回原始的 PIL 图像。
其中,加载的CIFAR-10 数据集包含以下内容。
- 训练集: 50,000 张 32x32 的彩色图像,分为 10 个类别。
- 测试集: 10,000 张 32x32 的彩色图像,分为 10 个类别。
- 类别标签: 10 个类别分别为:airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck。
我们将使用 CIFAR-10 数据集,该数据集包含 10 个类别,共 60,000 张 32×32 像素的彩色图像。 以下是该数据集的一些示例图像。
代码运行示例结果如下:
7)创建 DataLoader
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
加载数据集后,通常需要将其转换为 DataLoader,以便在训练时批量加载数据。
- batch_size: 每次加载的样本数量。进行批量加载后的数据就可以用于模型训练和测试。
- shuffle: 是否打乱数据顺序(通常训练集需要打乱,测试集不需要)。
8)加载预训练的 ResNet-50 模型
model = resnet50(pretrained=True)
在 PyTorch 中,加载预训练的 ResNet-50 模型非常简单,可以通过 torchvision.models 模块中的一个函数模块实现。ResNet-50 是一个经典的深度卷积神经网络,包含 50 层(包括卷积层、全连接层等)。其中,pretrained=True:表示加载在 ImageNet 数据集上预训练的权重。如果设置为 False,则加载的模型是未经训练的(随机初始化权重)。
修改最后一层全连接层以适应 CIFAR-10 的 10 个类别:
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 10)
model.fc是 ResNet-50 模型的最后一层全连接层(Fully Connected Layer)。在预训练的 ResNet-50 中,model.fc 的输出维度为 1000(对应 ImageNet 的 1000 个类别)。通过num_ftrs = model.fc.in_features获取全连接层的输入特征数(即 ResNet-50 倒数第二层的输出维度)。对于 ResNet-50,num_ftrs 的值为 2048。再通过model.fc = nn.Linear(num_ftrs, 10)将全连接层替换为一个新的全连接层,输入维度为 num_ftrs,输出维度为 10(对应 CIFAR-10 的 10 个类别)。以上方式的设置即可以理解为在全连接层的到处第二层,通过输入2048个特征信息后通过最后一层网络推理生成10个输出判别结果。这是个即是我们需要的输出结果。
有人可能会问为什么要修改全连接层的最后一层呢?
其一,可能是输出维度不匹配。预训练的 ResNet-50 模型的最后一层全连接层输出维度为 1000(对应 ImageNet 的 1000 个类别)。而对于 CIFAR-10 数据集,输出维度应为 10(对应 10 个类别)。所以这里需要根据需要应用到的数据集来判定具体要多少个输出维度。
其二,是替换全连接层。通过替换最后一层全连接层,可以使模型的输出维度与新任务匹配。
接下来,是将模型移动到可用的 GPU上运行,因为将模型和数据移动到 GPU 后,PyTorch 会自动管理显存,确保计算过程高效运行。
model = model.to(device)
device是一个 torch.device 对象,表示模型和数据应该运行的设备(如 CPU 或 GPU)。例如,device = torch.device(“cuda” if torch.cuda.is_available() else “cpu”)。即是将模型的所有参数和缓冲区移动到指定的设备(如 GPU)。如果 device 是 GPU,模型将在 GPU 上运行,从而加速训练和推理。
9)定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
在深度学习中,损失函数和优化器是模型训练过程中两个非常重要的组件。
nn.CrossEntropyLoss()是 PyTorch 中用于多分类任务的损失函数。它结合了 nn.LogSoftmax() 和 nn.NLLLoss(),适用于输出为类别概率分布的分类任务。
该交叉熵损失函数的输入是实际神经网络预测模型的输出(outputs):形状为 (batch_size, num_classes),表示每个类别的未归一化得分(logits)。真实标签(labels):形状为 (batch_size,),表示每个样本的真实类别索引。
输出则是一个标量值,表示当前批次的平均损失。
optim.Adam()是 PyTorch 中实现 Adam 优化器的函数。Adam 是一种自适应学习率优化算法,结合了动量(Momentum)和自适应学习率的优点。
model.parameters()表示模型中所有需要更新的参数。参数的具体内容包括前向传播中的权重(Weight:存储了层的权重矩阵或卷积核。例如,全连接层的权重矩阵是一个二维矩阵,卷积层的卷积核是一个四维张量)和偏置(Bias:存储了层的偏置向量。例如,全连接层和卷积层的偏置是一个一维向量)。model.parameters() 返回的是一个 生成器(generator),这个生成器包含了模型中所有需要训练的参数(如权重和偏置),每个参数都是一个 torch.Tensor 对象。生成器是惰性求值的,只有在需要时才会生成参数。
lr=0.001学习率(Learning Rate),控制参数更新的步长。学习率过大可能导致训练不稳定,过小可能导致训练速度过慢。
10)训练模型
for epoch in range(num_epochs):
model.train()
running_loss
= 0.0
correct
= 0
total
= 0
epoch: 表示模型遍历整个训练数据集的次数。通过多次遍历数据集,模型可以逐渐学习到数据的特征。每个 epoch 包含一个完整的训练过程(前向传播、损失计算、反向传播和参数更新)。num_epochs 的取值取决于数据集的大小和模型的复杂度,通常为 10、20、50、100 等。例如,num_epochs=10 表示模型将遍历数据集 10 次。
model.train(): 将模型设置为 训练模式。在训练模式下,模型会启用一些特定的行为(如 Dropout 和 Batch Normalization)。比如Dropout层:在训练模式下,Dropout 层会随机丢弃一部分神经元,以防止过拟合。在评估模式下,Dropout 层会禁用随机丢弃,使用所有神经元进行预测。而批量归一化Batch Normalization:在训练模式下,Batch Normalization 层会使用当前批次的均值和方差进行归一化。在评估模式下,Batch Normalization 层会使用训练过程中累积的均值和方差进行归一化。
running_loss = 0.0设置会初始化一个变量 running_loss,用于累积当前 epoch 的总损失。在每个 epoch 结束时,计算平均损失并打印。
#
使用 tqdm 显示进度条
for
images, labels in tqdm(train_loader, desc=f"Epoch {epoch + 1}/{num_epochs}"):
images,
labels = images.to(device), labels.to(device)
以上代码的作用是遍历训练数据加载器 train_loader,每次迭代返回一个批次的图像和标签。使用 tqdm 显示进度条,方便监控训练进度。参数images表示一个批次的图像数据,形状为 (batch_size, channels, height, width)。labels表示一个批次的标签数据,形状为 (batch_size,)。
后面通过 images.to函数将图像和标签数据移动到指定的设备(如 GPU)。device是一个 torch.device 对象,表示模型和数据应该运行的设备(如 cuda 或 cpu)。实际上,前面在检查GPU是否可用的模块中已经说明了如果GPU可用,那么图像将会被移动到可用的CUDA中。
#
前向传播
outputs
= model(images)
loss
= criterion(outputs, labels)
这里通过将输入数据 images 传递给模型,计算模型的输出。这个模型实际就是前面所定义的ResNet50模型,且已经被指定了一些模型参数传递规则。模型的输出outputs,形状为 (batch_size, num_classes),表示每个类别的未归一化得分(logits)。
这里使用损失函数 loss,定义标准criterion 来计算模型的输出与真实标签(这里的真实标签实际就是系统提前标注的真值系统)之间的差异。
#
反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
通过optimizer.zero_grad()清空模型参数的梯度。在每次反向传播之前,需要清空梯度,否则梯度会累积。通过loss.backward()计算损失函数对模型参数的梯度。通过链式法则,梯度从输出层逐层传播到输入层。
通过使用optimizer.step()计算出的梯度更新模型参数。优化器(如 optim.Adam)会根据梯度方向和步长(学习率)调整参数值。前面已经对optimizer的Adam函数进行了定义,这里做step引用可以直接开始运行对应参数设置下的优化函数。
#
统计损失和准确率
running_loss
+= loss.item()
_,
predicted = outputs.max(1)
total
+= labels.size(0)
correct
+= predicted.eq(labels).sum().item()
这里首先将当前批次的损失值累加到running_loss 中,并通过loss.item()将损失值从 Tensor 转换为 Python 浮点数。
outputs 是模型的输出,形状为 (batch_size, num_classes)。假设 outputs 是一个 2x3 的张量(batch_size=2,num_classes=3)。每个样本的输出是一个长度为 num_classes 的向量,表示每个类别的未归一化得分(logits)。
outputs.max(1) 返回每个样本的最大值及其索引,predicted 是预测的类别索引。返回两个值:
1.最大值(_,未使用)。
2.最大值的索引(predicted,即预测的类别索引)。
total += labels.size(0)中的labels 是当前批次的真实标签,形状为 (batch_size,)。每个元素是一个整数,表示样本的真实类别索引。
labels.size(0)表示获取当前批次的样本数(即 batch_size)。例如,如果 labels 的形状是 (64,),则 labels.size(0) 的值为 64。total += labels.size(0)将当前批次的样本数累加到 total 中。total 用于统计测试集的总样本数。
最后,通过比较 predicted 和 labels,返回一个布尔张量,表示每个样本的预测是否正确。predicted.eq(labels).sum()是对布尔张量求和,统计预测正确的样本数。predicted.eq(labels).sum().item()将 Tensor 转换为 Python 整数。
correct += predicted.eq(labels).sum().item()将当前批次中预测正确的样本数累加到correct中。correct用于统计测试集中预测正确的总样本数。
#
打印训练结果
train_loss
= running_loss / len(train_loader)
train_acc
= 100.0 * correct / total
print(f"Epoch
[{epoch + 1}/{num_epochs}], Loss: {train_loss:.4f}, Accuracy: {train_acc:.2f}%")
- running_loss / len(train_loader):当前 epoch 的总损失除以批次数,得到平均损失。
- 100 * correct / total:表示模型在测试集上的准确率。
如下表示了整个运行结果代码。
每次对整个训练数据集的进行遍历过程中,打印模型进度条,同时每次遍历的结果返回不同的运行误差结果。可以看到通过迭代次数的增加,误差值越来越小了。说明遍历模型训练的次数越多,整个训练过程得到的结果将不断的接近于真实值,误差将越来越小。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。