【tensorflow】张量Tensor的操作(创建,变换和分割)

2023-10-26

参考链接:

https://blog.csdn.net/yeshang_lady/article/details/124615743?ops_request_misc=&request_id=&biz_id=102&utm_term=tensorflow%20%E5%BC%A0%E9%87%8F&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-5-124615743.142v52pc_rank_34_queryrelevant25,201v3add_ask&spm=1018.2226.3001.4187

TF中张量的操作

import tensorflow as tf
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  # 不显示等级2以下的提示信息,去掉tf一些烦人的输出

1 张量的创建

1.1 使用tf.constant创建张量

可以直接在tf.constant中写入数组来构建tensor,此时如果指定数据类型,就会按照指定的创建.如果不指定数据类型,会自动分配数据类型.

如果都是整数,那么dtype就是int型,如果有一个元素是浮点,那么dtype就是float型.
整形当中,默认最小的类型是int32,不会使用int16,除非额外特别指定.
int16: -32768~32767
int32:-2147483648~2147483647
int64:-9223372036854775808~9223372036854775807

单精度:float32:精确到小数点后6位,4个字节
双精度:float64:精确到小数点后15位,8个字节

tf.constant([1,2,3,4,5,6])
<tf.Tensor: shape=(6,), dtype=int32, numpy=array([1, 2, 3, 4, 5, 6], dtype=int32)>

创建的变量类型都是EagerTensor

a  = tf.constant([1,2,3,4,5,6])
type(a)
tensorflow.python.framework.ops.EagerTensor

可以通过.numpy()来访问数组

a.numpy()
array([1, 2, 3, 4, 5, 6], dtype=int32)
tf.constant([1,2,3,4,5,6],dtype=tf.int16)
<tf.Tensor: shape=(6,), dtype=int16, numpy=array([1, 2, 3, 4, 5, 6], dtype=int16)>
tf.constant([1,2,3,4,5,6.1])
<tf.Tensor: shape=(6,), dtype=float32, numpy=array([1. , 2. , 3. , 4. , 5. , 6.1], dtype=float32)>

也可以先通过numpy创建数组a,然后通过tf.constant(a)创建tensor.

a = np.array([1,2,3,4,5,6])
tf.constant(a)
<tf.Tensor: shape=(6,), dtype=int32, numpy=array([1, 2, 3, 4, 5, 6], dtype=int32)>

如果设定了shape,那么会对value进行reshape.
当value是一个常数时,会被复制填充shape
当value本身就是一个数组时,则要求元素数量必须和reshape后的数量一致,否则会报错.

tf.constant(1,shape=(2,3))
<tf.Tensor: shape=(2, 3), dtype=int32, numpy=
array([[1, 1, 1],
       [1, 1, 1]], dtype=int32)>
tf.constant([1,2,3,4,5,6],shape=(2,3))
<tf.Tensor: shape=(2, 3), dtype=int32, numpy=
array([[1, 2, 3],
       [4, 5, 6]], dtype=int32)>

另外,如果value是一个eager值,则没有影响,还可以计算梯度

v= tf.Variable([0.0])
u=tf.Variable([1.1])
with tf.GradientTape()  as g:
    loss = tf.constant(3*v+u)  #等效于loss = 3*v + u
g.gradient(loss,v).numpy()

array([3.], dtype=float32)

但是如果value是一个符号张量,tf.constant(value)就会报错了.

所谓的符号张量可以理解为只是声明的为tf.graph,并没有实例化.只有在图流动时才进行实例化.

with tf.compat.v1.Graph().as_default():
    i=tf.compat.v1.placeholder(shape=[None, None], dtype=tf.float32)
    t=tf.constant(i)

其他相关操作:

(1)tf.convert_to_tensor()
也可以创建tensor,但是与tf.constant有两点不同

  1. 不能使用shape指定形状
  2. 允许使用符号张量
    例如同样value i 下面的转化就不会报错.
