当前位置: 首页 > news >正文

【动手学深度学习】2.1. 数据操作


目录

  • 2. 预备知识
    • 2.1. 数据操作
      • 1) 入门
      • 2)运算符
      • 3)广播机制(broadcasting mechanism)
      • 4)索引和切片
      • 5)节省内存
      • 6)转换为其他Python对象
      • 7)小结


2. 预备知识

学习深度学习需掌握以下基础:

  • 数据处理:涵盖存储、操作与预处理,核心技能为高效管理表格数据(样本为行,属性为列)。

  • 线性代数:矩阵运算是处理多维数据的基础,重点理解基本原理与实现,如矩阵乘法与操作。

  • 优化与微积分:通过调整模型参数优化性能,微积分指导参数更新方向,实用工具(如autograd)可自动求导简化计算。

  • 概率论:用于不确定场景下的推断与预测,提供量化不确定性的数学框架。

  • 官方文档利用:熟练查阅框架文档以扩展知识,解决实际问题。

.

2.1. 数据操作

为了能够完成各种数据操作,我们需要某种方法来存储和操作数据。 通常,我们需要做两件重要的事:

  • (1)获取数据;

  • (2)将数据读入计算机后对其进行处理。

首先,我们介绍维数组,也称为张量(tensor)。张量类(在MXNet中为ndarray, 在PyTorch和TensorFlow中为Tensor)都与Numpy的ndarray类似。 但深度学习框架又比Numpy的ndarray多一些重要功能: 首先,GPU很好地支持加速计算,而NumPy仅支持CPU计算; 其次,张量类支持自动微分。

.

1) 入门

核心概念

  • 张量维度:1轴为向量,2轴为矩阵,更高维度无特定数学名称。

  • 形状变换时元素总数不变,-1可自动推导维度。

  • 初始化方法(全0/1、随机)常用于模型参数初始化。

基础操作

  • 导入库:import torch(注意包名为torch,非pytorch)。

  • 创建张量:

x = torch.arange(12)  # 创建整数行向量 [0, 1, ..., 11]
x = torch.arange(12, dtype=torch.float32)  # 指定浮点类型
  • 形状与元素数:
x.shape   # 形状 → torch.Size([12])
x.numel() # 元素总数 → 12
  • 重塑形状:reshape不改变元素值与总数,支持自动维度计算(-1):
X = x.reshape(3, 4)       # 显式指定形状 → 3行4列矩阵
X = x.reshape(-1, 4)      # 自动计算行数 → 同(3,4)
  • 全0/全1张量:
torch.zeros((2, 3, 4))    # 形状(2,3,4)的全0张量
torch.ones((2, 3, 4))     # 形状(2,3,4)的全1张量
  • 随机初始化(标准正态分布):
torch.randn(3, 4)         # 形状(3,4),元素服从N(0,1)
  • 直接转换嵌套列表:外层列表对应轴0,内层对应轴1:
torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])# 输出:
tensor([[2, 1, 4, 3],[1, 2, 3, 4],[4, 3, 2, 1]])

.

2)运算符

核心概念

  • 按元素运算:要求输入张量形状相同,支持 +, -, *, /, ** 及标量函数(如 exp)。

  • 张量连结torch.cat 按指定轴拼接,dim=0 扩展行,dim=1 扩展列。

  • 逻辑运算:生成布尔张量,用于条件筛选或掩码操作。

  • 聚合操作:如 sum() 对张量所有元素求和,常用于数值计算与损失函数。

(1)按元素运算

  • 算术运算符(相同形状张量):
x = torch.tensor([1.0, 2, 4, 8])  
y = torch.tensor([2.0, 2, 2, 2])  
x + y, x - y, x * y, x / y, x ** y  # **运算符是求幂运算# 输出
(tensor([ 3.,  4.,  6., 10.]),  tensor([-1.,  0.,  2.,  6.]),  tensor([ 2.,  4.,  8., 16.]),  tensor([0.5000, 1.0000, 2.0000, 4.0000]),  tensor([ 1.,  4., 16., 64.]))  
  • 一元运算符(如指数运算):
torch.exp(x)  # 计算 e^x  # 输出:
tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])  

(2)张量连结

  • 沿指定轴拼接(dim=0 按行,dim=1 按列):
X = torch.arange(12, dtype=torch.float32).reshape(3, 4)  
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])  
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)  
  • 输出:
# dim=0 结果(6行4列)  
tensor([[ 0.,  1.,  2.,  3.],  [ 4.,  5.,  6.,  7.],  [ 8.,  9., 10., 11.],  [ 2.,  1.,  4.,  3.],  [ 1.,  2.,  3.,  4.],  [ 4.,  3.,  2.,  1.]])  # dim=1 结果(3行8列)  
tensor([[ 0.,  1.,  2.,  3.,  2.,  1.,  4.,  3.],  [ 4.,  5.,  6.,  7.,  1.,  2.,  3.,  4.],  [ 8.,  9., 10., 11.,  4.,  3.,  2.,  1.]])  

3)逻辑运算

  • 按元素比较(生成布尔张量):
# 以X == Y为例: 对于每个位置,如果X和Y在该位置相等,则新张量中相应项的值为1。 这意味着逻辑语句X == Y在该位置处为真,否则该位置为0。X == Y  # 输出
tensor([[False,  True, False,  True],  [False, False, False, False],  [False, False, False, False]])  

(4)求和操作

  • 张量元素总和(返回单元素张量):
X.sum()  # 输出:
tensor(66.)  

.

