『TensorFlow』张量拼接_调整维度_切片

本文详细介绍了TensorFlow中常用操作tf.concat、tf.stack、tf.squeeze、tf.split及张量切片等功能,通过实例展示如何使用这些函数进行张量处理。

1、tf.concat

tf.concat的作用主要是将向量按指定维连起来,其余维度不变;而1.0版本以后,函数的用法变成:

t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
#按照第0维连接
tf.concat( [t1, t2],0) ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
#按照第1维连接
tf.concat([t1, t2],1) ==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]

作为参考合成神经网络输出的时候在深度方向(inception_v3)是数字3,[batch,heigh,width,depth]。

2、tf.stack

用法:stack(values, axis=0, name=”stack”):
“”“Stacks a list of rank-R tensors into one rank-(R+1) tensor.

x = tf.constant([1, 4])
y = tf.constant([2, 5])
z = tf.constant([3, 6])
tf.stack([x,y,z]) ==> [[1,4],[2,5],[3,6]]
tf.stack([x,y,z],axis=0) ==> [[1,4],[2,5],[3,6]]
tf.stack([x,y,z],axis=1) ==> [[1, 2, 3], [4, 5, 6]]

tf.stack将一组R维张量变为R+1维张量。注意:tf.pack已经变成了tf.stack\3、tf.squeeze

数据降维,只裁剪等于1的维度

不指定维度则裁剪所有长度为1的维度

import tensorflow as tf 
arr = tf.Variable(tf.truncated_normal([3,4,1,6,1], stddev=0.1)) 
sess = tf.Session() 
sess.run(tf.global_variables_initializer()) 
sess.run(arr).shape 
# Out[12]: # (3, 4, 1, 6, 1) 
sess.run(tf.squeeze(arr,[2,])).shape 
# Out[17]: # (3, 4, 6, 1) 
sess.run(tf.squeeze(arr,[2,4])).shape 
# Out[16]: # (3, 4, 6) 
sess.run(tf.squeeze(arr)).shape
 # Out[19]: # (3, 4, 6)

 

3、tf.split

依照输入参数二的标量/向量有不同的行为:参数二为标量时,意为沿着axis等分为scalar份;向量时意为安装元素作为边界索引切分多份

def split(value, num_or_size_splits, axis=0, num=None, name="split"):
"""Splits a tensor into sub tensors.

If `num_or_size_splits` is an integer type, `num_split`, then splits `value`
along dimension `axis` into `num_split` smaller tensors.
Requires that `num_split` evenly divides `value.shape[axis]`.

If `num_or_size_splits` is not an integer type, it is presumed to be a Tensor
`size_splits`, then splits `value` into `len(size_splits)` pieces. The shape
of the `i`-th piece has the same size as the `value` except along dimension
`axis` where the size is `size_splits[i]`.

For example:

```python
# 'value' is a tensor with shape [5, 30]
# Split 'value' into 3 tensors with sizes [4, 15, 11] along dimension 1
split0, split1, split2 = tf.split(value, [4, 15, 11], 1)
tf.shape(split0) # [5, 4]
tf.shape(split1) # [5, 15]
tf.shape(split2) # [5, 11]
# Split 'value' into 3 tensors along dimension 1
split0, split1, split2 = tf.split(value, num_or_size_splits=3, axis=1)
tf.shape(split0) # [5, 10]
```

4、张量切片

tf.slice

解析:slice(input_, begin, size, name=None):Extracts a slice from a tensor.

假设input为[[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]],如下所示:

(1)tf.slice(input, [1, 0, 0], [1, 1, 3]) ==> [[[3, 3, 3]]]

(2)tf.slice(input, [1, 0, 0], [1, 2, 3]) ==> [[[3, 3, 3], [4, 4, 4]]]

(3)tf.slice(input, [1, 0, 0], [2, 1, 3]) ==> [[[3, 3, 3]], [[5, 5, 5]]]

 

tf.strided_slice(record_bytes, [0], [label_bytes]), tf.int32)

在看cifar10的例子的时候,必然会看到一个函数,官方给的文档注释长而晦涩,基本等于0.网上也有这个函数,但解释差劲或者基本没有解释,函数的原型是酱紫的.

def strided_slice(input_,
                  begin,
                  end,
                  strides=None,
                  begin_mask=0,
                  end_mask=0,
                  ellipsis_mask=0,
                  new_axis_mask=0,
                  shrink_axis_mask=0,
                  var=None,
                  name=None):
  """Extracts a strided slice from a tensor.
'input'= [[[1, 1, 1], [2, 2, 2]],
             [[3, 3, 3], [4, 4, 4]],
             [[5, 5, 5], [6, 6, 6]]]

来把输入变个型,可以看成3维的tensor,从外向为1,2,3维

[[[1, 1, 1], [2, 2, 2]],
 [[3, 3, 3], [4, 4, 4]],
 [[5, 5, 5], [6, 6, 6]]]

以tf.strided_slice(input, [0,0,0], [2,2,2], [1,2,1])调用为例,start = [0,0,0] , end = [2,2,2], stride = [1,2,1],求一个[start, end)的一个片段,注意end为开区间