with tf.compat.v1.Graph().as_default():
    i=tf.compat.v1.placeholder(shape=[None, None], dtype=tf.float32)
    t=tf.convert_to_tensor(i)

(2)tf.fill()可以用于创建标量构成的tensor,但是与tf.constant有很大不同:

  1. tf.fill只支持标量常数tf.constant支持任意常数
  2. tf.fill可以在运行时任意修改,因此在表示大型tensor时效率更高
  3. tf.fill并不嵌入值,所以它可以产生动态的输出尺寸
tf.fill([2,3],9.1)
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[9.1, 9.1, 9.1],
       [9.1, 9.1, 9.1]], dtype=float32)>

1.2 创建特殊张量

1.2.1 创建全0,1,自定义数值张量

这种创建出来的张量内元素值都是一样的.

tf.ones创建全1张量,tf.zeros创建全0张量

默认会采用tf.float32的变量类型存储

tf.ones([2,3],dtype=tf.int32)
<tf.Tensor: shape=(2, 3), dtype=int32, numpy=
array([[1, 1, 1],
       [1, 1, 1]], dtype=int32)>
tf.zeros([2,3])
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[0., 0., 0.],
       [0., 0., 0.]], dtype=float32)>

当然,也可以使用1.1中的constant,fill,convert_to_tensor创建变量

tf.constant(0,shape=[2,3])
<tf.Tensor: shape=(2, 3), dtype=int32, numpy=
array([[0, 0, 0],
       [0, 0, 0]], dtype=int32)>
tf.fill((2,3),1)
<tf.Tensor: shape=(2, 3), dtype=int32, numpy=
array([[1, 1, 1],
       [1, 1, 1]], dtype=int32)>
a = np.zeros((2,3))
tf.convert_to_tensor(a)
<tf.Tensor: shape=(2, 3), dtype=float64, numpy=
array([[0., 0., 0.],
       [0., 0., 0.]])>

1.2.2 创建符合特殊分布的张量

都是通过tf.random函数进行构建

  • 符合[min,max]的均匀分布的张量
tf.random.uniform([1,5],minval=0,maxval=5)
<tf.Tensor: shape=(1, 5), dtype=float32, numpy=
array([[4.3903494 , 2.6431446 , 2.7990234 , 0.94691813, 3.3530939 ]],
      dtype=float32)>
  • 指定均值方差的正态分布
tf.random.normal([2,2],mean=5,stddev=0.1)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[4.9246736, 4.816348 ],
       [4.970745 , 5.017907 ]], dtype=float32)>

创建一个连续的序列,和python自带的range函数基本一致

tf.range(1,10,2)
<tf.Tensor: shape=(5,), dtype=int32, numpy=array([1, 3, 5, 7, 9], dtype=int32)>
for i in range(1,10,2):
    print(i)
1
3
5
7
9

1.3 可变张量

前面可以知道,tf.constant创建的张量是不可优化的.而tf.variable建立的变量是可以优化的.

a = tf.constant([1,2,3])
b = tf.Variable([1,2,3])
c = tf.fill([1,2],0)
i = np.zeros((2,3))
d = tf.convert_to_tensor(i)

print(type(a))
print(type(b))
print(type(c))
print(type(d))
<class 'tensorflow.python.framework.ops.EagerTensor'>
<class 'tensorflow.python.ops.resource_variable_ops.ResourceVariable'>
<class 'tensorflow.python.framework.ops.EagerTensor'>
<class 'tensorflow.python.framework.ops.EagerTensor'>

可见,只有 通过tf.Variable建立的变量才是可以用于模型训练的变量.并且tf.Variable变量有特有的属性:

print(b.name,b.trainable)
Variable:0 True

1.4 其他tf.xx_initializer()类方法

Tensorflow中有几个以initializer结尾的方法,这几个方法的使用有一些特殊,因为这些方法得到的并不是张量,而是一个可调用对象。下面以tf.random_uniform_initializer()为例进行说明。具体如下:

组合起来,就可以创建一些具有特殊分布的张量,例如下面就是创建了一个具有均匀分布的tensor变量

a = tf.random_uniform_initializer(minval=0,maxval=5) #产生均匀分布的函数
print(type(a))
print(callable(a))
<class 'tensorflow.python.ops.init_ops_v2.RandomUniform'>
True
tf.constant(a(shape=[2,3],dtype=tf.int32))
<tf.Tensor: shape=(2, 3), dtype=int32, numpy=
array([[0, 4, 2],
       [2, 3, 3]], dtype=int32)>

2.基础操作

2.1 维度变换

  • 增加新的维度:tf.expand_dims

a = tf.random.uniform([2,3],0,10,dtype=tf.int32)
print(a)
b=tf.expand_dims(a,axis=0)
print(b)
c= tf.expand_dims(a,axis=1)
print(c)
d= tf.expand_dims(a,axis=2)
print(d)
tf.Tensor(
[[7 5 2]
 [0 4 3]], shape=(2, 3), dtype=int32)
tf.Tensor(
[[[7 5 2]
  [0 4 3]]], shape=(1, 2, 3), dtype=int32)
tf.Tensor(
[[[7 5 2]]

 [[0 4 3]]], shape=(2, 1, 3), dtype=int32)
tf.Tensor(
[[[7]
  [5]
  [2]]

 [[0]
  [4]
  [3]]], shape=(2, 3, 1), dtype=int32)
  • 删除维度 tf.squeeze ,会自动删除tensor size=1的维度
d = tf.squeeze(b)
print(d)

tf.Tensor(
[[7 5 2]
 [0 4 3]], shape=(2, 3), dtype=int32)

上面的两种方法: tf.expand_dims和tf.squeeze都不会改变张量的存储顺序和大小,值是改变了理解方式.

  • 复制张量

tf.tile()

a = tf.constant([1,2,3,4])
b = tf.tile(a,multiples=[2])
print(b)
tf.Tensor([1 2 3 4 1 2 3 4], shape=(8,), dtype=int32)
a = tf.constant([1,2,3,4],shape=[2,2])
b = tf.tile(a,multiples=[2,2])
print(b)
tf.Tensor(
[[1 2 1 2]
 [3 4 3 4]
 [1 2 1 2]
 [3 4 3 4]], shape=(4, 4), dtype=int32)

2.2 张量的合并

  • tf.concat()拼接

下面对a和b在axis=0的维度进行拼接

a = tf.random.uniform([2,3],1,10,dtype=tf.int32)
b= tf.random.uniform([1,3],1,10,dtype=tf.int32)
c = tf.concat([a,b],axis=0)
print(tf.shape(c))
print(c.shape)
tf.Tensor([3 3], shape=(2,), dtype=int32)
(3, 3)
  • tf.stack()拼接时的对象的shape必须完全一样
a = tf.random.uniform([2,3],1,10,dtype=tf.int32)
b= tf.random.uniform([2,3],1,10,dtype=tf.int32)
c = tf.stack([a,b],axis=0)
print(a)
print(b)
print(c)
tf.Tensor(
[[3 8 7]
 [9 8 6]], shape=(2, 3), dtype=int32)
tf.Tensor(
[[3 4 6]
 [3 9 4]], shape=(2, 3), dtype=int32)
tf.Tensor(
[[[3 8 7]
  [9 8 6]]

 [[3 4 6]
  [3 9 4]]], shape=(2, 2, 3), dtype=int32)

上述过程可以用expand_dim和concat来复现:

a = tf.expand_dims(a,axis=0)
b = tf.expand_dims(b,axis=0)
c = tf.concat([a,b],axis=0)
print(c)
tf.Tensor(
[[[3 8 7]
  [9 8 6]]

 [[3 4 6]
  [3 9 4]]], shape=(2, 2, 3), dtype=int32)

