人工智能学习总结blog3(Torch和PyTorch)

Google 推出并开源 TensorFlow,

Facebook 主导 PyTorch 和 Caffe 2,

Amazon 选择 MXNet,

微软开发并大力推广 CNTK,

Deeplearning4j是当前最大、最流行的基于JAVA的深度学习框架。

Torch 是一个基于Lua 编程语言的科学计算框架,主要用于深度学习研究。在 Torch 中,所有的数据都可以被表示为多维张量(tensor),并且支持自动求导。

Torch 同时也提供了一些常见的深度学习模型和优化算法的实现。而PyTorch 则是一个完整的深度学习框架,以计算图为核心,提供了完善的模型定义、训练、推理等功能。

torch是PyTorch 默认的数据结构库,其提供了多种张量操作函数,包括 torch.Tensor,torch.nn,torch.optim 等模块。

在PyTorch中使用torch库创建 Tensor、执行张量运算等,是PyTorch框架使用了Torch模块(依赖)

Tensor(张量)是 Torch 中最常见的数据结构,类似于 Numpy 中的数组,可以表示多维数据。Tensor 可以在 CPU 和 GPU 上进行计算,也支持自动求导。

Autograd(自动求导)是 Torch 中的自动微分引擎,用于计算梯度。Autograd 在记录 Tensor 上的所有操作,并构建一个有向无环图(DAG),在反向传播时自动计算梯度。

定义模型、损失函数、优化器

Module (模型) 在Torch中,可以通过继承 torch.nn.Module 类来定义自己的深度学习模型。torch.nn.Module 定义了神经网络模型的基本结构和行为。

所有自定义的神经网络模型类都应该继承自 torch.nn.Module。这样做的好处是:

继承 torch.nn.Module 可以使得您的模型具有 PyTorch 框架所提供的许多便利功能,如参数管理、梯度计算和反向传播等。

您可以重写 torch.nn.Module 中定义的一些方法,如 forward() 方法,来实现自己的前向传播逻辑。

torch.nn.Module 提供了一些有用的属性和方法,例如 parameters() 和 state_dict() 等,可以帮助您管理和保存模型。

Optimizer(优化器)是 Torch 中用于优化模型参数的算法。常用的优化器包括随机梯度下降(SGD)、Adam、Adagrad 等。

lossFuction(损失函数) 就是计算误差

训练模型

trainloader 表示用于载入训练数据的迭代器对象。在每一轮训练中,先将梯度清零(optimizer.zero_grad()),

然后进行模型的正向传播(model(inputs)),接着计算损失(loss_fn(outputs, labels)),

再进行反向传播计算梯度(loss.backward()),

最后调用优化器的 step() 方法更新模型参数。

注意:只有形状为标量的 Tensor(例如单个数值),才能调用 backword() 方法计算梯度,对于其他形状的 Tensor,需要对其中一个元素进行求和操作。

总结

1、Tensor:Torch中最常见的数据结构 Tensor,Tensor 的创建、形状、数据类型以及如何在 CPU 和 GPU 上进行计算。

2、Autograd:Torch的自动求导引擎 Autograd,backward() 方法计算梯度。

3、Optimizer:Torch 中如何定义优化器,如何在训练循环中使用优化器。

4、模型定义:继承 torch.nn.Module 类定义深度学习模型,在 init () 方法中定义网络结构,在 forward() 方法中定义前向计算流程。

5、模型训练:定义损失函数和优化器,调用前向传播、反向传播函数,使用优化器更新模型参数。

6、模型保存和加载:将训练好的模型保存到文件,并在之后的使用中加载模型以进行预测。

7、模型评估:使用训练好的模型计算测试集的准确率。

复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data import DataLoader  # 需要导入 DataLoader

# 1、加载数据集(先准备好训练的数据,标注,格式,归一化等)
# 在 Torch 中,可以使用 torchvision 模块来载入常用的数据集,例如 MNIST、CIFAR-10 等。
# Define the transform to normalize the data
# 定义数据预处理方法 导入必要的 PyTorch 模块和数据集。
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))])

# Download and load the MNIST dataset
# 下载和加载 MNIST 手写数字数据集
trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
testset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

# Use DataLoader for batching
trainloader = DataLoader(trainset, batch_size=64, shuffle=True)  # 定义训练数据加载器

# 2 定义模型、损失函数、优化器
# 2.1 定义模型 Net类继承自torch.nn.Module,并定义了3个全连接层(self.fc1 和 self.fc2,self.fc3)。
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = torch.nn.Linear(28 * 28, 128) # 输入层
        self.fc2 = torch.nn.Linear(128, 64) # 隐含层
        self.fc3 = torch.nn.Linear(64, 10) # 输出层

    def forward(self, x):
        x = x.view(-1, 28 * 28) # 将输入数据展开成一维向量
        x = torch.nn.functional.relu(self.fc1(x)) # ReLU 激活函数,第一层网络
        x = torch.nn.functional.relu(self.fc2(x)) # ReLU 激活函数,第二层网络
        x = self.fc3(x) # 输出层
        return x

model = Net()

