TensorFlow 基础(一)张量

news2024/12/25 9:06:37

文章目录

  • Basics
  • About shapes
  • Indexing
    • Single-axis indexing
    • Multi-axis indexing
  • Manipulating Shapes
  • More on dtypes
  • References


import tensorflow as tf
import numpy as np

Basics

张量是具有统一类型(dtype)的多维数组。它和 NumPy 中的 np.arrays 是非常类似的。如 Python 的数值和字符串类型一样,张量是不可变的(immutable):张量内容无法更新,只能创建新的张量。

包含单个数值的标量我们可以叫做 0-秩张量(rank-0),它没有轴:

rank_0_tensor = tf.constant(22)
rank_0_tensor
"""
<tf.Tensor: shape=(), dtype=int32, numpy=22>
"""

包含一个值列表的向量可以叫做 1-秩张量,它有一个轴:

rank_1_tensor = tf.constant([2.0, 3.0, 5.0])
rank_1_tensor
"""
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([2., 3., 5.], dtype=float32)>
"""

矩阵可以叫做 2-秩张量,它有两个轴:

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

张量也可以包含更多的轴,如 3 个或者 4 个,这也是我们在处理计算机视觉问题时最常遇到的轴维度,下面是一个 3-秩张量

rank_3_tensor = tf.constant([
    [[0, 1, 2, 3, 4],
     [5, 6, 7, 8, 9]],
    [[10, 11, 12, 13, 14],
     [15, 16, 17, 18, 19]],
    [[20, 21, 22, 23, 24],
     [25, 26, 27, 28, 29]]
])
rank_3_tensor
"""
<tf.Tensor: shape=(3, 2, 5), dtype=int32, numpy=
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9]],

       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29]]], dtype=int32)>
"""

我们可以使用 np.array 函数或者 .numpy 方法来将一个张量转换成 NumPy 数组:

np.array(rank_2_tensor)
"""
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)
"""
rank_3_tensor.numpy()
"""
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9]],

       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29]]], dtype=int32)
"""

我们可以对张量做一些基本的数学运算,如加法、逐元素乘法和矩阵乘法:

a = tf.constant([[1, 2],
                 [3, 4]])
b = tf.constant([[1, 1],
                 [1, 1]]) # 也可写为 b = tf.ones([2, 2])
print(tf.add(a, b), "\n")
print(tf.multiply(a, b), "\n")
print(tf.matmul(a, b), "\n")
"""
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

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

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)
"""

另外一种写法:

print(a + b, "\n")
print(a * b, "\n")
print(a @ b, "\n")
"""
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

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

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

"""

About shapes

张量形状的几个相关术语:

  • 形状(shape):张量的每个轴的长度(即元素数量)
  • (rank):张量的轴数
  • 轴或维度(axis or dimension):张量的某个维度
  • 大小(size):张量的总项数,即形状向量的乘积

下面我们来看如何来访问这些属性:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
print("Type of every element:", rank_4_tensor.dtype)
print("Number of dimensions:", rank_4_tensor.ndim)
print("Shape of tensor:", rank_4_tensor.shape)
print("Elements along axis 0 of tensor", rank_4_tensor.shape[0])
print("Total number of elements (3*2*4*5):", tf.size(rank_4_tensor).numpy())
"""
Type of every element: <dtype: 'float32'>
Number of dimensions: 4
Shape of tensor: (3, 2, 4, 5)
Elements along axis 0 of tensor 3
Total number of elements (3*2*4*5): 120
"""

.ndim.shape 方法返回的不是张量对象,如果想要返回张量,则需使用 tf.ranktf.shape 函数。

虽然通常用索引来指代轴,但在我们的实际问题中,每个轴是有实际含义的,如下图所示:
在这里插入图片描述
在计算机视觉任务中,即对于图片数据集来说,最后一个轴表示的其实为通道数。


Indexing

Single-axis indexing

单轴索引和 Python 中的列表以及 NumPy 索引类似。

标量索引:

rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
print("First:", rank_1_tensor[0].numpy())
print("Second:", rank_1_tensor[1].numpy())
print("Last:", rank_1_tensor[-1].numpy())
"""
First: 0
Second: 1
Last: 34
"""

