news 2026/9/7 11:36:16

张量是什么?机器学习中张量的核心概念与PyTorch实战详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
张量是什么?机器学习中张量的核心概念与PyTorch实战详解

很多刚接触机器学习的同学,在看教程或者读框架源码时,经常会遇到“张量”这个词,比如“把输入数据转换成张量”“模型的权重是一个四维张量”。刚开始听到张量,总觉得它是什么高深的数学概念,好像需要很强的线性代数功底才能理解。实际上,在学习机器学习的过程中,张量并没有想象中那么可怕,它本质上就是一种“装数据”的容器,只是比我们熟悉的数组、矩阵更通用、更灵活。

这篇文章会从最基础的数据形态讲起,逐步拆解张量的含义、形状、维度、运算规则,并且结合 NumPy 和 PyTorch 给出大量可运行的代码示例。无论你是刚入门机器学习的新手,还是想系统梳理张量概念的开发者,这篇文章都能帮你建立一套清晰的理解框架。学完之后,你至少能看懂 PyTorch 模型里的 shape 变化,能自己创建、变形、运算张量,也知道了常见的广播机制和形状报错该怎么排查。

1. 什么是张量:从数据形态说起

1.1 从标量、向量、矩阵到张量

在理解张量之前,我们先回顾一下数学里常见的数据组织形式。

  • 标量(Scalar):一个单独的数,比如 5、3.14。
  • 向量(Vector):一组有序排列的数,比如 [1, 2, 3],它是一维的。
  • 矩阵(Matrix):一个二维的数表,比如一个 2 行 3 列的二维数组。
  • 张量(Tensor):维度大于等于 0 的数组统称,也就是标量、向量、矩阵都是张量的特例。

从这个角度来看,张量是一个更大的概念。你可以把标量理解为“0 维张量”,向量是“1 维张量”,矩阵是“2 维张量”。当数据的维度超过 2 时,比如一个形状为 (2, 3, 4) 的数据,它就很难再被叫作矩阵了,这时候用“张量”来描述是最合适的。

换句话说,张量就是“广义化的数组”,它可以拥有任意多个维度,每一个维度都代表数据的一种排列方式。

1.2 张量的正式定义与记号

在数学中,张量可以理解为向量和矩阵向更高维度的推广。不过在机器学习的工程语境里,我们通常不讨论太多微分几何里的张量定义,而是把它当作“多维数组”来使用。

一个张量有几个关键属性:

  • 阶数(Rank):也叫维度数量。标量的阶数是 0,向量的阶数是 1,矩阵的阶数是 2。
  • 形状(Shape):每个维度的大小。比如形状为 (2, 3) 的张量,表示有 2 行 3 列。
  • 数据类型(Dtype):元素的数据类型,比如整数、浮点数、布尔值。

在 PyTorch 中,我们可以通过tensor.ndim查看张量的维度数量,通过tensor.shape查看形状。NumPy 中也类似,用array.ndimarray.shape

import numpy as np a = np.array([1, 2, 3]) print("维度数量:", a.ndim) print("形状:", a.shape) print("数据类型:", a.dtype)

输出:

维度数量: 1 形状: (3,) 数据类型: int64

可以看到,这个一维数组的维度数量是 1,形状是 (3,),表示有 3 个元素。

1.3 为什么机器学习离不开张量

机器学习模型的本质,就是“输入数据,经过一系列数学运算,输出预测结果”。而计算机处理数学运算时,最有效率的数据组织形式就是数组和矩阵。神经网络里大量的矩阵乘法、逐元素运算、梯度计算,都需要统一的数据结构来承载。

张量之所以成为机器学习的核心数据结构,原因可以概括为三点。

第一,统一性。图像、文本、表格、音频,最终都可以转换成张量。一张彩色图片可以表示成 (高度, 宽度, 通道数) 的三维张量,一段文本可以表示成 (句子长度, 词向量维度) 的二维张量。

第二,并行计算。GPU 擅长对大规模张量做并行运算,深度学习框架把计算组织成张量运算之后,可以高效利用 GPU 加速。

第三,自动求导。现代深度学习框架基于张量构建计算图,张量在参与运算时会记录操作历史,框架可以自动计算梯度,这是反向传播算法的基础。

因此,想学好机器学习,尤其是深度学习,理解张量是绕不开的一步。