num_epochs=5
# 2.2 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()
# 2.3 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# 3 训练模型
for epoch in range(num_epochs):
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):  # 使用 trainloader 进行迭代
        inputs, labels = data
        optimizer.zero_grad()             # 清空梯度
        outputs = model(inputs)           # 正向传播
        loss = loss_fn(outputs, labels)   # 计算误差,损失函数
        loss.backward()                   # 反向传播
        optimizer.step()                  # 优化参数

        running_loss += loss.item()
        if i % 1000 == 999:    # 每1000个数据样本批次打印一次运行损失
            print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 1000))
            running_loss = 0.0

print('Finished Training')


# 4 保存模型
torch.save(model.state_dict(), 'model.pt')

"""
4.2 加载模型
model = Net()
model.load_state_dict(torch.load('model.pt'))
"""

# 5 模型测试
## torch.no_grad() 表示在测试过程中不需要计算梯度。对于每个测试样本,计算模型输出并取预测结果的最大值(predicted),
## 然后统计预测正确的样本数量和总样本数量,最后计算准确率。
correct = 0
total = 0
with torch.no_grad():
    for data in trainloader:  # 使用 testloader 进行迭代
        images, labels = data
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
        100 * correct / total))

ubyte数据文件的解释

复制代码
import numpy as np
import struct
import matplotlib.pyplot as plt

"""
idx3-ubyte 表示这是一个三维数组的 ubyte (unsigned byte) 格式数据(图片数据)。
idx1-ubyte 表示这是一个一维数组的 ubyte 格式数据(标签)。


train-images-idx3-ubyte 文件按照以下格式保存:
1.文件头
前 4 个字节表示魔数 0x00000803(以小端字节序存储),表示 3 维数组的 ubyte 格式。
接下来 4 个字节表示图像数量 60000。
再接下来 4 个字节表示行数 28。
最后 4 个字节表示列数 28。

2.图像数据
文件头之后的数据部分就是所有图像的像素值。
每个图像的像素值是按照行优先的顺序依次存储的。
每个像素值都是一个 8 位无符号整数(0-255)。
"""

def decode_idx3_ubyte(idx3_ubyte_file):
    """
    解析idx3文件的通用函数
    :param idx3_ubyte_file: idx3文件路径
    :return: 数据集
    """
    # 读取二进制数据
    bin_data = open(idx3_ubyte_file, 'rb').read()

    # 解析文件头信息,依次为魔数、图片数量、每张图片高、每张图片宽
    offset = 0
    fmt_header = '>iiii'
    magic_number, num_images, num_rows, num_cols = struct.unpack_from(fmt_header, bin_data, offset)
    print ('魔数:%d, 图片数量: %d张, 图片大小: %d*%d' % (magic_number, num_images, num_rows, num_cols))

    # 解析数据集
    image_size = num_rows * num_cols
    offset += struct.calcsize(fmt_header)
    fmt_image = '>' + str(image_size) + 'B'
    images = np.empty((num_images, num_rows, num_cols))
    for i in range(num_images):
        if (i + 1) % 10000 == 0:
            print ('已解析 %d' % (i + 1) + '张')
        images[i] = np.array(struct.unpack_from(fmt_image, bin_data, offset)).reshape((num_rows, num_cols))
        offset += struct.calcsize(fmt_image)
    return images


def decode_idx1_ubyte(idx1_ubyte_file):
    """
    解析idx1文件的通用函数
    :param idx1_ubyte_file: idx1文件路径
    :return: 数据集
    """
    # 读取二进制数据
    bin_data = open(idx1_ubyte_file, 'rb').read()

    # 解析文件头信息,依次为魔数和标签数
    offset = 0
    fmt_header = '>ii'
    magic_number, num_images = struct.unpack_from(fmt_header, bin_data, offset)
    print ('魔数:%d, 图片数量: %d张' % (magic_number, num_images))

    # 解析数据集
    offset += struct.calcsize(fmt_header)
    fmt_image = '>B'
    labels = np.empty(num_images)
    for i in range(num_images):
        if (i + 1) % 10000 == 0:
            print ('已解析 %d' % (i + 1) + '张')
        labels[i] = struct.unpack_from(fmt_image, bin_data, offset)[0]
        offset += struct.calcsize(fmt_image)
    return labels

if __name__ == '__main__':
    # 假设文件位于当前目录下
    filename = r'F:\pyprojects\yolov10\study\data\MNIST\raw\t10k-images-idx3-ubyte'

    # 查看一张图片, 设置 NumPy 数组的打印格式
    train_images = decode_idx3_ubyte(filename)
    np.set_printoptions(linewidth=200, formatter={'int':'{:3d} '.format})
    print(train_images[0])

    plt.imshow(train_images[0], cmap='gray')
    plt.show()
相关推荐
世人万千丶4 小时前
鸿蒙日志体系高级应用:HiLog分级输出/隐私脱敏/远程日志采集/线上问题精准溯源方案
学习·harmonyos·鸿蒙
奔跑中的小象4 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南4 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang4 小时前
LangGraph 状态机实战
人工智能
刹那芳华19925 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作5 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门5 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜5 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟5 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦5 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能