3)广播机制(broadcasting mechanism)

原理: 允许不同形状的张量进行按元素运算,自动扩展至相同形状。

  • 通过复制元素扩展张量,使其形状一致;

  • 扩展通常沿长度为1的轴进行(如标量与张量运算);

示例

a = torch.arange(3).reshape((3, 1))  # 形状 (3,1)  
b = torch.arange(2).reshape((1, 2))  # 形状 (1,2) 
# 即:
a → tensor([[0], [1], [2]])
b → tensor([[0, 1]])  # 广播过程:
# a 沿列(轴1)复制两次 → 形状变为 (3,2)。
# b 沿行(轴0)复制三次 → 形状变为 (3,2)。# 按元素相加结果:
a + b  
# 输出:
tensor([[0, 1],  [1, 2],  [2, 3]])  

.

4)索引和切片

  • 元素访问:张量元素通过索引访问,第一个元素索引0,最后一个元素索引-1。

  • 切片操作:使用范围索引访问多个元素,如X[-1]获取最后一个元素,X[1:3]获取第2到第3个元素。

  • 修改元素:直接通过索引赋值修改张量元素,如X[1, 2] = 9

  • 批量修改:通过索引组合批量修改元素,如X[0:2, :] = 12修改前两行所有列的值。

示例代码:

X = torch.tensor([[0., 1., 2., 3.],  [4., 5., 6., 7.],  [8., 9., 10., 11.]])  # 访问最后一个元素  
X[-1] → tensor([ 8.,  9., 10., 11.])  # 访问第2、3行  
X[1:3] → tensor([[ 4.,  5.,  6.,  7.],  [ 8.,  9., 10., 11.]])  # 修改单个元素  
X[1, 2] = 9  
# 结果:  
tensor([[ 0.,  1.,  2.,  3.],  [ 4.,  5.,  9.,  7.],  [ 8.,  9., 10., 11.]])  # 批量修改前两行所有元素  
X[0:2, :] = 12  
# 结果:  
tensor([[12., 12., 12., 12.],  [12., 12., 12., 12.],  [ 8.,  9., 10., 11.]])  

.

5)节省内存

运行一些操作可能会导致为新结果分配内存。 例如,如果我们用Y = X + Y,我们将取消引用Y指向的张量,而是指向新分配的内存处的张量。下面介绍一些节省内存的操作:

  • 避免不必要内存分配:使用原地操作减少内存分配,如Y[:] = X + Y

  • 原地更新操作:使用X += YX[:] = X + Y进行原地更新,减少内存开销。

  • 内存地址验证:通过id()函数验证内存地址是否改变,如检查id(Y) == before

示例代码:

# 方法1:通过切片赋值  
Z = torch.zeros_like(Y)  
Z[:] = X + Y  # 不改变Z的内存地址  # 方法2:运算符简写  
X += Y        # 直接原地更新X,内存地址不变  # 验证内存地址:
before = id(X)  
X += Y  
id(X) == before → True  # 内存地址未变  

.

6)转换为其他Python对象

将深度学习框架定义的张量转换为NumPy张量(ndarray)很容易,反之也同样容易。 torch张量和numpy数组将共享它们的底层内存,就地操作更改一个张量也会同时更改另一个张量。

A = X.numpy()
B = torch.tensor(A)type(A), type(B)
# 输出:
(numpy.ndarray, torch.Tensor)

要将大小为1的张量转换为Python标量,我们可以调用item函数或Python的内置函数。

a = torch.tensor([3.5])a, a.item(), float(a), int(a)
# 输出:
(tensor([3.5000]), 3.5, 3.5, 3)

.

7)小结

深度学习存储和操作数据的主要接口是张量(维数组)。它提供了各种功能,包括基本数学运算、广播、索引、切片、内存节省和转换其他Python对象。

.


声明:资源可能存在第三方来源,若有侵权请联系删除!

相关文章:

  • 技术篇-2.4.Python应用场景及开发工具安装
  • 如果验证集缺失或测试集缺失应该怎么办?
  • Cursor远程连接+工具使用
  • redis-7.4.2 通过 systemd管理,rpmbuild spec文件参考
  • 关于初学者对大模型的一些概念的理解
  • 纳斯达克与标普500的技术博弈:解析美股交易系统的低延迟与高安全解决方案
  • java后端-海外登录(谷歌/FaceBook/苹果)
  • 高等数学-空间中的曲线与曲面
  • React 第四十六节 Router中useInRouterContext的使用详细介绍及注意事项
  • 价格行为(PriceAction)复盘 - Google - 250521
  • 嵌入式自学第二十六天(5.22)
  • C#中WSDL文件引用问题
  • 爱博精电正式入驻京东平台,为客户提供更高效、便捷的采购体验
  • RocketMQ 中的 ConsumeQueue:消息消费的关键索引
  • Java单例模式终极指南:从原理到防御性编程
  • Python描述统计分析
  • PTA刷题笔记
  • 变上限积分是被积函数的一个原函数
  • 多用户批发商城系统哪个好?商淘云S2B2b多供应商批发源码评测
  • redis数据持久化和配置-15(备份和还原 Redis 数据)
  • 淘客网站怎么做百度/seo系统优化
  • 国内网站建设公司排名/搜索引擎营销特点
  • 分析网站建设前期的seo准备工作/企业高管培训课程有哪些
  • 网站搭建系统/可以引流推广的app
  • 手机兼职在哪个网站做/深圳市seo网络推广哪家好
  • 杭州网站建设哪家权威/如何建立免费公司网站