【TensorFlow2.0】(4) 维度变换、广播
各位同学好,今天我和大家分享一下TensorFlow2.0中有关数学计算的相关操作,主要内容有:
(1) 改变维度:reshape();(2) 维度转置:transpose();(3) 增加维度:expand_dims();(4) 减少维度:squeeze();(5) 广播:broadcasting_to()
那我们开始吧。
1. 维度变换
假设一张图像有四个维度: [ batch, row, width, channel ]
batch:理解为几张图像
row:图像的行
width:图像的列
channel:通道
图像维度的表示形式也有如下几种:
[b,28,28] 图像b有28行28列
[b,28*28] 不考虑行列信息,考虑整个图像的像素
[b,2,14*28] 将图片分成上下两个部分
[b,28,28,1] 增加一个channel通道,和第一种一样,只是增加一个通道
都没有改变原图像的数据点个数,只是换了一种理解方式
1.1 重新塑造维度
改变维度: tf.reshape(tensor, shape)
根据指定的shape改变tensor的维度。不会改变原tensor的维度,需要有变量去接收。改变图像的shape时,需要保证改变后的图像和原图像的数据点个数相同。
# 创建一个四维正态分布tensor
a = tf.random.normal([4,28,28,3])
# 查看形状
a.shape
# 按指定shape改变原形状
tf.reshape(a,[4,28*28,3]).shape
# 如果不想计算28*28可写成-1,-1这一项自动计算
tf.reshape(a,[4,-1,3]).shape
对创建的四维tensor改变形状,指定形状为 [4,28*28,3],这三个轴可以理解为 [图像, 像素, 通道],该变换,抹除了行和列的概念,变成784个像素去考虑,这时图像失去了二维信息。
如果不想计算28*28的值,还可以使用 '-1' 代替计算,函数碰到-1会自动计算两个数的乘积,注意,一个函数中只能出现一个-1,不然计算机不知道怎么去分配。
将原tensor从[4, 28, 28, 3],转换到 [4, 28*28*3],抹除行和列的概念,同时抹除通道的概念。将这种shape理解为[图像, 数据点],即有4幅图像,每幅图像有2352个数据点。若不想计算28*28*3,可以用-1代替计算。
a = tf.random.normal([4,28,28,3])
a.shape # 查看形状
# 抹除通道概念。理解为4个图像,每个图象有2352个数据点
tf.reshape(a,[4,28*28*3]).shape
# 用-1代替计算
tf.reshape(a,[4,-1]).shape
1.2 重新排列维度
转置: tf.transpose(tensor, perm)
tensor代表需要转置的变量,perm代表重新排列尺寸,不指定perm,默认为全部转置。
该方法会直接改变原图像的尺寸,不需要新变量去接收。
# 定义一个四维tensor
a = tf.random.normal([4,3,2,1])
a.shape
# 不传参数,全部转置
tf.transpose(a).shape
# 指定参数,新shape的0维度放原来的0维度,新shape的2维度放原来的3维度
tf.transpose(a,perm=[0,1,3,2]).shape
若不传参数,默认将tensor全部转置,如在矩阵中的行列互换,从三行两列变成两行三列。
若指定参数,perm=[0,1,3,2] 代表重新指定排列的顺序,新shape的第0个维度放原来的第0个维度,新shape的第1个维度放原来的第1个维度,新shape的第2个维度放原来的第3个维度,新shape的第3个维度放原来的第2个维度。也就是说从原来的[b,h,w,c] 变成 [b,h,c,w]
我们再看一例,加深理解。
# 从b维度转到[4,28,28,2]
b = tf.random.normal([28,2,4,28]) # [w,c,b,h]
tf.transpose(b,perm=[2,3,0,1]).shape # [b,h,w,c]
1.3 增加维度
指定位置增加一个维度: tf.expand_dims(tensor, axis)
tensor为需要增加维度的变量;axis为在哪个轴前面增加维度
不改变原始数据,需要有新变量去接收
# 4个班级35个学生8门课
a = tf.ones([4,35,8])
# 在最前面增加一个维度
tf.expand_dims(a,axis=0).shape
# 在指定位置前面添加一个维度,在课目前加一个维度
tf.expand_dims(a,axis=2).shape
axis=0代表指定第0个轴,即班级维度,在前面添加一个轴,理解为学校维度
如果轴axis为整数时,在指定轴前面增加一个新维度;若轴axis为负数时,在指定轴后面增加一个新维度。
b = tf.zeros([4,35,8]) # 下标为(-3,-2,-1)
# 理解为,在学生维度35后面增加一个维度
tf.expand_dims(b,axis=-2).shape
# 理解为,在课目维度8后面增加一个维度
tf.expand_dims(b,axis=-1).shape
1.4 减少维度
删除当前shape为1的维度: tf.squeeze(tensor, axis)
tensor代表需要减少维度的变量;axis代表指定删除哪一个轴的维度,如果存在多个shape为1的轴,不指定axis时,默认删除所有axis为1的轴。axis指定的轴必须是存在的且该轴的shape为1
不改变原数据,需要有新变量接收
# 创建一个五维tensor
a = tf.ones([1,2,1,1,3])
a.shape
# 不指定轴,默认删除所有维度为1的轴
tf.squeeze(a).shape
# 指定删除第0个轴
tf.squeeze(a,axis=0).shape
# 删除倒数第2个轴
tf.squeeze(a,axis=-2).shape
2. 广播
利用广播将原始tensor成倍增加: tf.broadcasting_to(tensor, shape)
tensor代表需要扩张的变量,shape代表需要扩张成什么样的
是一种张量维度扩张的手段,某一个维度重复n多次,但是没有真正的复制一个数据。是一种优化手段,没有复制数据,但是呈现出数据已经被扩张。
不会改变原数据,需要有变量来接收
举个例子说明一下:
计算时,如果a维度和b维度不一致时,在相应的维度上添加一个维度
a.shape = [4,16,16,32] 大维度 b.shape = [32] 小维度
先将小维度和大维度的右端对齐,如果小维度在大维度的相应维度上没有维度,就插入一个维度
b.shape = [1,1,1,32]
把插入的一维度扩张成相同的size,最终b通过broadcasting会输出
b.shape = [4,16,16,32]
broadcasting没有复制数据,把它理解成已经复制了,用于优化计算
小维度某个轴的shape为1时可以扩张成大维度对应轴的shape,如果为其他shape不可以扩张
如在计算a维度和b维度,a.shape = [4,32,14,14],b.shape = [2,32,14,14],在轴axis=0处,b的shape为2,不可以进行扩张,如果是1可以进行扩张,因此,这两个tensor不可以运算。
下面,我们看一下代码
#(1)不调用函数自动计算
# 定义一个四维tensor
a = tf.random.normal([4,32,32,3])
# 大维度加小维度,先对小维度扩张
(a + tf.random.normal([32,32,1])).shape
# 由于轴axis=1对应的shape不同且不为1,不能扩张
(a + tf.random.normal1([1,4,1,1])).shape # 不能计算
在计算时,我们选择可以不用调用广播的函数,计算时,计算机会自动执行广播的方法,对小维度扩张。因此,shape为[32,32,1]被扩张成[1,32,32,1],再变成[4,32,32,3],然后这两个tensor就可以进行计算了。
而第二个计算,shape为[1,4,1,1],由于小维度的axis=1对应的shape为4,大维度shape为32,无法进行广播扩张,只有shape是1时才能扩张。
我们也可以调用广播函数tf.broadcast_to(input, shape)进行扩张
# 定义2个需要计算的tensor
a = tf.random.normal([4,32,32,3])
b = tf.random.normal([32,32,1])
# 利用广播函数将b扩张成a,利用新变量x接收扩张后的结果
x = tf.broadcast_to(b,a.shape)
x.shape
对变量a和b计算前,需要将a和b的维度变成一样的,因此需要将小维度的b扩张成和变量a一样的维度。又因为广播函数不会改变原值,所以用新变量x来接收广播完成后的b。
【TensorFlow2.0】(4) 维度变换、广播相关推荐
- TensorFlow2.0:维度变换
** 一 reshape函数 重排列 ** In [1]: import tensorflow as tf In [2]: a = tf.random.normal([4,28,28,3],mean= ...
- 深度学习_TensorFlow2.0基础_张量创建,运算,维度变换,采样
Tensorflow2.0 基础 一:TensorFlow特性 1.TensorFlow An end-to-end open source machine learning platform end ...
- mybatis-plus对datetime返回去掉.0_华为AI认证-TensorFlow2.0编程基础
参考<HCIA-AI2.0培训教材><HCIA-AI2.0实验手册> 认证要求: 了解TensorFlow2.0是什么以及其特点 掌握TensorFlow2.0基础和高阶操作方 ...
- TensorFlow2.0学习
文章目录 一.TensorFlow的建模流程 1.1 结构化数据建模流程范例 1.1.1 准备数据 1.1.2 定义模型 1.1.3 训练模型 1.1.4 评估模型 1.1.5 使用模型 1.1.6 ...
- 【TensorFlow2.0】(5) 数学计算、合并、分割
各位同学好,今天和大家分享一下TensorFlow2.0中的数学运算方法.合并与分割.内容有: (1)基本运算:(2)矩阵相乘:(3)合并 tf.concat().tf.stack():(4)分割 t ...
- 图注意力网络(Graph Attention Network, GAT) 模型解读与代码实现(tensorflow2.0)
前面的文章,我们讲解了图神经网络三剑客GCN.GraphSAGE.GAT中的两个: 图卷积神经网络(GCN)理解与tensorflow2.0代码实现 GraphSAGE 模型解读与tensorflow ...
- 深度学习(8)TensorFlow基础操作四: 维度变换
深度学习(8)TensorFlow基础操作四: 维度变换 1. View 2. 示例 3. Reshape操作可能会导致潜在的bug 4. tf.transpose 5. Squeeze VS Exp ...
- python维度变换_Python NumPy用法
介绍 NumPy是Python数值计算最重要的基础包,大多数提供科学计算的包都是用NumPy的数组作为构建基础.NumPy本身并没有提供多么高级的数据分析功能,理解NumPy数组以及面向数组的计算,将 ...
- 〖TensorFlow2.0笔记21〗自定义数据集(宝可精灵数据集)实现图像分类+补充:tf.where!
自定义数据集(宝可精灵数据集)实现图像分类+补充:tf.where! 文章目录 一. 数据集介绍以及加载 1.1. 数据集简单描述 1.2. 程序实现步骤 1.3. 加载数据的格式 1.4. map函 ...
最新文章
- Linux下进程间通信——管道
- python中format函数用法简书_Python 中format 的用法
- matlab撤销上一步命令_CAD快速入门技巧:CAD软件中撤销操作的方法汇总
- java 自旋锁_java锁的种类以及辨析(一):自旋锁
- 【Java线程】Thread Runnable必知必会
- 深度优先搜索——选数(洛谷 P1036)
- Linux下修改mysql密码以及忘记密码重置
- 计算机编程与数控宏程序实例教程,数控车床编程教程,图文实例详解
- 关于 HenCoder
- SVG和G语言的混合显示引擎
- 《鸟哥 Linux 私房菜:基础版》阅读笔记
- RGB888和RGB565互相转换
- 本地win10服务器不能复制文件,解决Win10无法复制文件并提示“0x80070032”错误的方法...
- 怎么查看linux系统硬盘,Linux系统下如何查看所有存储设备(磁盘分区)
- spring-security 实现单点登录
- RHY融获基金数字资产投资,海外扩建加速
- 一直听说“不忘初心”,今天才知道真正内涵!
- 七牛云php回调,回调通知_开发指南_对象存储 - 七牛开发者中心
- 自己动手实现RAFT算法
- 西门子s7-1200博图v16灌装机PLC程序+西门子KTP1200触摸屏程序 1200plc和3台v90伺服pn通讯
热门文章
- Json 动态获取key 或者获取value
- 用 Hystrix 构建高可用服务架构
- PL/SQL Developer(解压版)连接64位的Oracle11g
- PyTorch 笔记(15)— 分别使用 tensor、autograd、torch.nn 搭建简易神经网络
- Ubuntu 安装 CUDA 和 cuDNN 详细步骤
- 另类L2TP Tunnel
- Corn Fields(POJ 3254状压dp)
- C# SQLiteHelper
- js判断 IE 浏览器
- android jni语法,Android NDK中的JNIEXPORT和JNICALL