从PyTorch官方的一篇教程说开去(5 - 神经网络 torch.nn)

神经网络长啥样?有没有四只眼睛八条腿?

借图镇楼 -

真的是非常经典,可以给下面的解释省掉很多力气。

分3个维度阐述 -

1)输入数据集。假如你自己去微调一下大模型就知道,最开始的一步就是要准备(足够大的)数据集,比如百度就要求1kw条+的数据集,否则就不给你训练。PyTorch官方的数据集是用的著名的FashionMNIST,这是一个由许多28pixel * 28pixel的黑白像素组成的图片(img),类似于windows中的缩略图,每一个图片有标记(label),以及序号(idx)。

感兴趣的您也可以自行下载,下载来的是压缩格式.gz,里面图片是用PIL格式存储的单一二进制文件。如果想看看这些黑白缩略图长啥样呢,可以下载和渲染看看 -

python 复制代码
import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt

training_data = datasets.FashionMNIST(
    root="drive/MyDrive/",
    train=True,
    download=True,
    transform=ToTensor()
)

test_data = datasets.FashionMNIST(
    root="drive/MyDrive/",
    train=False,
    download=True,
    transform=ToTensor()
)
python 复制代码
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
for i in range(1, cols * rows + 1):
    sample_idx = torch.randint(len(training_data), size=(1,)).item()
    print(sample_idx)
    img, label = training_data[sample_idx]
    figure.add_subplot(rows, cols, i)
    plt.title(labels_map[label])
    plt.axis("off")
    plt.imshow(img.squeeze(), cmap="gray")
plt.show()

2)输入有了。对于以上数据集,那就是一大堆784的数组或者列表。你需要把这个转化为1x784的tensor张量或者矢量或者向量,被称为flatten层,也就是把所有信息一维化或者叫扁平化。tensor这个词我们回头专门讨论一下,现在理解为多维数组就好。

那接下来整几层网络?分别干啥用?每一层多少个神经元?最后的输出咋整?

python 复制代码
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

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

y=nn.Linear(28*28, 512)
print(y,"\n")
z=nn.ReLU(y)
print(z,"\n")

以上是官方的代码,初始化第二层用了512,这个用来存储输出的特征数量,那么784个数用512个特征是否足够表达呢?会不会欠拟合or过拟合呢?这个就完全是经验值了,或者说,要根据你特定的场景或者模型来跑跑看了。反正本例中,每个输入图像通过这个层后,会被转换成一个包含512个数值的向量。中间的隐藏层,是为了方便把输入过渡到输出,你把数字换成1024也完全没有毛病(有可能你的显卡会对你提出抗议,给你穿个小鞋啥的)

本例的输出是为了统计图像的类别,类别一共有10类,从0-T-shirt到9-踝靴,所以输出用10位来表达足够,这里采用了一种被成为one-hot编码的常用的数据表示方法,One-hot编码将分类数据表示为二进制(0和1)的格式,其中每个类别由一个唯一的二进制向量表示,该向量的长度等于类别的总数。例如,假设我们有一个包含三个可能类别的数据集:A、B和C。我们可以用以下one-hot编码表示它们:

  • 类别 A: 1, 0, 0
  • 类别 B: 0, 1, 0
  • 类别 C: 0, 0, 1

3)综上,我们根据输入输出的形式,设计了一个4层(线性化+输入层,隐藏中间层1,隐藏中间层2,输出层)。现在问题来了,这个稚嫩的神经网络怎么干活呢?它怎么不断的学习和奖惩,从而准确的看到个图就报出类别名呢?

因为用了torch库,所以一些细节在代码中被隐藏了。

比如,为了把784个像素和512个特征值对应起来,其实隐含生成了一个权重矩阵和偏置向量。权重是一个矩阵,其行数等于输出特征数(512),列数等于输入特征数(784)。偏置是一个长度为输出特征数(512)的向量。

这个就和上一章节中我们讨论过的玩游戏的AI的脑子对应上了。我们需要初始化权重矩阵(全0或者全1),和偏置向量(从0或者1开始)。然后使用贪婪算法和梯度下降算法,不断的迭代优化。

呃,还漏了一点,激活函数ReLU(),这个是为了让我们的初始化和迭代过程更加平滑一点,避免0或者1产生一些诸如"死亡神经元"之类的算法缺陷(即当输入为负时,梯度为零,导致部分神经元停止更新。)。激活函数有很多种,默认的是f(x) = max(0, x),也就是在x大于0时直接输出x,小于0时输出0。它简单且计算效率高,是当前最流行的激活函数之一,尤其适用于隐藏层。其实可以选择的激活函数还有很多,比如Tanh,Exponential,Sigmoid等等。

相关推荐
只是甲6 小时前
Text2SQL 系列博客 02:技术原理深度剖析 - 从自然语言到 SQL 的完整链路
人工智能·text2sql·nl2sql·ai agent·自助数据分析·data agent·agentic 数据洞察
懷淰メ6 小时前
【AI赋能】基于PyQt+YOLO+DeepSeek水上漂浮物检测系统(详细介绍)
人工智能·yolo·目标检测·计算机视觉·pyqt·漂浮物·水上漂浮物
EQUINOX16 小时前
【论文精读】| CLIP精读
大数据·人工智能
PC2005-cloud7 小时前
博文已索引但不展示:一次 Bing SEO 问题排查记录
服务器·人工智能
weixin_408099677 小时前
2026 图片去文字 API 实战:AI一键去除图片文字(附 Python / Java / PHP / JS 完整代码)
人工智能·api接口·图片去水印·石榴智能·ai图像修复·图片去文字
幻影123!7 小时前
从零训练一个会下五子棋的AI
python·深度学习·神经网络·强化学习·五子棋·alpha zero·mokugo
greenbbLV7 小时前
2026节日慰问品政策解读:合规标准升级与福利行业新趋势
人工智能·节日
奈斯先生Vector7 小时前
告别工具碎片化:基于 Nano Banana 全模态 AI 聚合架构搭建“文本-图像-视频”自动化协同生产线
运维·数据库·人工智能·架构·自动化·aigc·音视频
领麦微红外7 小时前
国产MEMS红外测温传感器:传感器+算法+产品级出厂标定一站式交付模式深度解读
人工智能·硬件工程·产品经理
mingo_敏8 小时前
DeepAgents : 检索(Retrieval)
人工智能·深度学习·langchain