TensorFlow——维度变换与Broadcasting

TensorFlow 维度变换

文章目录

  • TensorFlow 维度变换
    • 一.Reshape
    • 二.tf.transpose
    • 三.Squeeze和Expand_dims
  • Broadcasting
    • 前言
    • Broadcasting核心思想
    • Broadcasting有什么好处
    • Broadcasting演示

一.Reshape

这个方法是numpy的方法。不再赘述,需要说明的是,reshape虽然应用起来非常灵活。但是会造成一些问题。比如说,一个28乘以14的图片,你一不小心,把长宽的参数给搞反了,那么很容易就出bug。

而且,如果你真的想把长宽属性给颠倒一下,那么你就总得记住我哪个地方换了,那个地方没换,这样也很麻烦

二.tf.transpose

这个意思是:转置。这个单词其实本意是“交换,转换”。但实际上,转置也就意味着交换(英文真奇妙)

假设我这个长宽像素信息是按照[高度,宽度]存储的,我对这个矩阵转置,自然而然的就变成了[宽度,长度]。

在tensorFlow当中,tf.transpose的相关参数如下:

tf.transpose(
    a,
    perm=None,
    name='transpose',
    conjugate=False
) # 置换 a,根据 perm 重新排列尺寸

三.Squeeze和Expand_dims

Squeeze的英文含义:挤压。所以,从名称就可以知道,这是用来缩小维度的。

而Expand_dims从名字就可以看出,是用来升维的。

我们还以之前的,4个班级,每个班级35个学生,每个学生修8门课的示例为例:
TensorFlow——维度变换与Broadcasting_第1张图片

  • In[105]:在Expand_dims当中,如果指定axis=0,那么就会在0轴之前增加维度
  • In[106]:若axis指定最后一个,那么就会在最后增加一个维度。
  • In[107] 和 In[108] : Expand_dims支持后向索引

TensorFlow——维度变换与Broadcasting_第2张图片
关于squeeze,你可以像Expand_dims那样指定要操作的轴。除此之外呢,它还有一个特点,你若啥都不指定,那么会默认把所有的shape=1的维度给去掉(即:In[115]的部分)。

Broadcasting

前言

在Numpy当中就有Broadcasting,tensorFlow无缝继承了Numpy的Broadcasting,而且还进行了拓展了。总的来说,这是一种在不更新数据本身的情况下,对维度进行扩展的方法。

Broadcasting核心思想

在掌握Broadcasting的时候务必要知道以下要点:

首先,只适用于加减法。这是一个重要前提。

其次,知道如下步骤:

  • step1:首先,把两个数组,进行“右对齐”。比如说a.shape = [1,2,3,4], b.shape=[3,4]那么就首先把右侧的[3,4]部分对齐。

  • step2:如果二者维度相同,那么小的向大的靠拢,比如说:a.shape=[4,32,14,14],b.shape=[14,14]。

    那么,右对齐之后,(a+b).shape = [4,32,14,14]。这也算是一个要点:以短的为中心,必要的情况下,短的那个array,不断往前添1维。

  • step3:不过,对于step2这种情况下,也就只是1维的地方可以扩展。step2的时候,b的shape扩展为[1,1,14,14],正是因为前面两个是1,所以才能扩展。如果a.shape=[4,32,14,14],b.shape=[2,32,14,14]。那么不可以进行Broadcasting,因为b的第一维是2.

有一幅图,很好的反映了Broadcasting:

TensorFlow——维度变换与Broadcasting_第3张图片

Broadcasting有什么好处

首先,Broadcasting不会额外占用内存,所以,更加的节省空间

其次,现实确实需要这种需求,比如说,我有一组数据[classes, students, courses] = [4,32,8]。存在一个数组a当中代表一共4个班级,每个班级32个学生,每个学生修8门课程。我现在要把每个学生的每个课程的分数都加五分。

那么我大可以写[4,32,8] +[5.0](当然了,后面这个5.0是个8列的数据)

Broadcasting演示

In [1]: import tensorflow as tf
In [2]: import numpy as np
In [3]: x = tf.random.normal([4,32,32,3])
In [4]: (x+tf.random.normal([3])).shape
Out[4]: TensorShape([4, 32, 32, 3])

In [5]: (x+tf.random.normal([32,32,1])).shape
Out[5]: TensorShape([4, 32, 32, 3])

In [6]: (x+tf.random.normal([4,1,1,1])).shape
Out[6]: TensorShape([4, 32, 32, 3])

In [7]: x.shape
Out[7]: TensorShape([4, 32, 32, 3])

In [8]: (x+tf.random.normal([4,1,1,1])).shape
Out[8]: TensorShape([4, 32, 32, 3])

In [9]: b = tf.broadcast_to(tf.random.normal([4,1,1,1]),[4,32,32,3]) 
# 把shape为[4,1,1,1]的broadcast称为[4,32,32,3],如果不能Broadcasting,那么会报错

In [10]: b.shape
Out[10]: TensorShape([4, 32, 32, 3])

你可能感兴趣的:(tensorflow)