2. 环境准备与工具选择

2.1 Python 环境

本文的示例代码主要使用 Python 和常见的科学计算库。建议使用 Python 3.8 或更高版本,具体版本可以根据你的项目需求调整。如果你还没有配置环境,推荐使用 Anaconda 或 Miniconda 创建独立的虚拟环境,避免不同项目之间依赖冲突。

conda create -n tensor-tutorial python=3.10 conda activate tensor-tutorial

2.2 NumPy 与 PyTorch 的作用

本文会用到两个库:

  • NumPy:Python 科学计算的基础库,提供了高性能的多维数组对象ndarray,也是很多数据分析、机器学习库的底层依赖。
  • PyTorch:主流的深度学习框架,其核心数据结构就是torch.Tensor,和 NumPy 的数组非常相似,但额外支持自动求导和设备迁移(CPU/GPU)。

安装命令如下:

pip install numpy pip install torch

如果你的电脑有 NVIDIA 显卡并安装了 CUDA,建议按照 PyTorch 官网的提示安装对应 CUDA 版本的 PyTorch;如果只是为了学习张量概念,CPU 版本的 PyTorch 完全够用。

2.3 示例项目结构

为了方便实验,建议新建一个目录,里面放一到两个 Python 脚本,或者直接用 Jupyter Notebook 逐段运行。

tensor-tutorial/ ├── tensor_basics.py └── tensor_operations.py

本文的代码如果标注了tensor_basics.py,就表示这部分代码可以集中放在该文件里运行。接下来的内容,我会先介绍张量的核心属性,再逐步展开创建、变形、运算和应用。

3. 张量的核心属性:形状、维度与轴

3.1 轴的编号规则

在张量中,“轴”(Axis)和“维度”(Dimension)经常混用,它们指的都是数据排列的“方向”。轴是从 0 开始编号的。

看一个简单的三维张量:

import numpy as np x = np.array([ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]) print(x.shape) # 输出 (2, 2, 2)

这个张量的形状是 (2, 2, 2),含义是:

  • 第 0 轴长度为 2,表示外层有 2 个“块”。
  • 第 1 轴长度为 2,表示每个块里有 2 行。
  • 第 2 轴长度为 2,表示每行有 2 个元素。

用坐标来理解:x[0, 1, 0]表示第 0 个块、第 1 行、第 0 列的元素,也就是数字 3。轴编号的顺序,决定了你在索引时怎么定位数据。

3.2 理解形状 shape

形状是张量最直观的描述,它用一个元组表示每个轴的长度。比如:

  • (3,)表示一维张量,共 3 个元素。
  • (2, 3)表示二维张量,2 行 3 列。
  • (4, 2, 3)表示三维张量,可以理解为 4 个 2 行 3 列的矩阵堆叠在一起。

在 PyTorch 中,形状同样非常重要。像nn.Linearnn.Conv2d这类网络层,输入输出形状必须严格对应,形状不匹配会直接报错。

3.3 张量的数据类型

张量里的元素有不同类型。常见的包括:

  • 整数型:int32int64
  • 浮点型:float32float64
  • 布尔型:bool

深度学习模型默认多使用float32,因为它在精度和计算速度之间取得了平衡。某些场景下,比如数据处理阶段用整数索引,模型计算阶段则转成浮点数。

import torch a = torch.tensor([1, 2, 3]) b = torch.tensor([1.0, 2.0, 3.0]) print(a.dtype) # torch.int64 print(b.dtype) # torch.float32

这里需要注意,PyTorch 创建整数列表后默认是int64,创建带小数的列表后默认是float32,这和 NumPy 的默认规则略有差异。

4. 张量的创建与基本操作

4.1 使用 NumPy 创建张量

NumPy 提供了非常丰富的数组创建函数。

import numpy as np # 从 Python 列表创建 a = np.array([[1, 2, 3], [4, 5, 6]]) # 全零数组 zeros = np.zeros((2, 3)) # 全一数组 ones = np.ones((2, 3)) # 指定数值填充 full = np.full((2, 3), 7) # 随机数组 random_arr = np.random.rand(2, 3) # 等差数列 arange_arr = np.arange(12).reshape(3, 4) print("a:", a.shape) print("zeros:", zeros.shape) print("full:\n", full)

