torch FashionMNIST数据集导出图片

import numpy as np
import struct
 
from PIL import Image
import os

path_home='./data/FashionMNIST/raw/'
data_file = path_home+'train-images-idx3-ubyte'
# It's 47040016B, but we should set to 47040000B
data_file_size = 47040016
data_file_size = str(data_file_size - 16) + 'B'
 
data_buf = open(data_file, 'rb').read()
 
magic, numImages, numRows, numColumns = struct.unpack_from(
    '>IIII', data_buf, 0)
datas = struct.unpack_from(
    '>' + data_file_size, data_buf, struct.calcsize('>IIII'))
datas = np.array(datas).astype(np.uint8).reshape(
    numImages, 1, numRows, numColumns)
 
label_file = path_home+'train-labels-idx1-ubyte'
 
# It's 60008B, but we should set to 60000B
label_file_size = 60008
label_file_size = str(label_file_size - 8) + 'B'
 
label_buf = open(label_file, 'rb').read()
 
magic, numLabels = struct.unpack_from('>II', label_buf, 0)
labels = struct.unpack_from(
    '>' + label_file_size, label_buf, struct.calcsize('>II'))
labels = np.array(labels).astype(np.int64)
 
datas_root = 'mnist_train'
if not os.path.exists(datas_root):
    os.mkdir(datas_root)
 
for i in range(10):
    file_name = datas_root + os.sep + str(i)
    if not os.path.exists(file_name):
        os.mkdir(file_name)
 
for ii in range(numLabels):
    img = Image.fromarray(datas[ii, 0, 0:28, 0:28])
    label = labels[ii]
    file_name = datas_root + os.sep + str(label) + os.sep + \
        'mnist_train_' + str(ii) + '.png'
    img.save(file_name)

torch自定义数据集模型训练demo

import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader
from torch import nn
import os
import pandas as pd
from torchvision.io import decode_image


device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else "cpu"
#  独热数据逆转化 ,本例独热化非必须
def arc_one_hot(x,list=torch.tensor([0,1,2,3,4,5,6,7,8,9],dtype=torch.float).to(device)):
    return x@list
#  1.创建自定义数据集
class CustomImageDataset(Dataset):
    def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
        self.img_labels = pd.read_csv(annotations_file, header=None) # 注意首行默认会被作为标题行忽略,或者设置header=None 
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform

    def __len__(self):
        return len(self.img_labels)

    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        #print(img_path)
        image = decode_image(img_path).float().div(255) #需要转成float类型,否则无法训练
        #print(image.shape)
        label = self.img_labels.iloc[idx, 1]
        #print(label)
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        #独热化
        # print(label)
        new_transform = Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(dim=0, index=torch.tensor(y), value=1))
        label = new_transform(label)
        # print("------fuck")
        # print(label)
        return image, label
    

# csv注意是否有标题行
csv_path='/Users/mnist_test_cus_data/imglist_train.csv'
img_dir='/Users/mnist_test_cus_data/imgs_train/'
batch_size = 64
# 创建自定义数据集实例
mydataset = CustomImageDataset(annotations_file=csv_path, img_dir=img_dir, transform=None, target_transform=None)

# 使用 DataLoader 加载数据
mydataloader = DataLoader(mydataset, batch_size, shuffle=True, num_workers=0) #, num_workers=4 macos报错
print(len(mydataloader))
print(len(mydataloader.dataset))
# print(mydataset[59999])
# print(mydataset[0][0])
# print(mydataset[0][1])
# exit()

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
    target_transform = Lambda(lambda y: torch.zeros(10,dtype=torch.float).scatter_(dim=0, index=torch.tensor(y), value=1))
)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

# 遍历 DataLoader
#for batch in mydataloader:
#    images, labels = batch
    #print(images.size(), labels.size())
    #print(images)
    #print(labels)

for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {X.shape}")
    print(f"Shape of y: {y.shape} {y.dtype}")

    # print(X)
    # print(y)
    # print(arc_one_hot(y.to(device)))

    break
print(len(mydataloader))
# exit()


#  2. 可视化数据
def showdata():
    labels_map = {
        0: "T-Shirt",
        1: "Trouser",
        2: "Pullover",
        3: "Dress",
        4: "Coat",
        5: "Sandal",
        6: "Shirt",
        7: "Sneaker",
        8: "Bag",
        9: "Ankle Boot",
    }
    figure = plt.figure(figsize=(8, 8))
    cols, rows = 3, 3
    xxx=''
    for i in range(1, cols * rows + 1):
        sample_idx = torch.randint(len(mydataset), size=(1,)).item()
        img, label = mydataset[sample_idx]
        figure.add_subplot(rows, cols, i)
        # 独热逆转化
        label=arc_one_hot(label.to(device)).item()
        plt.title(labels_map[label])
        plt.axis("off")
        xxx=img
        plt.imshow(img.squeeze(), cmap="gray")
    plt.show()
    print(xxx.shape)
    print('------')
    print(xxx.squeeze().shape)

    # Display image and label.
    train_features, train_labels = next(iter(mydataloader))
    print(f"Feature batch shape: {train_features.size()}")
    print(f"Labels batch shape: {train_labels.size()}")
    img = train_features[0].squeeze()
    label = train_labels[0]
    plt.imshow(img, cmap="gray")
    plt.show()
    print(f"Label: {label}")
    # exit()