使用冒号的切片索引:

print("Everything:", rank_1_tensor[:].numpy())
print("Before 4:", rank_1_tensor[:4].numpy())
print("From 4 to the end:", rank_1_tensor[4:].numpy())
print("From 2, before 7:", rank_1_tensor[2:7].numpy())
print("Every other item:", rank_1_tensor[::2].numpy()) # start:stop:step
print("Reversed:", rank_1_tensor[::-1].numpy())
"""
Everything: [ 0  1  1  2  3  5  8 13 21 34]
Before 4: [0 1 1 2]
From 4 to the end: [ 3  5  8 13 21 34]
From 2, before 7: [1 2 3 5 8]
Every other item: [ 0  1  3  8 21]
Reversed: [34 21 13  8  5  3  2  1  1  0]
"""

Multi-axis indexing

对于高秩张量的每个单独的轴,遵循与单轴情形完全相同的规则。

为每个索引轴传递一个整数,结果是对应位置的标量:

print(rank_2_tensor)
rank_2_tensor[1, 1].numpy()
"""
tf.Tensor(
[[1. 2.]
 [3. 4.]
 [5. 6.]], shape=(3, 2), dtype=float16)
4.0
"""

索引任何行、列:

print("Second row:", rank_2_tensor[1, :].numpy())
print("Second column:", rank_2_tensor[:, 1].numpy())
print("Last row:", rank_2_tensor[-1, :].numpy())
print("First item in last column:", rank_2_tensor[0, -1].numpy())
print("Skip the first row:")
print(rank_2_tensor[1:, :].numpy(), "\n")
"""
Second row: [3. 4.]
Second column: [2. 4. 6.]
Last row: [5. 6.]
First item in last column: 2.0
Skip the first row:
[[3. 4.]
 [5. 6.]]
"""

对于我们上面定义的 3-秩张量,我们想选择每个批次中每个示例的所有位置的最后一个特征:

rank_3_tensor[:, :, 4]
"""
tf.Tensor(
[[ 4  9]
 [14 19]
 [24 29]], shape=(3, 2), dtype=int32)
"""

我们会得到一个二维张量,画出图来就是这样的:
在这里插入图片描述
稍微做些改动:

rank_3_tensor[:, :, 4:]
"""
tf.Tensor(
[[[ 4]
  [ 9]]

 [[14]
  [19]]

 [[24]
  [29]]], shape=(3, 2, 1), dtype=int32)
"""

我们会发现得到的是一个三维张量。所以一定要注意冒号的使用。


Manipulating Shapes

x = tf.constant([[1], [2], [3]])
print(x.shape)
"""
(3, 1)
"""

可以将返回的 TensorShape 对象转换为列表:

print(x.shape.as_list())
"""
[3, 1]
"""

使用 .reshape 方法改变张量的形状,该方法速度很快,资源消耗很低,因为不需要复制底层数据。

reshaped = tf.reshape(var_x, [1, 3])

注意我们传入的形状为列表类型

print(var_x.shape)
print(reshaped.shape)
"""
(3, 1)
(1, 3)
"""

TensorFlow 使用“行优先”的内存访问顺序。把一个张量展平,我们可以看到它在内存中的排列顺序:

print(rank_3_tensor)
"""
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)
"""
print(tf.reshape(rank_3_tensor, [-1]))
"""
tf.Tensor(
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29], shape=(30,), dtype=int32)
"""

利用 tf.reshape 无法实现轴的交换,要交换轴,我们需要使用 tf.transpose

tf.transpose(rank_3_tensor, (1, 0, 2))
"""
<tf.Tensor: shape=(2, 3, 5), dtype=int32, numpy=
array([[[ 0,  1,  2,  3,  4],
        [10, 11, 12, 13, 14],
        [20, 21, 22, 23, 24]],

       [[ 5,  6,  7,  8,  9],
        [15, 16, 17, 18, 19],
        [25, 26, 27, 28, 29]]], dtype=int32)>
"""

More on dtypes