这些函数在数据预处理中非常常用,比如初始化权重、创建掩码、生成测试数据等。

4.2 使用 PyTorch 创建张量

PyTorch 的创建方式和 NumPy 很像,常见的有:

import torch # 从列表创建 a = torch.tensor([[1, 2], [3, 4]]) # 全零 zeros = torch.zeros(2, 3) # 全一 ones = torch.ones(2, 3) # 随机均匀分布 rand = torch.rand(2, 3) # 随机正态分布 randn = torch.randn(2, 3) # 和 NumPy 互相转换 np_arr = a.numpy() back_to_torch = torch.from_numpy(np_arr) print("zeros:", zeros.shape) print("rand:", rand)

在 PyTorch 中,还有一个非常常用的函数torch.arange,它和 Python 的range类似,但返回的是张量。

x = torch.arange(24).reshape(2, 3, 4) print(x.shape) # torch.Size([2, 3, 4])

4.3 索引与切片

张量的索引和 Python 列表的切片语法非常相似,但因为轴变多了,需要理解每个位置对应哪个轴。

import numpy as np x = np.arange(12).reshape(3, 4) print(x) # 取第 1 行 print(x[1]) # 取第 1 行第 2 列 print(x[1, 2]) # 取所有行的第 2 列 print(x[:, 2]) # 取前 2 行的后 2 列 print(x[:2, 2:])

输出:

[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [ 4 5 6 7] 6 [ 2 6 10] [[2 3] [6 7]]

多维切片的关键就是记住:每一维都独立写一个切片范围,用逗号隔开。:表示这一维全部保留,:两边的数字表示起止位置,和 Python 列表规则一致。

5. 张量的变形与维度变换

5.1 reshape 与 view

reshape是改变张量形状最常用的方法,它把张量按某种顺序重新排列成新的形状,前提是元素总数必须一致。

import numpy as np import torch # NumPy x = np.arange(12) y = x.reshape(3, 4) print(y) # PyTorch xt = torch.arange(12) yt = xt.view(3, 4) print(yt)

PyTorch 中viewreshape都用于变形,但实现机制略有不同。view要求原张量在内存中是连续的,而reshape在必要时会自动复制数据。如果你不确定,优先使用reshape更稳妥。

还有一种常见情况是通过-1让框架自动推断某一维的大小。

x = np.arange(12) y = x.reshape(-1, 4) # 自动算出行数是 3 print(y.shape) # (3, 4)

这种方式在写数据加载、批处理时非常实用,不需要手动计算形状。

5.2 增删维度:squeeze 与 unsqueeze

squeeze用于删除长度为 1 的维度,unsqueeze用于在指定位置增加一个长度为 1 的维度。

import torch x = torch.randn(1, 3, 1, 4) # 删除所有长度为 1 的维度 y = x.squeeze() print(y.shape) # torch.Size([3, 4]) # 在指定位置加维度 z = x.unsqueeze(0) print(z.shape) # torch.Size([1, 1, 3, 1, 4])

为什么需要增加长度为 1 的维度?因为某些模型层要求输入是四维张量,比如卷积层期望形状为 (批次大小, 通道数, 高度, 宽度)。当你只有一张灰度图时,数据形状可能是 (高度, 宽度),就需要先unsqueeze(0)增加通道维度,再unsqueeze(0)增加批次维度,才能送入模型。

5.3 转置 transpose 与 permute

transpose交换两个指定的维度,permute可以按照任意顺序重排所有维度。

import torch x = torch.randn(2, 3, 4) # 交换第 0 和第 2 维 y = x.transpose(0, 2) print(y.shape) # torch.Size([4, 3, 2]) # 重排所有维度 z = x.permute(2, 0, 1) print(z.shape) # torch.Size([4, 2, 3])

这在实际项目中很常见。比如一张图片在读取时形状可能是 (高度, 宽度, 通道数),而 PyTorch 的卷积层期望的是 (通道数, 高度, 宽度),这时候就需要用transposepermute调整维度顺序。

# 假设读入的图片张量形状为 (H, W, C) image = torch.randn(224, 224, 3) # 转换为 (C, H, W) image_t = image.permute(2, 0, 1) print(image_t.shape) # torch.Size([3, 224, 224])

5.4 拼接与分割

拼接可以用torch.cat在某个轴上把多个张量连接起来,也可以用torch.stack增加一个新维度后堆叠。

import torch a = torch.randn(2, 3) b = torch.randn(2, 3) # 沿第 0 轴拼接 cat0 = torch.cat([a, b], dim=0) print(cat0.shape) # torch.Size([4, 3]) # 沿第 1 轴拼接 cat1 = torch.cat([a, b], dim=1) print(cat1.shape) # torch.Size([2, 6]) # stack 会增加一个新维度 stacked = torch.stack([a, b], dim=0) print(stacked.shape) # torch.Size([2, 2, 3])

这两个操作在构建批数据、合并特征时经常出现。需要强调的是,cat要求除拼接轴外其他维度完全一致,否则会报错。

6. 张量运算与广播机制

6.1 逐元素运算

张量可以直接参与加减乘除,运算符会对每个位置的元素独立计算。

import torch a = torch.tensor([1, 2, 3]) b = torch.tensor([4, 5, 6]) print(a + b) # tensor([5, 7, 9]) print(a * b) # tensor([4, 10, 18]) print(a ** 2) # tensor([1, 4, 9]) print(torch.exp(a)) # 指数运算

这里要注意,*是逐元素相乘,不是矩阵乘法。矩阵乘法用@或者torch.matmul

6.2 矩阵乘法

矩阵乘法要求第一个矩阵的列数等于第二个矩阵的行数。

import torch A = torch.randn(2, 3) B = torch.randn(3, 4) C = A @ B # 等价于 torch.matmul(A, B) print(C.shape) # torch.Size([2, 4])

神经网络中的全连接层,本质上就是输入张量和权重矩阵做矩阵乘法,再加上偏置。理解矩阵乘法的维度变化,是看懂模型结构的基础。

6.3 广播机制详解

广播(Broadcasting)是 NumPy 和 PyTorch 中非常重要且容易困惑的机制。简单来说,当两个张量形状不完全一致时,框架会尝试自动扩张较小的张量,使它们能够进行运算。

import torch a = torch.tensor([1, 2, 3]) b = torch.tensor(10) print(a + b) # tensor([11, 12, 13]),10 被广播到每个元素

再看一个二维的例子:

m = torch.arange(6).reshape(2, 3) row = torch.tensor([10, 20, 30]) print(m + row)

输出:

tensor([[10, 21, 32], [13, 24, 35]])

这里row形状是 (3,),m形状是 (2, 3),框架把row沿第 0 轴广播,相当于复制了一份,和每一行相加。

广播规则可以概括为:从最后一个维度开始比较,如果两个维度相等,或者其中一个是 1,就可以继续匹配;如果既不等长,也不是 1,就无法广播,会报错。

# 例子:形状 (3, 1) 与 (1, 4) 可以广播成 (3, 4) x = torch.randn(3, 1) y = torch.randn(1, 4) z = x + y print(z.shape) # torch.Size([3, 4])

广播机制能减少很多显式的复制操作,让代码更简洁、内存占用更低,但如果不理解它,很容易写出形状不匹配的代码,或者得到意想不到的结果。

7. 机器学习中的张量实战场景

7.1 批处理数据:一次喂入多个样本

在训练模型时,我们通常不会一次只输入一个样本,而是把一个批次(Batch)的样本同时送入模型。假设每个样本是一个 64 维的特征向量,批次大小为 32,那么输入张量的形状就是 (32, 64)。

import torch batch_size = 32 feature_dim = 64 inputs = torch.randn(batch_size, feature_dim) print(inputs.shape) # torch.Size([32, 64])

模型权重通常也是一个矩阵,形状为 (输出特征数, 输入特征数)。矩阵乘法得到的结果形状为 (32, 输出特征数),每一个样本对应一行输出。

output_dim = 10 weight = torch.randn(output_dim, feature_dim) outputs = inputs @ weight.T print(outputs.shape) # torch.Size([32, 10])

这里的weight.T是权重矩阵的转置,这样矩阵乘法才能正确匹配维度。

7.2 图像数据:通道、高度、宽度

图像数据是理解高维张量最经典的例子。一张 RGB 彩色图片,如果高度为 224、宽度为 224,它有 3 个颜色通道,那么单个图片可以表示为形状 (3, 224, 224) 的张量。一个批次 16 张图片,形状就是 (16, 3, 224, 224)。

import torch batch_size = 16 channels = 3 height = 224 width = 224 images = torch.randn(batch_size, channels, height, width) print(images.shape) # torch.Size([16, 3, 224, 224])

卷积神经网络处理的就是这种四维张量。卷积核在高度和宽度方向上滑动,同时跨通道聚合信息,最终输出的特征图仍然是张量。

7.3 序列文本:批次、步长、特征

自然语言处理中,一段文本经过分词和词向量映射后,会转换成一个形状为 (序列长度, 词向量维度) 的二维张量。一个批次的多条文本,形状就是 (批次大小, 序列长度, 词向量维度)。

batch_size = 8 seq_len = 50 embed_dim = 128 texts = torch.randn(batch_size, seq_len, embed_dim) print(texts.shape) # torch.Size([8, 50, 128])

这里的第 0 轴是批次方向,第 1 轴是序列的时间步方向,第 2 轴是每个词的特征方向。RNN、LSTM、Transformer 等模型都会操作这种三维张量。

7.4 神经网络参数:权重与偏置张量

神经网络的每一层参数同样以张量形式存储。比如二维卷积层的卷积核,形状通常为 (输出通道数, 输入通道数, 卷积核高, 卷积核宽);全连接层的权重是二维矩阵,偏置是一维向量。

import torch.nn as nn linear = nn.Linear(in_features=64, out_features=10) print(linear.weight.shape) # torch.Size([10, 64]) print(linear.bias.shape) # torch.Size([10])

训练过程中,PyTorch 会为这些参数张量自动计算梯度,并更新它们的值。可以说,模型训练本质上就是不断调整这些张量参数的过程。

8. 常见问题与排查思路

在实际操作张量时,会遇到各种各样的报错。为了帮你快速定位问题,这里整理了一张排查表。

问题现象常见原因解决思路
shape mismatch报错两个张量在某个维度上大小不一致,无法直接运算或拼接打印两个张量的shape,确认需要对齐的维度,必要时使用reshapetransposeunsqueeze调整
广播时意外变成大矩阵不理解广播规则,维度被自动扩展,结果与预期不符打印中间结果的形状,逐步确认每一步的形状变化
view报错is not contiguous张量在transposepermute后内存不连续,无法直接view改用reshape,或先调用contiguous()view
张量在 GPU 上,运算时报设备不一致部分张量在 CPU,部分在 GPU,无法直接混合运算.to(device)统一设备,确保参与运算的张量在同一个设备上
NumPy 张量和 PyTorch 张量混用报错两个库的数据结构不能直接做运算torch.from_numpy()转成 PyTorch 张量,或用.numpy()转回 NumPy 数组
矩阵乘法维度不对左侧张量的最后一维不等于右侧张量的倒数第二维检查矩阵乘法的维度匹配条件,必要时对权重做转置或重排
索引结果维度减少用单个整数索引某一维时,该维度会被去除如果需要保留维度,使用切片写法,比如x[0:1]代替x[0]

排查形状类问题时,最有效的办法就是在报错位置前后打印print(x.shape)。把每个关键步骤的形状都看清楚,问题往往很快就能定位。

9. 最佳实践与工程建议

9.1 养成注释形状的习惯

在写模型或数据处理代码时,建议在关键张量操作附近用注释标明形状变化。这样做不仅能帮助自己理清逻辑,也能让团队其他人快速理解代码。

# 输入: (batch_size, 3, 224, 224) x = x.permute(0, 2, 3, 1) # -> (batch_size, 224, 224, 3) x = x.reshape(batch_size, -1) # -> (batch_size, 3*224*224)

这种方式在排错时能节省大量时间。

9.2 注意数据类型一致性

模型输入通常要求float32,而标签可能是整数类型。送入损失函数前,要确认数据类型的匹配。用到 NumPy 和 PyTorch 混编时,要显式转换,避免运行时才暴露问题。

9.3 内存与性能优化

处理大张量时,需要注意内存占用。批量创建的中间变量会占用大量显存,因此:

  • 不需要的中间结果要及时释放,或者用del删除后调用torch.cuda.empty_cache()
  • 能用inplace操作时谨慎使用,因为它虽然省内存,但会影响自动求导。
  • 尽量使用批量运算而不是循环,循环处理张量在 Python 中性能很低。

9.4 使用断言约束形状

在数据加载或模型前向传播中,可以用assert主动检查形状,提前暴露错误,而不是等到运算失败才排查。

def preprocess_batch(images): assert images.ndim == 4, f"期望 4 维张量,实际是 {images.ndim} 维" assert images.shape[1] == 3, "通道数必须为 3" return images.float()

9.5 安全操作与生产环境注意事项

在真实项目中,涉及数据变换时,尽量在测试环境验证形状变化是否符合预期,尤其是使用reshape时,它不保证保持语义顺序。需要保持语义的业务数据,建议优先使用transposepermute等明确的维度变换操作。对大文件或大数据集做预处理时,先在小规模数据上验证流程,再扩展到全量数据,避免算力浪费。

9.6 善用官方文档与调试工具

NumPy 和 PyTorch 的官方文档都非常完善。遇到不熟悉的函数,可以先查看函数签名和参数说明。调试时,可以用printipdb或者 PyTorch 的torch.set_printoptions控制输出格式,让大张量更容易阅读。

10. 总结与下一步学习建议

本文从标量、向量、矩阵开始,逐步引出了张量的定义,讲解了形状、维度、轴、数据类型等核心属性,并通过大量代码示例演示了张量的创建、索引切片、变形、维度重排、拼接、矩阵乘法和广播机制。最后结合图像、文本、批处理、网络参数等真实场景,说明了张量在机器学习中的应用方式,也整理了一份常见报错排查表。

如果你能独立完成文中大部分示例,并且能说出(32, 3, 224, 224)每个数字代表什么含义,说明你已经掌握了张量的基本使用方法。

下一步可以继续学习:

  • PyTorch 的autograd机制,理解张量如何实现自动求导。
  • DatasetDataLoader的使用,掌握真实数据如何转换成批张量。
  • 卷积层、循环神经网络等常见网络结构中的张量维度变化。
  • 使用 TensorBoard 或张量可视化工具观察模型中间层的输出。

张量是机器学习中绕不开的基础概念,也是连接数据与模型之间的桥梁。建议不要只看不练,打开 Python 环境,把文中的代码逐段运行一遍,多打印几次shape,很快就能建立起对张量的直觉。如果本文对你有帮助,可以收藏备用,也欢迎分享给正在学习机器学习的朋友。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 11:36:08

Linux驱动多设备支持:of_device_id匹配与实例私有数据管理

1. 瑞芯微平台上最常见的多设备驱动翻车现场 如果你在瑞芯微平台上写过Linux驱动,大概率碰到过这种场景:板子上接了不止一个同型号设备,两个触摸屏、四颗温湿度传感器或者两块同规格Codec,驱动加载之后只有最后注册的那个能工作&a…

作者头像 李华
网站建设 2026/9/7 11:30:30

OpenHarmony硬件调试三板斧:日志、量测与系统排查实战

1. 从一次调不通的板子说起做OpenHarmony(开源鸿蒙)开发,最难熬的不是写代码,而是代码写完了板子不干活。你反复编译、烧录、重启,外设就是没反应,串口里静悄悄,屏幕上一片黑,那种滋…

作者头像 李华
网站建设 2026/9/7 11:26:38

音视频同步与制作实战:从音乐表演录制到发布的完整技术指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 11:26:30

AI自动化监控大佬持仓:从数据采集到定时提醒的完整方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 11:25:41

端侧AI算力选型实战:从TOPS到真实性能,车载机载场景避坑指南

1. 项目概述:为什么端侧算力选型如此棘手 1.1 核心需求解析 接触过具身智能项目的人都有一个体会:模型跑通了是一回事,真正把它塞进一台机器人、一辆车、或者一架无人机里,是另一回事。云端用A100跑得飞快,到了端侧面…

作者头像 李华
网站建设 2026/9/7 11:25:31

Eclipse导入调试仿滴滴Android老源码:从环境配置到真机运行指南

简介:面向安卓开发学习者的仿滴滴出行项目源码,可用于理解移动出行类App从界面搭建到后台通信的整体实现。资源共289个文件,压缩包5.04MB,以Java源码、class编译文件、XML布局与配置、PNG界面切图为主,同时附带可安装的…

作者头像 李华