# 3.定义模型

print(f"Using {device} device")

# Define model
class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten() #维度展平
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10)
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork().to(device)
print(model)

# 4. 定义损失函数和优化器
loss_fn = nn.CrossEntropyLoss() #交叉熵
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

# 5. 训练
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    print("size="+str(size))
    model.train() # 启用 Batch Normalization 和 Dropout,归一化,随机丢弃神经元防止过拟合,测试时不丢弃
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)
        # Compute prediction error
        pred = model(X)
        # print("---------->pred=")
        # print(pred)
        # print(y)
        # print("-----------------------<")
        # 不需要独热逆转化,交叉熵计算过程包含了独热编码,但是不仍然可以使用独热参数
        # y=arc_one_hot(y)
        loss = loss_fn(pred, y)

        # Backpropagation
        loss.backward() # 计算梯度
        optimizer.step() # 根据梯度优化参数
        optimizer.zero_grad() # 梯度归零

        if batch % 100 == 0: # 每100个batch打印一次
            loss, current = loss.item(), (batch + 1) * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")
        # exit()
# 6. 测试
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            #print(y)
            #不需要独热逆编码
            #y=arc_one_hot(y)
            #print(y)
            pred = model(X)
            #print(pred)
            test_loss += loss_fn(pred, y).item()
            #统计个数
            # >>> xx==zz
            # tensor([ True, False, False,  True, False,  True, False,  True, False, False,
            #          True, False, False,  True, False, False,  True, False,  True, False,
            #          True, False, False, False, False,  True,  True, False,  True, False,
            #         False,  True, False, False, False, False, False, False,  True,  True,
            #         False, False, False,  True, False, False,  True, False, False,  True,
            #         False,  True, False,  True,  True, False, False, False, False,  True,
            #         False,  True,  True,  True])
            # >>> (xx==zz).type(torch.float)
            # tensor([1., 0., 0., 1., 0., 1., 0., 1., 0., 0., 1., 0., 0., 1., 0., 0., 1., 0.,
            #         1., 0., 1., 0., 0., 0., 0., 1., 1., 0., 1., 0., 0., 1., 0., 0., 0., 0.,
            #         0., 0., 1., 1., 0., 0., 0., 1., 0., 0., 1., 0., 0., 1., 0., 1., 0., 1.,
            #         1., 0., 0., 0., 0., 1., 0., 1., 1., 1.])
            # >>> (xx==zz).type(torch.float).sum()
            # tensor(25.)
            # >>> (xx==zz).type(torch.float).sum().item()
            # 25.0
            yy=arc_one_hot(y)
            correct += (pred.argmax(1) == yy).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

#  7. 训练和测试
def do_train():
    epochs = 5
    for t in range(epochs):
        print(f"Epoch {t+1}\n-------------------------------")
        train(mydataloader, model, loss_fn, optimizer)
        test(test_dataloader, model, loss_fn)
    print("Done!")
    __save_model__()

# for var_name in model.state_dict():
#     print(var_name, "\t", model.state_dict()[var_name])

# for var_name in optimizer.state_dict():
#     print(var_name, "\t", optimizer.state_dict()[var_name])

#  8. 保存模型
def __save_model__():
    path="model.pth"
    torch.save(model.state_dict(), path)
    print("Saved PyTorch Model State to "+path)
#  9. 加载模型
def load_model():
    model = NeuralNetwork().to(device)
    model.load_state_dict(torch.load("model.pth", weights_only=True))
    return model
#  10. 测试模型
def  test_model():
    model = load_model()
    classes = [
        "T-shirt/top",
        "Trouser",
        "Pullover",
        "Dress",
        "Coat",
        "Sandal",
        "Shirt",
        "Sneaker",
        "Bag",
        "Ankle boot",
    ]

    model.eval()
    x, y = test_data[0][0], test_data[0][1]
    with torch.no_grad():
        x = x.to(device)
        pred = model(x)
        # 独热转化,同device才能计算
        y=arc_one_hot(y.to(device)).int()
        print(y)

        print(f"Predicted: {pred[0].argmax(0)}, Actual: {y}")
        predicted, actual = classes[pred[0].argmax(0)], classes[y]
        print(f'Predicted: "{predicted}", Actual: "{actual}"')