第1维 start = 0 , end = 2, stride = 1, 所以取 0 , 1行,此时的输出

[[[1, 1, 1], [2, 2, 2]],
 [[3, 3, 3], [4, 4, 4]]]

第2维时, start = 0 , end = 2 , stride = 2, 所以只能取0行,此时的输出

[[[1, 1, 1]],
 [[3, 3, 3]]]

第3维的时候,start = 0, end = 2, stride = 1, 可以取0,1行,此时得到的就是最后的输出

[[[1, 1]],
 [[3, 3]]]

整理之后最终的输出为:

[[[1,1],[3,3]]]

类似代码如下:

import tensorflow as tf   
data = [[[1, 1, 1], [2, 2, 2]],   
     [[3, 3, 3], [4, 4, 4]],   
     [[5, 5, 5], [6, 6, 6]]]   
x = tf.strided_slice(data,[0,0,0],[1,1,1])   
with tf.Session() as sess:   
print(sess.run(x))  

 

转载于:https://www.cnblogs.com/hellcat/p/8581804.html

### 张量的基本概念 张量是一种多维数组,在机器学习框架如 PyTorch 和 TensorFlow 中广泛使用。它可以看作是一个广义上的矩阵,支持任意维度的数据结构表示。例如,零阶张量是标量,一阶张量一维数组(向量),二阶张量是二维数组(矩阵)。更高阶的张量可以用来表示更复杂的数据结构。 在 PyTorch 中,可以通过 `torch.tensor()` 创建张量[^2]。张量不仅继承了 NumPy 的灵活性,还提供了 GPU 加速的支持,使其成为深度学习中的核心数据结构之一。 --- ### 切片操作 张量切片操作类似于 Python 列表或 NumPy 数组的索引方式。对于低维张量,可以直接通过下标访问特定位置的元素;对于高维张量,则需要指定多个维度的范围来提取子集。 #### 示例代码 ```python import torch x = torch.arange(1, 10).reshape(3, 3) # 创建一个 3x3 的张量 print(x) # 提取第 0 行的所有列 row_0 = x[0, :] print(row_0) # 提取第 1 列的所有行 col_1 = x[:, 1] print(col_1) # 提取左上角的一个子区域 sub_tensor = x[:2, :2] print(sub_tensor) ``` 上述代码展示了如何从三维空间中选取部分数据。需要注意的是,当涉及多维张量时,不同维度之间的索引需要用逗号 `,` 隔开[^2]。 --- ### NumPy 数组与张量的关系 NumPy 是一种强大的科学计算库,其核心对象是 ndarray(N 维数组)。虽然 NumPy 不具备硬件加速功能,但它提供了一套完整的 API 来处理各种数值运算任务。而 PyTorch 的张量设计初衷便是兼容 NumPy 并扩展其能力。 两者的主要区别在于: - **性能优化**:PyTorch 张量能够利用 CUDA 进行并行化计算,从而显著提升效率。 - **互操作性**:PyTorch 提供了一个简单的方法将 NumPy 数组转换为张量或将张量转换回 NumPy 数组。这种无缝切换使得开发者可以在 CPU/GPU 上自由迁移工作负载[^3]。 #### 转换示例 ```python import numpy as np import torch # 将 NumPy 数组转换为 PyTorch 张量 np_array = np.array([[1, 2], [3, 4]]) tensor_from_numpy = torch.from_numpy(np_array) print(tensor_from_numpy) # 将 PyTorch 张量转换为 NumPy 数组 tensor = torch.tensor([[5., 6.], [7., 8.]]) numpy_from_tensor = tensor.numpy() print(numpy_from_tensor) ``` 值得注意的是,如果原始 NumPy 数据位于主机内存 (CPU),那么对应的张量也会共享同一块地址空间,反之亦然[^3]。 --- ### 拼接的意义 拼接是指沿着某一特定轴方向连接两个或更多个张量的过程。这一过程通常由函数 `torch.cat()` 或者 `torch.stack()` 实现。前者适用于相同形状的对象按顺序排列组合成更大的整体;后者则是先增加一个新的维度再执行堆叠动作[^4]。 #### 应用场景分析 - 在图像分类模型训练过程中,可能需要把一批次的小图片串联起来形成批量输入给网络层; - 对于序列建模问题来说,时间步长上的特征也可能被横向或者纵向粘贴在一起以便后续加工处理。 以下是具体实现的例子: ```python # 使用 cat 方法沿 dim=0 方向拼接 x1 = torch.rand(2, 3) x2 = torch.rand(2, 3) result_cat_dim0 = torch.cat((x1, x2), dim=0) print(result_cat_dim0.shape) # 输出应为 (4, 3) # 使用 stack 方法新增加一层嵌套关系 y1 = torch.zeros(2, 2) y2 = torch.ones(2, 2) result_stack = torch.stack([y1, y2], dim=0) print(result_stack.shape) # 结果应该是 (2, 2, 2) ``` 以上案例说明了根据不同需求选择合适的工具完成目标的重要性[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值