PyTorch 框架实现多层感知机(MLP):手写数字分类全流程详解

系列文章目录

Pytorch基础篇

01-PyTorch新手必看:张量是什么?5 分钟教你快速创建张量!
02-张量运算真简单!PyTorch 数值计算操作完全指南
03-Numpy 还是 PyTorch?张量与 Numpy 的神奇转换技巧
04-揭秘数据处理神器:PyTorch 张量拼接与拆分实用技巧
05-深度学习从索引开始:PyTorch 张量索引与切片最全解析
06-张量形状任意改!PyTorch reshape、transpose 操作超详细教程
07-深入解读 PyTorch 张量运算:6 大核心函数全面解析,代码示例一步到位!
08-自动微分到底有多强?PyTorch 自动求导机制深度解析

Pytorch实战篇

09-从零手写线性回归模型:PyTorch 实现深度学习入门教程
10-PyTorch 框架实现线性回归:从数据预处理到模型训练全流程
11-PyTorch 框架实现逻辑回归:从数据预处理到模型训练全流程

12-PyTorch 框架实现多层感知机(MLP):手写数字分类全流程详解


文章目录

  • 系列文章目录
  • 前言
  • 一、简单全连接神经网络的搭建
    • [1.1 什么是全连接神经网络?](#1.1 什么是全连接神经网络?)
    • [1.2 使用 PyTorch 搭建简单网络](#1.2 使用 PyTorch 搭建简单网络)
      • [1.2.1 示例代码:构建两层全连接网络](#1.2.1 示例代码:构建两层全连接网络)
      • [1.2.2 输出结果](#1.2.2 输出结果)
      • [1.2.3 代码解析](#1.2.3 代码解析)
  • 二、激活函数的引入
    • [2.1 为什么需要激活函数?](#2.1 为什么需要激活函数?)
    • [2.2 在网络中引入激活函数](#2.2 在网络中引入激活函数)
      • [2.2.1 示例代码:为网络添加 ReLU 激活函数](#2.2.1 示例代码:为网络添加 ReLU 激活函数)
      • [2.2.2 输出结果](#2.2.2 输出结果)
      • [2.2.3 代码解析](#2.2.3 代码解析)
    • [2.3 不同激活函数的对比](#2.3 不同激活函数的对比)
    • [2.4 激活函数的注意事项](#2.4 激活函数的注意事项)
  • 三、多层感知机(MLP)的结构与实现
    • [3.1 什么是多层感知机?](#3.1 什么是多层感知机?)
      • [3.1.1 MLP 的基本特点](#3.1.1 MLP 的基本特点)
    • [3.2 使用 PyTorch 实现多层感知机](#3.2 使用 PyTorch 实现多层感知机)
      • [3.2.1 示例代码:构建多层感知机](#3.2.1 示例代码:构建多层感知机)
      • [3.2.2 输出结果](#3.2.2 输出结果)
      • [3.2.3 代码解析](#3.2.3 代码解析)
    • [3.3 数据输入形状](#3.3 数据输入形状)
    • [3.4 模型训练的必要组件](#3.4 模型训练的必要组件)
      • [3.4.1 示例代码:定义损失函数和优化器](#3.4.1 示例代码:定义损失函数和优化器)
    • [3.5 注意事项](#3.5 注意事项)
    • [3.6 多层感知机的优化方向](#3.6 多层感知机的优化方向)
  • 四、实际案例:手写数字分类
    • [4.1 数据加载与预处理](#4.1 数据加载与预处理)
      • [4.1.1 下载 MNIST 数据集](#4.1.1 下载 MNIST 数据集)
      • [4.1.2 数据处理说明](#4.1.2 数据处理说明)
    • [4.2 定义模型结构](#4.2 定义模型结构)
      • [4.2.1 模型代码](#4.2.1 模型代码)
      • [4.2.2 模型结构解释](#4.2.2 模型结构解释)
    • [4.3 定义训练过程](#4.3 定义训练过程)
      • [4.3.1 训练函数](#4.3.1 训练函数)
      • [4.3.2 代码说明](#4.3.2 代码说明)
    • [4.4 模型测试与评估](#4.4 模型测试与评估)
      • [4.4.1 测试函数](#4.4.1 测试函数)
      • [4.4.2 测试流程](#4.4.2 测试流程)
    • [4.5 完整运行流程](#4.5 完整运行流程)
    • [4.6 运行结果](#4.6 运行结果)
    • [4.7 进一步优化](#4.7 进一步优化)
  • 五、总结

前言

在人工智能和深度学习领域,PyTorch 以其灵活性和简洁性,迅速成为研究人员和开发者们的首选工具。然而,对于许多初学者而言,深度学习的入门看似门槛颇高:神经网络的结构、数学公式的理解、代码实现的细节......每一环都可能让人望而却步。

本文以经典的 MNIST 手写数字分类问题 为例,通过 从零开始的方式,带领你逐步实现一个多层感知机(MLP),从最基础的全连接网络开始,逐渐引入激活函数和多层结构,最终完成一个完整的训练与测试流程。本文不仅提供详细的代码示例,更注重背后的原理解析与实践指导,力求让你在最短的时间内掌握 PyTorch 的核心用法。

无论你是深度学习的初学者,还是希望深入了解 PyTorch 实战的开发者,这篇文章都将是你学习的绝佳起点。

一、简单全连接神经网络的搭建

1.1 什么是全连接神经网络?

全连接神经网络(Fully Connected Neural Network, FCNN)是深度学习中最基础的网络结构之一。它的特点是:网络中的每一层神经元与下一层的每个神经元都存在连接。全连接网络的核心是矩阵运算,可以表示为以下公式:

y = W x + b \ y = Wx + b y=Wx+b

其中:

  • ( W ) 是权重矩阵;
  • ( b ) 是偏置;
  • ( x ) 是输入;
  • ( y ) 是输出。

简单的全连接网络通常由输入层、一个或多个隐藏层和输出层组成,每一层通过线性变换对输入数据进行处理。以下是全连接网络的基本结构示意图:

plaintxt 复制代码
输入层 -> 隐藏层 -> 输出层

1.2 使用 PyTorch 搭建简单网络

在 PyTorch 中,神经网络的构建通常通过继承 torch.nn.Module 来完成。我们可以定义网络的结构并实现前向传播。

1.2.1 示例代码:构建两层全连接网络

以下是一个使用 PyTorch 构建两层全连接网络的简单示例:

python 复制代码
import torch
import torch.nn as nn

# 定义简单的全连接神经网络
class SimpleNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleNN, self).__init__()
        # 定义两层全连接层
        self.fc1 = nn.Linear(input_size, hidden_size)  # 第一层全连接
        self.fc2 = nn.Linear(hidden_size, output_size)  # 第二层全连接

    def forward(self, x):
        # 定义前向传播
        x = self.fc1(x)  # 输入通过第一层
        x = self.fc2(x)  # 输入通过第二层
        return x

# 定义模型参数
input_size = 10  # 输入特征数
hidden_size = 5  # 隐藏层神经元个数
output_size = 2  # 输出类别数

# 初始化模型
model = SimpleNN(input_size, hidden_size, output_size)

# 打印模型结构
print(model)

1.2.2 输出结果

运行以上代码后,你将看到模型的结构:

plaintxt 复制代码
SimpleNN(
  (fc1): Linear(in_features=10, out_features=5, bias=True)
  (fc2): Linear(in_features=5, out_features=2, bias=True)
)

1.2.3 代码解析

  1. nn.Linear:PyTorch 提供的全连接层类,用于实现输入到输出的线性变换。
  2. forward 方法:定义了数据的前向传播路径,规定输入数据如何流经网络层。

二、激活函数的引入

2.1 为什么需要激活函数?

全连接网络中的线性层只能实现输入和输出之间的线性变换。为了让网络具备非线性建模能力,我们需要引入激活函数。

激活函数的主要作用是:

  • 引入非线性,使网络能够学习复杂的模式;
  • 控制神经元的输出范围,避免梯度爆炸或梯度消失。

常见的激活函数包括:

  • ReLU (Rectified Linear Unit)
    • 定义: f ( x ) = max ⁡ ( 0 , x ) \ f(x) = \max(0, x) f(x)=max(0,x)
    • 特点:简单高效,对正值保持线性,对负值置零。
  • Sigmoid
    • 定义: f ( x ) = 1 1 + e − x \ f(x) = \frac{1}{1 + e^{-x}} f(x)=1+e−x1
    • 特点:输出范围为 (0, 1),常用于二分类任务。
  • Tanh (双曲正切函数)
    • 定义: f ( x ) = e x − e − x e x + e − x \ f(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} f(x)=ex+e−xex−e−x
    • 特点:输出范围为 (-1, 1),常用于归一化数据的建模。

2.2 在网络中引入激活函数

在 PyTorch 中,激活函数可以通过 torch.nn 模块中的函数类实现,也可以直接使用 torch 提供的操作符。

2.2.1 示例代码:为网络添加 ReLU 激活函数

以下是为之前的两层全连接网络添加 ReLU 激活函数的代码:

python 复制代码
class SimpleNNWithActivation(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleNNWithActivation, self).__init__()
        # 定义两层全连接层
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()  # 添加 ReLU 激活函数
        self.fc2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        x = self.fc1(x)  # 输入通过第一层
        x = self.relu(x)  # 应用 ReLU 激活函数
        x = self.fc2(x)  # 输入通过第二层
        return x

# 初始化网络
model_with_activation = SimpleNNWithActivation(input_size, hidden_size, output_size)

# 打印模型结构
print(model_with_activation)

2.2.2 输出结果

运行后打印的模型结构如下:

plaintxt 复制代码
SimpleNNWithActivation(
  (fc1): Linear(in_features=10, out_features=5, bias=True)
  (relu): ReLU()
  (fc2): Linear(in_features=5, out_features=2, bias=True)
)

2.2.3 代码解析

  1. __init__ 方法中,定义了 ReLU 激活函数对象(self.relu = nn.ReLU())。
  2. forward 方法中,激活函数被插入到第一层和第二层之间,用于对第一层的输出进行非线性变换。

2.3 不同激活函数的对比

以下是三种常见激活函数的对比表:

激活函数 数学公式 输出范围 优势 缺点
ReLU f ( x ) = max ⁡ ( 0 , x ) \ f(x) = \max(0, x) f(x)=max(0,x) [0, ∞) 计算简单,收敛速度快 对负值不敏感,可能导致神经元失活
Sigmoid f ( x ) = 1 1 + e − x \ f(x) = \frac{1}{1 + e^{-x}} f(x)=1+e−x1 (0, 1) 输出平滑,适合概率预测 梯度消失,计算开销较大
Tanh f ( x ) = e x − e − x e x + e − x \ f(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} f(x)=ex+e−xex−e−x (-1, 1) 输出对称,适合归一化数据 梯度消失,计算开销较大

通过这些对比,ReLU 是目前最常用的激活函数,尤其是在深层神经网络中。


2.4 激活函数的注意事项

  1. 避免梯度消失问题:在使用 Sigmoid 和 Tanh 时,当输入过大或过小时,梯度可能趋近于 0。
  2. ReLU 的"神经元失活"问题:如果输入总是负值,某些神经元可能永远无法被激活。
  3. 选择激活函数的依据
    • ReLU 常用于隐藏层;
    • Sigmoid 常用于输出层的二分类任务;
    • Tanh 在数据归一化的场景下表现更好。

三、多层感知机(MLP)的结构与实现

3.1 什么是多层感知机?

多层感知机(Multilayer Perceptron, MLP)是深度学习中一种重要的神经网络结构。它由多层全连接层组成,并通过激活函数引入非线性,能够学习并拟合复杂的非线性关系。

3.1.1 MLP 的基本特点

  1. 多层结构:包括输入层、一个或多个隐藏层和输出层。
  2. 激活函数:隐藏层通常使用非线性激活函数(如 ReLU)。
  3. 全连接层:每个神经元与下一层的所有神经元相连。
  4. 前向传播和反向传播:前向传播计算输出,反向传播通过梯度下降优化权重。

MLP 的基本结构如下:

plaintxt 复制代码
输入层 -> 隐藏层1 -> 激活函数 -> 隐藏层2 -> 激活函数 -> 输出层

相较于简单的单层全连接网络,MLP 通过多个隐藏层和非线性激活函数,能够表示更复杂的函数关系,是神经网络的基础模型。


3.2 使用 PyTorch 实现多层感知机

以下是实现一个具有两层隐藏层的 MLP 的代码示例。

3.2.1 示例代码:构建多层感知机

python 复制代码
import torch
import torch.nn as nn

# 定义多层感知机
class MLP(nn.Module):
    def __init__(self, input_size, hidden_sizes, output_size):
        super(MLP, self).__init__()
        # 定义第一层全连接层
        self.fc1 = nn.Linear(input_size, hidden_sizes[0])  
        # 定义第二层全连接层
        self.fc2 = nn.Linear(hidden_sizes[0], hidden_sizes[1])  
        # 定义输出层
        self.fc3 = nn.Linear(hidden_sizes[1], output_size)  
        # 定义 ReLU 激活函数
        self.relu = nn.ReLU()

    def forward(self, x):
        # 数据通过第一层
        x = self.fc1(x)
        x = self.relu(x)  # 应用 ReLU 激活
        # 数据通过第二层
        x = self.fc2(x)
        x = self.relu(x)  # 再次应用 ReLU 激活
        # 数据通过输出层
        x = self.fc3(x)
        return x

# 定义模型参数
input_size = 784  # 输入层节点数(如28x28图像展开为784维向量)
hidden_sizes = [128, 64]  # 两个隐藏层,节点数分别为128和64
output_size = 10  # 输出层节点数(如10个分类)

# 初始化模型
mlp_model = MLP(input_size, hidden_sizes, output_size)

# 打印模型结构
print(mlp_model)

3.2.2 输出结果

运行以上代码后,会打印出模型结构:

plaintxt 复制代码
MLP(
  (fc1): Linear(in_features=784, out_features=128, bias=True)
  (fc2): Linear(in_features=128, out_features=64, bias=True)
  (fc3): Linear(in_features=64, out_features=10, bias=True)
  (relu): ReLU()
)

3.2.3 代码解析

  1. 层的定义
    • 第一层全连接层:self.fc1,输入维度为 784,输出维度为 128;
    • 第二层全连接层:self.fc2,输入维度为 128,输出维度为 64;
    • 输出层:self.fc3,输入维度为 64,输出维度为 10。
  2. 激活函数
    • 在每一层全连接层后使用 ReLU 激活函数,增加非线性建模能力。
  3. 前向传播
    • forward 方法定义了输入数据流经网络的路径。

3.3 数据输入形状

多层感知机通常需要将输入数据展平为一维向量(即 flatten 操作),以符合全连接层的输入要求。例如,对于 MNIST 数据集,输入是 28x28 的灰度图像,需要将其展平成大小为 ( 28 \times 28 = 784 ) 的向量。

python 复制代码
# 示例:将 28x28 图像展平成一维向量
images = torch.randn(64, 1, 28, 28)  # 假设 64 个批量的 MNIST 数据
flattened_images = images.view(images.size(0), -1)  # 展平成 (64, 784)
print(flattened_images.shape)  # 输出形状:(64, 784)

3.4 模型训练的必要组件

为了训练多层感知机,需要以下组件:

  1. 损失函数:计算预测结果与真实值之间的误差。
  2. 优化器:调整模型参数以最小化损失函数。
  3. 数据加载器:批量加载数据,支持随机抽样和迭代。

3.4.1 示例代码:定义损失函数和优化器

python 复制代码
import torch.optim as optim

# 定义交叉熵损失函数(适合分类任务)
criterion = nn.CrossEntropyLoss()

# 定义随机梯度下降优化器
optimizer = optim.SGD(mlp_model.parameters(), lr=0.01)

print("Loss function and optimizer defined!")

3.5 注意事项

  1. 隐藏层的数量和节点数
    • 隐藏层越多,网络的表达能力越强,但计算复杂度也会增加;
    • 节点数的选择需要平衡模型性能和计算开销,可根据经验或通过交叉验证调整。
  2. 过拟合问题
    • 多层感知机可能容易过拟合,特别是在隐藏层过多或节点数过大时;
    • 可以引入正则化技术(如 Dropout)来缓解过拟合。
  3. 初始化权重
    • 默认的权重初始化方式通常表现良好,但在某些复杂任务中,可以考虑使用自定义初始化方法。

3.6 多层感知机的优化方向

为了进一步优化多层感知机的性能,可以尝试以下方法:

  1. 更复杂的激活函数
    • 除了 ReLU,还可以尝试 Leaky ReLU、ELU 或 GELU 等更高级的激活函数。
  2. 正则化技术
    • 添加 Dropout 层随机丢弃部分神经元,防止过拟合;
    • 在损失函数中加入 L2 正则化项(权重惩罚)。
  3. 使用 GPU
    • 通过将模型和数据加载到 GPU 上,显著加速训练过程:

      python 复制代码
      device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
      mlp_model.to(device)

四、实际案例:手写数字分类

在本节中,将结合经典的 MNIST 数据集,使用多层感知机(MLP)完成手写数字分类任务。MNIST 数据集包含 28x28 的灰度图像,共 10 个类别(数字 0 到 9)。


4.1 数据加载与预处理

4.1.1 下载 MNIST 数据集

使用 torchvision 提供的工具,可以轻松下载并加载 MNIST 数据集。

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

# 数据预处理
transform = transforms.Compose([
    transforms.ToTensor(),  # 转换为 Tensor
    transforms.Normalize((0.5,), (0.5,))  # 归一化到 [-1, 1]
])

# 加载 MNIST 数据集
train_dataset = datasets.MNIST(
    root='./data', train=True, transform=transform, download=True
)
test_dataset = datasets.MNIST(
    root='./data', train=False, transform=transform, download=True
)

# 定义数据加载器
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)

print("MNIST 数据集加载完成!")

4.1.2 数据处理说明

  1. ToTensor():将 PIL 图像转换为 PyTorch 张量,并将像素值从 [0, 255] 缩放到 [0, 1]。
  2. Normalize((0.5,), (0.5,)):将数据标准化到 [-1, 1] 区间,加速训练收敛。
  3. 数据加载器DataLoader 支持批量加载数据,并通过 shuffle 打乱训练集,增加模型的泛化能力。

4.2 定义模型结构

我们使用一个多层感知机模型,包含两层隐藏层和 ReLU 激活函数。每层的节点数根据 MNIST 数据特性选择。

4.2.1 模型代码

python 复制代码
import torch.nn as nn

class MLP(nn.Module):
    def __init__(self, input_size, hidden_sizes, output_size):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_sizes[0])  # 第一层全连接
        self.fc2 = nn.Linear(hidden_sizes[0], hidden_sizes[1])  # 第二层全连接
        self.fc3 = nn.Linear(hidden_sizes[1], output_size)  # 输出层
        self.relu = nn.ReLU()  # 激活函数

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.fc3(x)
        return x

# 定义模型参数
input_size = 28 * 28  # MNIST 图像展平成一维向量,28x28 = 784
hidden_sizes = [128, 64]  # 两个隐藏层,节点数分别为 128 和 64
output_size = 10  # 输出层(10 个分类)

# 初始化模型
model = MLP(input_size, hidden_sizes, output_size)

print(model)

4.2.2 模型结构解释

  • 输入层为 784(28x28 展开后),输出层为 10(对应 10 个数字类别)。
  • 两个隐藏层分别包含 128 和 64 个神经元,通过 ReLU 激活函数引入非线性。
  • 模型的参数(权重和偏置)会在训练中自动更新。

4.3 定义训练过程

模型训练包括前向传播、损失计算、反向传播和优化步骤。

4.3.1 训练函数

python 复制代码
import torch
import torch.optim as optim

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()  # 适合分类任务的交叉熵损失
optimizer = optim.SGD(model.parameters(), lr=0.01)  # 随机梯度下降优化器

# 训练函数
def train(model, train_loader, criterion, optimizer, epochs=5):
    for epoch in range(epochs):
        model.train()  # 切换到训练模式
        running_loss = 0.0

        for images, labels in train_loader:
            # 展平图像为向量
            images = images.view(images.size(0), -1)

            # 清零梯度
            optimizer.zero_grad()

            # 前向传播
            outputs = model(images)
            loss = criterion(outputs, labels)

            # 反向传播和优化
            loss.backward()
            optimizer.step()

            running_loss += loss.item()

        print(f"Epoch [{epoch+1}/{epochs}], Loss: {running_loss/len(train_loader):.4f}")

4.3.2 代码说明

  1. 损失函数CrossEntropyLoss 计算预测值与真实标签之间的误差。
  2. 优化器SGD(随机梯度下降)更新模型参数。
  3. 训练流程
    • 数据通过模型的前向传播计算输出;
    • 通过损失函数计算误差;
    • 反向传播计算梯度;
    • 使用优化器更新权重。

4.4 模型测试与评估

训练完成后,我们需要在测试集上评估模型的性能,计算分类准确率。

4.4.1 测试函数

python 复制代码
def test(model, test_loader):
    model.eval()  # 切换到评估模式
    correct = 0
    total = 0

    with torch.no_grad():  # 测试时不需要计算梯度
        for images, labels in test_loader:
            # 展平图像为向量
            images = images.view(images.size(0), -1)

            # 前向传播
            outputs = model(images)
            _, predicted = torch.max(outputs, 1)  # 获取最大值对应的类别

            total += labels.size(0)
            correct += (predicted == labels).sum().item()

    accuracy = 100 * correct / total
    print(f"Test Accuracy: {accuracy:.2f}%")

4.4.2 测试流程

  1. 模式切换model.eval() 将模型设置为评估模式,关闭 Dropout 和 BatchNorm 的动态行为。
  2. 无梯度计算 :通过 torch.no_grad() 节省内存和计算开销。
  3. 准确率计算:通过比较预测类别与真实标签,计算准确率。

4.5 完整运行流程

将训练和测试结合在一起,完成整个流程。

python 复制代码
# 训练模型
train(model, train_loader, criterion, optimizer, epochs=5)

# 测试模型
test(model, test_loader)

4.6 运行结果

经过 5 轮训练,模型在 MNIST 测试集上的分类准确率通常可以达到 90% 以上

plaintxt 复制代码
Epoch [1/5], Loss: 0.5204
Epoch [2/5], Loss: 0.3198
Epoch [3/5], Loss: 0.2712
Epoch [4/5], Loss: 0.2397
Epoch [5/5], Loss: 0.2163
Test Accuracy: 92.58%

4.7 进一步优化

如果想进一步提升模型性能,可以尝试以下方法:

  1. 增加隐藏层:引入更多隐藏层或增加隐藏层的节点数。
  2. 使用更复杂的优化器 :如 Adam 优化器 (optim.Adam)。
  3. 学习率调整:引入学习率调度器,动态调整学习率。
  4. 正则化:添加 Dropout 层,减少过拟合风险。
python 复制代码
# 替换优化器为 Adam
optimizer = optim.Adam(model.parameters(), lr=0.001)

五、总结

在本文中,我们从零开始实现了一个完整的多层感知机(MLP)模型,用于 MNIST 手写数字分类问题。通过这一过程,你应该已经掌握了以下关键知识点:

  1. 全连接神经网络的基本结构 :如何通过 nn.Linear 搭建最基础的神经网络;
  2. 激活函数的引入:如何通过非线性激活函数(如 ReLU)提升模型的学习能力;
  3. 多层感知机的实现:如何设计一个包含多层隐藏层的深度学习模型;
  4. 完整的训练与测试流程:从数据加载、前向传播、反向传播到模型性能的评估。

相关推荐
NAGNIP8 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab9 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab9 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP13 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年13 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼14 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS14 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
warm3snow14 小时前
Claude Code 黑客马拉松:5 个获奖项目,没有一个是"纯码农"做的
ai·大模型·llm·agent·skill·mcp
天翼云开发者社区15 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈15 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能