def  do_test_model():
    load_model()
    test_model()
def do_train_model():
    showdata()
    do_train()
    test_model()
def main():
    do_train_model()
    #do_test_model()
    

if __name__ == '__main__':
    main()

torch 张量

张量是一种特殊的数据结构,与数组和矩阵非常相似。在 PyTorch 中,我们使用张量来编码模型的输入和输出,以及模型的参数。

张量类似于 NumPy 的 ndarray,不同之处在于张量可以在 GPU 或其他硬件加速器上运行。实际上,张量和 NumPy 数组通常可以共享底层内存,从而无需复制数据(详见与 NumPy 的桥接)。张量还针对自动微分进行了优化(我们将在后面的 Autograd 部分详细介绍)。如果您熟悉 ndarrays,您会很快适应 Tensor API。如果不熟悉,请继续阅读!

import torch
import numpy as np

初始化张量

张量可以通过多种方式进行初始化。请看以下示例

直接从数据创建

张量可以直接从数据创建。数据类型会自动推断。

data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)

从 NumPy 数组创建

张量可以从 NumPy 数组创建(反之亦然 – 详见与 NumPy 的桥接)。

np_array = np.array(data)
x_np = torch.from_numpy(np_array)

继续阅读“torch 张量”

torch 快速入门

Quickstart

This section runs through the API for common tasks in machine learning. Refer to the links in each section to dive deeper.

Working with data

PyTorch has two primitives to work with datatorch.utils.data.DataLoaderand torch.utils.data.DatasetDataset stores the samples and their corresponding labels, and DataLoader wraps an iterable around the Dataset.

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

PyTorch offers domain-specific libraries such as TorchTextTorchVision, andTorchAudio, all of which include datasets. For this tutorial, we will be using a TorchVision dataset.

The torchvision.datasets module contains Dataset objects for many real-world vision data like CIFAR, COCO (full list here). In this tutorial, we use the FashionMNIST dataset. Every TorchVision Dataset includes two arguments:transform and target_transform to modify the samples and labels respectively.

# Download training data from open datasets.
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)
print(len(training_data))
60000
继续阅读“torch 快速入门”

梯度、散度、旋度

0、哈密顿算子

1、梯度(Gradient)是矢量,也是法向量

2、散度(Divergence)是标量

3、旋度(Curl)是向量

  • 标量的梯度为矢量,因此对该矢量可以继续求散度,从而引入拉普拉斯算子∇2 :
  • 矢量的散度为标量,因此对该标量可以继续求梯度:

拉普拉斯算子对标量的运算结果为标量、对矢量的运算结果为矢量。

举例:

电势场的梯度是电场强度,电场强度的的散度等于q/ε,高斯定理

AI什么是模型?什么是参数?什么是大模型?什么是通用模型?什么是推理模型?

一、模型是什么?

(一)、核心定义:

在人工智能(AI)中,模型(Model) 是一个核心概念,可以理解为一种数学工具或计算框架,它通过学习(调整内部参数)数据中的规律,将输入信息转化为有意义的输出结果。简单来说,模型是AI的“大脑”,负责处理问题并给出答案,但它本质上只是一套复杂的数学规则(数学函数),而非真正的意识或智慧。

理解模型的概念,是区分AI技术能力与科幻幻想的关键——它强大但有限,是工具而非生命。

(二)、目标

  • 从已知数据中捕捉隐藏的规律,从而对未知数据做出合理推断。

(三)、通俗理解:菜谱

  • 模型 ≈ 菜谱的步骤
  • 参数 ≈ 调料的比例(盐放多少、火候大小)
  • 数据 ≈ 食材、调料
  • 训练 ≈ 通过多次试做(学习)调整调料(参数)比例,直到菜肴味道达标。

(四)、常见类型

  • 简单模型
  • 如:线性回归 y=wx+b
  • 参数少(仅斜率w 和截距b),适用于数据关系简单的问题(如预测房价与面积的关系)。
  • 复杂模型
  • 如:深度神经网络(如GPT-4、ResNet)
  • 参数可达数十亿,通过多层非线性计算捕捉复杂模式(如语言生成、图像识别)。

(五)、模型如何“学习”?

  • 初始化:模型参数随机设定(类似“蒙题”)。
  • 试错:用输入数据计算输出,对比正确答案计算误差(如预测错误时)。
  • 调整:通过优化算法(如梯度下降)更新参数,减少误差。
  • 收敛:反复迭代后,参数稳定到能较好拟合数据的值。