如果创建张量时没有指定数据类型,TensorFlow 会将 Python 整数转换为 tf.int32,将 Python 浮点数转换为 tf.float32。另外,当转换为数组时,TensorFlow 会采用与 NumPy 相同的规则。

我们可以使用 tf.cast 函数来转换张量的数据类型:

the_f64_tensor = tf.constant([2.2, 3.3, 4.4], dtype=tf.float64)
the_f16_tensor = tf.cast(the_f64_tensor, dtype=tf.float16)
the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)
print(the_u8_tensor)
"""
tf.Tensor([2 3 4], shape=(3,), dtype=uint8)
"""

References

TensorFlow 官方文档 (https://tensorflow.google.cn/guide/tensor)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/144446.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C进阶_C语言_函数与指针_C语言指针进阶

上一篇博客http://t.csdn.cn/GYCiM 我们了解了指针相关知识&#xff0c;今天来了解函数和指针的关系。 目录 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 qsort 冒泡排序模拟实现qsort 函数指针 我们知道&#xff0c;数组指针是指向数组的指针。 int arr[…

Ribbon负载均衡服务调用

文章目录一. 什么是Ribbon二. Ribbon负载均衡三. Ribbon负载均衡策略四. Ribbon饥饿加载一. 什么是Ribbon PS: 本篇文章文作者学习笔记&#xff0c;技术参考价值不大。 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端&#xff0c;负载均衡的工具。 简单的说&#x…

Allegro174版本新功能介绍之改变报表字体大小

Allegro174版本新功能介绍之改变报表字体大小 Allegro在升级到174的时候,默认show element的字体是非常小的,类似下图,辨认起来非常困难 但是174是支持把字体调整的大一些的,具体操作如下 选择Setup选择User Preferences

SpringBoot整合java诊断工具Arthas

一、Arthas官方文档https://arthas.aliyun.com/doc/二、springBoot整合方式1、pom文件引入<dependency><groupId>com.taobao.arthas</groupId><artifactId>arthas-spring-boot-starter</artifactId><version>3.6.7</version> </d…

机器学习:机器学习常见的算法分类和算法优缺点汇总

机器学习实战教程(13篇)_M_Q_T的博客-CSDN博客这些网址非常适合想学习机器学习&#xff0c;却苦于没有项目&#xff08;尤其缺少数据&#xff09;的人。无意中看到&#xff0c;给自己做一个记录。目录大类&#xff1a;学习方式监督式学习&#xff1a;非监督式学习&#xff1a;半…

ES6 课程概述③

文章目录5-1. 新增的对象字面量语法5-2. Object 的新增 API5-4 类&#xff1a;构造函数的语法糖传统的构造函数的问题类的特点5-5. 类的其他书写方式5-1. 新增的对象字面量语法 成员速写 如果对象字面量初始化时&#xff0c;成员的名称来自于一个变量&#xff0c;并且和变量的…

2023/01/05 java面试题每日10问

1.What is Java? Java is object-oriented, platform-independent, Multithreaded, and portable programming language.it provides its own JRE and API. 2.What is the difference between JDK, JRE, and JVM? JVM Java Virtual Machine provides the runtime environm…

小小闭门会,揭示SaaS大趋势

从2014年中国的SaaS领域开始有融资到现在已经8年&#xff0c;从最开始的一张云图填不满到现在的密密麻麻&#xff0c;厂商和产品如雨后春笋般的多了起来&#xff0c;但很多SaaS依然在孤军奋战&#xff0c;很多厂商陷入定制化泥潭。有人说中国的SaaS有特殊国情&#xff0c;大企业…

【bioinfo】酶切法片段化建库相比超声打断建库引入softclip使用FADE软件识别/去除

FADE软件参考文献 参考文献&#xff1a;片段化酶诱导的双链伪影的表征和缓解 - PMC (nih.gov) 文献提供的酶切产生的错误识别和去除软件FADE&#xff1a;软件git地址 文献补充材料图&#xff1a;由酶切产生的人工错误序列的碱基质量值偏高&#xff0c;相对其他softclip的质量…

适配Dell R750xs server Broadcom BCM57412 NetXtreme-E 10Gb SFP+ 网卡

摘要 The Issue is to handle Scaler v8.2-385 (baf7f3a) on Dell R750xs server, the 10G NIC card is Broadcom BCM57412 NetXtreme-E 10Gb SFP. Firmware is the latest, but driver is not. The symptom is that only one port or no port could be recognized. After patc…

基于MAX7800羽毛板语音控制ESP8266小车

1. 项目介绍 基于MAX7800羽毛板语音控制ESP8266小车 采用现成的KWS20关键词&#xff0c;[up, down, left, right, stop, go, yes, no, on, off, one, two, three, four, five, six, seven, eight, nine, zero]&#xff0c;进行语音关键字识别远程控制小车。 2. 项目设计思路 搭…

JSP——EL表达式

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

年度征文 | 回顾2022,展望2023 (清风与我)

个人简介&#xff1a; 名称内容个人主页清风与我学习方向主攻前端方向推荐学习vue&#xff0c;vue3&#xff0c;node.js&#xff0c;React&#xff0c;项目实战推荐学习用网站菜鸟教程&#xff0c;博客&#xff0c;哔哩哔哩 …学习用资源网vue&#xff0c;element&#xff0c;…

Apollo星火计划学习笔记——Apollo开放空间规划算法原理与实践

文章目录1. 开放空间规划算法总体介绍1.1 Task: OPEN_SPACE_ROI_DECIDER1.2 Task: OPEN_SPACE_TRAJECTORY_PROVIDER1.3 Task: OPEN_SPACE_TRAJECTORY_PARTITION1.4 Task: OPEN_SPACE_FALLBACK_DECIDER2. 基于混合A *的路径规划算法2.1 hybrid A*的简要思想2.2 RS曲线2.3 Apollo…

一文读懂方壳电池仓段差缺陷检测

摩根大通预计&#xff0c;2025年中国新能源汽车渗透率将达46.3%&#xff0c;彭博新能源财经最新发布的《新能源汽车市场长期展望》(EVO)报告显示&#xff0c;到2025年底&#xff0c;新能源汽车保有量将达到7700万辆&#xff0c;不难看出新能源行业依旧前景广阔。围绕“新能源”…

JDBC(Java Database connect)详解

一、相关概念 什么是JDBC JDBC&#xff08;Java Data Base Connectivity,java数据库连接&#xff09;是一种用于执行SQL语句的Java API&#xff0c;可以为多种关系数据库提供统一访问&#xff0c;它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准&#xff0c;据此可…

软件测试门槛低么?适合初学者么

随着软件工程活动的不断演化&#xff0c;软件测试工作已经成为了不可或缺的一部分&#xff0c;测试工作某种程度上是可以很大幅度提高软件的产品质量以及提升用户的使用满意度。因此&#xff0c;许多想要学习软件测试的朋友也许常常会有这样的困惑&#xff0c;软件测试门槛低吗…

JS数组对象——根据日期进行排序Date.parse(),按照时间进行升序或降序排序localeCompare()

JS数组对象——根据日期对象进行排序&#xff0c;按照时间进行升序或降序排序场景复现封装数组对象的排序方法根据日期和时间对象排序1、按照日期时间混合排序2、分别按照日期和时间进行排序场景复现 排序在项目中非常实用&#xff0c;出现频率极高&#xff0c;尤其是后台管理…

用javascript分类刷leetcode17.栈(图文视频讲解)

目录 Stack的特点&#xff1a;先进后出&#xff08;FILO&#xff09; 使用场景&#xff1a;十进制转2进制 函数调用堆栈 js里没有栈&#xff0c;但是可以用数组模拟 42/2 42%20 21/2 21%21 10/2 10%20 5/2 5%21 2/2 2%20 1/2 1%21 stack: [0,1,0,1,0,1] res: 1 0 1 …

VC#复习资料

一、选择题 2、“闪电”图标 3、using命名空间 命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式&#xff0c;using 关键字表明程序使用的是给定命名空间中的名称&#xff0c;使用 using 命名空间指令&#xff0c;这样在使用的时候就不用在前面加上命名空间名称…