2.3 张量分割

张量分割就是张量合并的逆过程

a = tf.squeeze(a) 
print(a)
tf.Tensor(
[[3 8 7]
 [9 8 6]], shape=(2, 3), dtype=int32)

通过调整axis可以指定切片的维度.

a_split_1=tf.split(a,num_or_size_splits=[1,2],axis=1)
a_split_0=tf.split(a,num_or_size_splits=[1,1],axis=0)
print(a_split_1[0])
print(a_split_1[1])
print(a_split_0[0])
print(a_split_0[1])

tf.Tensor(
[[3]
 [9]], shape=(2, 1), dtype=int32)
tf.Tensor(
[[8 7]
 [8 6]], shape=(2, 2), dtype=int32)
tf.Tensor([[3 8 7]], shape=(1, 3), dtype=int32)
tf.Tensor([[9 8 6]], shape=(1, 3), dtype=int32)

同一个axis也可以有不同的切片方式,通过调整num_or_size_splits=[1,1,1],就可以把a张量切片成3分

a_split_1=tf.split(a,num_or_size_splits=[1,1,1],axis=1)
print(a_split_1[0])
print(a_split_1[1])
print(a_split_1[2])

tf.Tensor(
[[3]
 [9]], shape=(2, 1), dtype=int32)
tf.Tensor(
[[8]
 [8]], shape=(2, 1), dtype=int32)
tf.Tensor(
[[7]
 [6]], shape=(2, 1), dtype=int32)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【tensorflow】张量Tensor的操作(创建,变换和分割) 的相关文章