(六)、模型的关键特性

  • 泛化能力:模型在未知数据上的表现(避免“死记硬背”训练数据)。
  • 可解释性:简单模型(如线性回归)容易理解,复杂模型(如深度学习)常被视为“黑箱”。
  • 计算成本:参数越多,模型越强大,但需要更多算力和数据。

(七)、模型的局限性

  • 数据依赖:模型的表现高度依赖训练数据的质量和多样性(“垃圾进,垃圾出”)。
  • 无真实理解:即使模型能生成流畅文本,也不理解语言的含义(如ChatGPT不知道“苹果”是水果还是公司)。
  • 静态知识:传统模型的知识截止于训练数据的时间点(需定期重新训练)。
继续阅读“AI什么是模型?什么是参数?什么是大模型?什么是通用模型?什么是推理模型?”

AI是什么,真的会思考吗?

一、AI是什么?

人工智能(Artificial Intelligence),英文缩写为AI

AI是通过计算机系统模拟人类智能的技术,能够执行通常需要人类智能的任务,如学习、推理、问题解决和语言理解。

二、AI真的会思考吗?

1、AI的“思考”本质是模式匹配

AI的“智能”本质是对人类行为的统计学模仿,而非真正的思考。

它像一面高度复杂的镜子,反射出人类知识和语言模式,但没有自我意识。

理解这一点,既能欣赏AI技术的强大,也能避免对它的过度神话或恐惧。

  • 数据驱动:AI(如DeepSeek、ChatGPT)通过分析海量数据中的统计规律,学习如何回答问题或生成文本。
    例如,它发现“天空”常与“蓝色”“云朵”等词共现,便学会在特定上下文中使用这些词。
  • 无理解能力:AI并不理解“天空为什么是蓝色”,它只是根据训练数据中人类对类似问题的回答模式,
    组合出合理的文本。就像一台高级的“拼图机器”,按规则拼接已知碎片。

2、AI的“决策”是数学优化

目标函数驱动:AI的行为受预设的数学目标控制,如:语言模型:目标是最佳化“预测下一个词的概率”。围棋AI:目标是“最大化胜率”。

无主观意图:AI不会自主设定目标(如“我想赢”),所有行为都是通过梯度下降等算法,向预设的数学目标逼近。

继续阅读“AI是什么,真的会思考吗?”

深度学习什么是模型又在训练什么?

深度学习是机器学习的一个分支,它主要通过使用称为神经网络的复杂结构来学习数据的表征。在深度学习中,”训练”和”模型”是两个核心概念。

训练

在深度学习中,”训练”是指用数据来训练一个神经网络。这个过程涉及以下几个步骤:

  • 输入数据: 这些数据可以是图片、文本、声音或其他任何形式的信息。对于不同类型的问题,输入数据的形式会有所不同。
  • 标签: 在监督学习中,每个输入数据通常都会有一个对应的标签,这个标签是我们想要模型预测的目标。
  • 学习过程: 在这个过程中,神经网络通过调整其内部参数(通常是权重和偏置)来尝试正确地预测输入数据的标签。
  • 损失函数: 用于衡量模型的预测结果和实际标签之间的差异。训练的目标是最小化这个损失函数。
  • 优化算法: 如梯度下降,用于调整网络参数以最小化损失函数。
  • 迭代过程: 整个训练过程是迭代的,通常需要多次遍历训练数据集,这些遍历称为”epoch”。
继续阅读“深度学习什么是模型又在训练什么?”

开源深度学习框架PyTorch

什么是 PyTorch?

PyTorch 是一个基于软件的开源深度学习框架,用于构建神经网络,将 Torch 的机器学习 (ML) 库与基于 Python 的高级 API 相结合。它的灵活性和易用性以及其他优点使其成为学术和研究界领先的机器学习框架。

PyTorch 支持 多种神经网络架构,从简单的线性回归算法到复杂的卷积神经网络和用于计算机视觉和自然语言处理 (NLP) 等任务的生成式转换器模型。PyTorch 基于广为人知的 Python 编程语言构建,并提供广泛的预配置(甚至预训练)模型库,使数据科学家能够构建和运行复杂的深度学习网络,同时最大限度地减少在代码和数学结构上花费的时间和精力

继续阅读“开源深度学习框架PyTorch”

卷积神经网络(分类网络)

卷积神经网络是一种前馈神经网络,用于图片分类的卷积网络一般包含两部分:卷积部分和全链接部分。

卷积部分将传统的卷积操作中卷积核的值当成了训练的对象,并加入了池化层,激活层,专门用来提取图片特征。全链接部分就是普通的神经网络,前面以图片特征为输入,后面加上softmax层来输出每个类的概率。

继续阅读“卷积神经网络(分类网络)”