随机推荐

  • 【代码记录】pytorch推理及与onnx推理精度对比

    1 pytorch推理 import cv2 import sys import numpy as np import torch os from torch import nn import torchvision models as m
  • 子串/子段问题总结

    1 一般子串问题 求一个串中满足某种条件的子串 1 如果所求子串的条件是一个值 比如sum 则考虑子段问题 注意这样一个性质 子段 前缀差 子段和 前缀和的差 vector
  • 4.3 链码的其它操作:实现对链码的打包升级

    目标 实现如何对链码打包签名 链码升级的实现 任务实现 链码部署除了正常的安装 实例化操作步骤之外 还有一种部署方式 即先将链码进行打包 然后对已打包的文件进行签名 最后再进行安装与实例的操作 4 3 1 链码打包及签名 4 3 1 1 打
  • final-期末大作业-制作AR射箭小游戏(Unity AR配置详细教程)

    要求 大作业要求 制作一款特定技术应用小游戏 并提交技术报告 内容 请参考以下技术主题 但不限于这些主题 运用手机拍若干全景图 贴到天空盒或球型天空 做一个简单校园漫游功能 粒子系统效果制作 必须带一个控制组件 控制粒子呈现效果 UI系统制
  • mysql 扁平结构设计_数组扁平化

    TOC 简介 数组的扁平化 就是将一个嵌套多层的数组 array 嵌套可以是任何层数 转换为只有一层的数组 举个例子 假设有个名为 flatten 的函数可以做到数组扁平化 效果就会如下 js var arr 1 2 3 4 console
  • Pycharm常用快捷键大全,初学友好,不怕记不住

    初来乍到 我是爱摸鱼的芝士呐 一 pycharm的简单介绍 字多可以跳过 pycharm是全宇宙最适合Python的编辑器 没有之一 个人见解勿杠杠就是你对 虽然看似全是英文 对于英语不好的小伙伴不友好 但是 不管是代码还是菜单栏 都有翻译
  • 照片转换为超声图像(MATLAB仿真)

    照片转换为超声图像 MATLAB 仿真实现 任意选取一张照片转换为超声图像 1 选取一张照片 2 将照片转换为散射点 3 进行超声成像仿真
  • Echarts formatter

    提示框浮层内容格式器 支持字符串模板和回调函数两种形式 回调函数 params Object Array ticket string callback ticket string html string gt string HTMLElem
  • 威纶通定时循环操作宏_威纶通触摸屏宏指令的使用

    工控多年的公众号运营者 我经常分享原创技术内容 内容涉及到工业多个方面 分享新知识带你一起进步 今天看到一个例程 想再写一下威纶通触摸屏宏指令的使用 之前有分享过一篇有关威纶通关于宏指令使用的文章 那篇文章的宏只用过 GetData 指令
  • iis多进程下的全局变量_python下多线程的限制以及多进程中传递参数的方式!不来瞅瞅?...

    欢迎各位小哥哥小姐姐阅读本的文章 对大家学习有帮助 请点赞加关注哦 您的点赞和关注将是我持续更新的动力呢 v 有不懂的问题可以私聊我哦 python下多线程的限制以及多进程中传递参数的方式 python多线程有个全局解释器锁 global
  • C#桌面程序无法调试以及无法查看变量的解决办法

    作者 朱金灿 来源 clever101的专栏 为什么大多数人学不会人工智能编程 gt gt gt 一 问题描述 最近在调试一个C 桌面程序 总是无法进入调试状态 后来能进入调试状态了 却无法查看程序变量的值 二 问题解决过程 经过搜索网上资
  • python 中wheel 安装_python中wheel的用法整理

    Python的第一个主流打包格式是 egg文件 现在大家庭中又有了一个叫做Wheel whl 的新成员 wheel 被设计成包含PEP 376兼容安装 一种非常接近于磁盘上的格式 的所有文件 在本文中 我们将学习如何创建一个wheel以及如
  • linux 命令行报bash command not found的解决办法

    命令行报bash command not found的解决办法 几乎所有命令 命令行输入命令执行后报 bash command not found 这是由于系统PATH设置问题 PATH没有设置对 系统就无法找到精确命令了 1 在命令行中输
  • Nginx 返回自定义 text 或 json

    叙述 有些时候请求某些接口的时候需要返回指定的文本字符串或者json字符串 如果逻辑非常简单或者干脆是固定的字符串 那么可以使用nginx快速实现 这样就不用编写程序响应请求了 可以减少服务器资源占用并且响应性能非常快 解决方案 固定文本
  • 实时音频编解码之十五 Opus编码-CELT编码

    本文谢绝任何形式转载 谢谢 4 3 1 基频预滤波 对预加重之后信号预滤波 其和解码器的后滤波相反 基频周期搜索应根据以下标准优化 1 连续性 对于连续帧 基频周期通常不会突变 2 避免基频倍数 当使用的周期是实际周期的倍数时 后滤波器失去
  • 蓝桥杯真题:算式问题

    emmm其实是算全排列的问题 按照STL文档的描述 next permutation函数将按字母表顺序生成给定序列的下一个较大的排列 直到整个序列为降序为止 prev permutation函数与之相反 是生成给定序列的上一个较小的排列 具
  • 超详细!!!Linux:利用Shell脚本使用case分支语句

    case分支语句 case 语句 case语句主要适用情况 case分支语句语法结构 case值得注意的特点 case语句应用示例 1 检查用户输入字符类型 2 编写系统服务脚本 case 语句 case语句主要适用情况 某个变量存在多种取
  • Nginx+tomcat 实现前后端分离(解决跨域)

    工具 nginx 1 15 3 apache tomcat 9 0 11 代码准备 前端 新建前端文件 结构如下 index html代码如下
  • 腾讯股票数据接口 http/javascript

    From http blog csdn net ustbhacker article details 8365756 之前使用了新浪的股票数据 由于新浪http javascript缺少一些数据 用chrome自带的开发工具监视腾迅财经HT
  • 【tensorflow】张量Tensor的操作(创建,变换和分割)

    参考链接 https blog csdn net yeshang lady article details 124615743 ops request misc request id biz id 102 utm term tensorfl