张量简介#
在 TensorFlow.org 上查看 | 在 Google Colab 运行 | 在 GitHub 上查看源代码 | 下载笔记本 |
import tensorflow as tf
import numpy as np
2024-10-25 09:52:27.908653: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:485] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
2024-10-25 09:52:27.927423: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:8454] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
2024-10-25 09:52:27.933160: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1452] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2024-10-25 09:52:27.947730: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2024-10-25 09:52:28.982740: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
张量是具有统一类型(称为 dtype
)的多维数组。您可以在 tf.dtypes.DType
中查看所有支持的 dtypes
。
如果您熟悉 NumPy{:.external},就会知道张量与 np.arrays
有一定的相似性。
就像 Python 数值和字符串一样,所有张量都是不可变的:永远无法更新张量的内容,只能创建新的张量。
基础知识#
首先,创建一些基本张量。
下面是一个“标量”(或称“0 秩”张量)。标量包含单个值,但没有“轴”。
# This will be an int32 tensor by default; see "dtypes" below.
rank_0_tensor = tf.constant(4)
print(rank_0_tensor)
tf.Tensor(4, shape=(), dtype=int32)
2024-10-25 09:52:30.699248: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 1040 MB memory: -> device: 0, name: NVIDIA GeForce RTX 3090, pci bus id: 0000:03:00.0, compute capability: 8.6
2024-10-25 09:52:30.699954: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 9488 MB memory: -> device: 1, name: NVIDIA GeForce RTX 2080 Ti, pci bus id: 0000:81:00.0, compute capability: 7.5
“向量”(或称“1 秩”张量)就像一个值列表。向量有 1 个轴:
# Let's make this a float tensor.
rank_1_tensor = tf.constant([2.0, 3.0, 4.0])
print(rank_1_tensor)
tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)
“矩阵”(或称“2 秩”张量)有 2 个轴:
# If you want to be specific, you can set the dtype (see below) at creation time
rank_2_tensor = tf.constant([[1, 2],
[3, 4],
[5, 6]], dtype=tf.float16)
print(rank_2_tensor)
tf.Tensor(
[[1. 2.]
[3. 4.]
[5. 6.]], shape=(3, 2), dtype=float16)
一个标量,形状:[] |
向量,形状:[3] |
矩阵,形状:[3, 2] |
---|---|---|
张量的轴可能更多,下面是一个包含 3 个轴的张量:
# There can be an arbitrary number of
# axes (sometimes called "dimensions")
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]],])
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)
对于包含 2 个以上的轴的张量,您可以通过多种方式加以呈现。
3 轴张量,形状:[3, 2, 5] |
||
---|---|---|
通过使用 np.array
或 tensor.numpy
方法,您可以将张量转换为 NumPy 数组:
np.array(rank_2_tensor)
array([[1., 2.],
[3., 4.],
[5., 6.]], dtype=float16)
rank_2_tensor.numpy()
array([[1., 2.],
[3., 4.],
[5., 6.]], dtype=float16)
张量通常包含浮点型和整型数据,但是还有许多其他数据类型,包括:
复杂的数值
字符串
tf.Tensor
基类要求张量是“矩形”,也就是说,每个轴上的每一个元素大小相同。但是,有可以处理不同形状的特殊类型张量:
不规则张量(请参阅下文中的 RaggedTensor)
稀疏张量(请参阅下文中的 SparseTensor)
您可以对张量执行基本数学运算,包括加法、逐元素乘法和矩阵乘法。
a = tf.constant([[1, 2],
[3, 4]])
b = tf.constant([[1, 1],
[1, 1]]) # Could have also said `tf.ones([2,2], dtype=tf.int32)`
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") # element-wise addition
print(a * b, "\n") # element-wise multiplication
print(a @ b, "\n") # matrix multiplication
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)
各种运算都可以使用张量。
c = tf.constant([[4.0, 5.0], [10.0, 1.0]])
# Find the largest value
print(tf.reduce_max(c))
# Find the index of the largest value
print(tf.math.argmax(c))
# Compute the softmax
print(tf.nn.softmax(c))
tf.Tensor(10.0, shape=(), dtype=float32)
tf.Tensor([1 0], shape=(2,), dtype=int64)
tf.Tensor(
[[2.6894143e-01 7.3105854e-01]
[9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)
注:通常,在 TensorFlow 函数需要 Tensor
作为输入的任何地方,该函数也将接受可使用 tf.convert_to_tensor
转换为 Tensor
的任何内容。请参见下面的示例。
tf.convert_to_tensor([1,2,3])
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([1, 2, 3], dtype=int32)>
tf.reduce_max([1,2,3])
<tf.Tensor: shape=(), dtype=int32, numpy=3>
tf.reduce_max(np.array([1,2,3]))
<tf.Tensor: shape=(), dtype=int64, numpy=3>
形状简介#
张量有形状。下面是几个相关术语:
形状:张量的每个轴的长度(元素数量)。
秩:张量轴数。标量的秩为 0,向量的秩为 1,矩阵的秩为 2。
轴或维度:张量的一个特殊维度。
大小:张量的总项数,即形状矢量元素的乘积
注:虽然您可能会看到“二维张量”之类的表述,但 2 秩张量通常并不是用来描述二维空间。
张量和 tf.TensorShape
对象提供了方便的属性来访问:
rank_4_tensor = tf.zeros([3, 2, 4, 5])
4 秩张量,形状:[3, 2, 4, 5] |
|
---|---|
print("Type of every element:", rank_4_tensor.dtype)
print("Number of axes:", 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("Elements along the last axis of tensor:", rank_4_tensor.shape[-1])
print("Total number of elements (3*2*4*5): ", tf.size(rank_4_tensor).numpy())
Type of every element: <dtype: 'float32'>
Number of axes: 4
Shape of tensor: (3, 2, 4, 5)
Elements along axis 0 of tensor: 3
Elements along the last axis of tensor: 5
Total number of elements (3*2*4*5): 120
但请注意,Tensor.ndim
和 Tensor.shape
特性不返回 Tensor
对象。如果您需要 Tensor
,请使用 tf.rank
或 tf.shape
函数。这种差异不易察觉,但在构建计算图时(稍后)可能非常重要。
tf.rank(rank_4_tensor)
<tf.Tensor: shape=(), dtype=int32, numpy=4>
tf.shape(rank_4_tensor)
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([3, 2, 4, 5], dtype=int32)>
虽然通常用索引来指代轴,但是您始终要记住每个轴的含义。轴一般按照从全局到局部的顺序进行排序:首先是批次轴,随后是空间维度,最后是每个位置的特征。这样,在内存中,特征向量就会位于连续的区域。
典型的轴顺序 |
---|
索引编制#
单轴索引编制#
TensorFlow 遵循标准 Python 索引编制规则(类似于在 Python 中为列表或字符串编制索引{:.external})以及 NumPy 索引编制的基本规则。
索引从
0
开始负索引表示按倒序编制索引
冒号
:
用于切片:start:stop:step
rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
print(rank_1_tensor.numpy())
[ 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())
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]
多轴索引编制#
更高秩的张量通过传递多个索引来编制索引。
对于高秩张量的每个单独的轴,遵循与单轴情形完全相同的规则。
print(rank_2_tensor.numpy())
[[1. 2.]
[3. 4.]
[5. 6.]]
为每个索引传递一个整数,结果是一个标量。
# Pull out a single value from a 2-rank tensor
print(rank_2_tensor[1, 1].numpy())
4.0
您可以使用整数与切片的任意组合编制索引:
# Get row and column tensors
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 轴张量的索引编制示例:
print(rank_3_tensor[:, :, 4])
tf.Tensor(
[[ 4 9]
[14 19]
[24 29]], shape=(3, 2), dtype=int32)
选择批次中每个示例的所有位置的最后一个特征 | |
---|---|
请参阅张量切片指南,了解如何应用索引编制以操作张量中的各个元素。
操作形状#
改变张量的形状很有用。
# Shape returns a `TensorShape` object that shows the size along each axis
x = tf.constant([[1], [2], [3]])
print(x.shape)
(3, 1)
# You can convert this object into a Python list, too
print(x.shape.as_list())
[3, 1]
通过重构可以改变张量的形状。tf.reshape
运算的速度很快,资源消耗很低,因为不需要复制底层数据。
# You can reshape a tensor to a new shape.
# Note that you're passing in a list
reshaped = tf.reshape(x, [1, 3])
print(x.shape)
print(reshaped.shape)
(3, 1)
(1, 3)
数据在内存中的布局保持不变,同时使用请求的形状创建一个指向同一数据的新张量。TensorFlow 采用 C 样式的“行优先”内存访问顺序,即最右侧的索引值递增对应于内存中的单步位移。
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)
如果您展平张量,则可以看到它在内存中的排列顺序。
# A `-1` passed in the `shape` argument says "Whatever fits".
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
唯一合理的用途是用于合并或拆分相邻轴(或添加/移除 1
)。
对于 3x2x5 张量,重构为 (3x2)x5 或 3x(2x5) 都合理,因为切片不会混淆:
print(tf.reshape(rank_3_tensor, [3*2, 5]), "\n")
print(tf.reshape(rank_3_tensor, [3, -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=(6, 5), dtype=int32)
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, 10), dtype=int32)
一些正确的重构示例。 | ||
---|---|---|
重构可以处理总元素个数相同的任何新形状,但是如果不遵从轴的顺序,则不会发挥任何作用。
利用 tf.reshape
无法实现轴的交换,要交换轴,您需要使用 tf.transpose
。
# Bad examples: don't do this
# You can't reorder axes with reshape.
print(tf.reshape(rank_3_tensor, [2, 3, 5]), "\n")
# This is a mess
print(tf.reshape(rank_3_tensor, [5, 6]), "\n")
# This doesn't work at all
try:
tf.reshape(rank_3_tensor, [7, -1])
except Exception as e:
print(f"{type(e).__name__}: {e}")
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=(2, 3, 5), dtype=int32)
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=(5, 6), dtype=int32)
InvalidArgumentError: {{function_node __wrapped__Reshape_device_/job:localhost/replica:0/task:0/device:GPU:0}} Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7 [Op:Reshape]
2024-10-25 09:52:31.779728: I tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: INVALID_ARGUMENT: Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7
一些错误的重构示例。 | ||
---|---|---|
您可能会遇到非完全指定的形状。要么是形状包含 None
(轴长度未知),要么是整个形状为 None
(张量的秩未知)。
除 tf.RaggedTensor 外,此类形状只会在 TensorFlow 的符号化计算图构建 API 环境中出现:
DTypes
详解#
使用 Tensor.dtype
属性可以检查 tf.Tensor
的数据类型。
从 Python 对象创建 tf.Tensor
时,您可以选择指定数据类型。
如果不指定,TensorFlow 会选择一个可以表示您的数据的数据类型。TensorFlow 将 Python 整数转换为 tf.int32
,将 Python 浮点数转换为 tf.float32
。另外,当转换为数组时,TensorFlow 会采用与 NumPy 相同的规则。
数据类型可以相互转换。
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)
# Now, cast to an uint8 and lose the decimal precision
the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)
print(the_u8_tensor)
tf.Tensor([2 3 4], shape=(3,), dtype=uint8)
广播#
广播是从 NumPy 中的等效功能{:.external}借用的一个概念。简而言之,在一定条件下,对一组张量执行组合运算时,为了适应大张量,会对小张量进行“扩展”。
最简单和最常见的例子是尝试将张量与标量相乘或相加。在这种情况下会对标量进行广播,使其变成与其他参数相同的形状。
x = tf.constant([1, 2, 3])
y = tf.constant(2)
z = tf.constant([2, 2, 2])
# All of these are the same computation
print(tf.multiply(x, 2))
print(x * y)
print(x * z)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
同样,可以扩展长度为 1 的轴,使其匹配其他参数。在同一个计算中可以同时扩展两个参数。
在本例中,一个 3x1 的矩阵与一个 1x4 进行逐元素乘法运算,从而产生一个 3x4 的矩阵。注意前导 1 是可选的:y 的形状是 [4]
。
# These are the same computations
x = tf.reshape(x,[3,1])
y = tf.range(1, 5)
print(x, "\n")
print(y, "\n")
print(tf.multiply(x, y))
tf.Tensor(
[[1]
[2]
[3]], shape=(3, 1), dtype=int32)
tf.Tensor([1 2 3 4], shape=(4,), dtype=int32)
tf.Tensor(
[[ 1 2 3 4]
[ 2 4 6 8]
[ 3 6 9 12]], shape=(3, 4), dtype=int32)
广播相加:[3, 1] 乘以 [1, 4] 的结果是 [3,4] |
---|
下面是不使用广播的同一运算:
x_stretch = tf.constant([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]])
y_stretch = tf.constant([[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]])
print(x_stretch * y_stretch) # Again, operator overloading
tf.Tensor(
[[ 1 2 3 4]
[ 2 4 6 8]
[ 3 6 9 12]], shape=(3, 4), dtype=int32)
在大多数情况下,广播的时间和空间效率更高,因为广播运算不会在内存中具体化扩展的张量。
使用 tf.broadcast_to
可以了解广播的运算方式。
print(tf.broadcast_to(tf.constant([1, 2, 3]), [3, 3]))
tf.Tensor(
[[1 2 3]
[1 2 3]
[1 2 3]], shape=(3, 3), dtype=int32)
与数学运算不同,broadcast_to
并不会节省内存。在这个示例中,您将具体化张量。
这可能会变得更复杂。Jake VanderPlas 的 Python 数据科学手册一书中的这一节{:.external}介绍了更多广播技巧(同样使用 NumPy)。
tf.convert_to_tensor#
大部分运算(如 tf.matmul
和 tf.reshape
)会使用 tf.Tensor
类的参数。不过,在上面的示例中,您会发现形状类似于张量的 Python 对象也可以接受。
大部分(但并非全部)运算会在非张量参数上调用 convert_to_tensor
。我们提供了一个转换注册表,大多数对象类(如 NumPy 的 ndarray
、TensorShape
、Python 列表和 tf.Variable
)都可以自动转换。
请参阅 tf.register_tensor_conversion_function
以了解详情。如果您有自己的类型,则可能希望自动转换为张量。
不规则张量#
如果张量的某个轴上的元素个数可变,则称为“不规则”张量。对于不规则数据,请使用 tf.ragged.RaggedTensor
。
例如,下面的示例无法用规则张量表示:
“tf.RaggedTensor”,形状:[4, None] |
---|
ragged_list = [
[0, 1, 2, 3],
[4, 5],
[6, 7, 8],
[9]]
try:
tensor = tf.constant(ragged_list)
except Exception as e:
print(f"{type(e).__name__}: {e}")
ValueError: Can't convert non-rectangular Python sequence to Tensor.
应使用 tf.ragged.constant
来创建 tf.RaggedTensor
:
ragged_tensor = tf.ragged.constant(ragged_list)
print(ragged_tensor)
<tf.RaggedTensor [[0, 1, 2, 3], [4, 5], [6, 7, 8], [9]]>
tf.RaggedTensor
的形状将包含一些具有未知长度的轴:
print(ragged_tensor.shape)
(4, None)
字符串张量#
tf.string
是一种 dtype
,也就是说,在张量中,您可以用字符串(可变长度字节数组)来表示数据。
字符串是原子类型,无法像 Python 字符串一样编制索引。字符串的长度并不是张量的一个轴。有关操作字符串的函数,请参阅 tf.strings
。
下面是一个标量字符串张量:
# Tensors can be strings, too here is a scalar string.
scalar_string_tensor = tf.constant("Gray wolf")
print(scalar_string_tensor)
tf.Tensor(b'Gray wolf', shape=(), dtype=string)
下面是一个字符串向量:
字符串向量,形状:[3,] |
---|
# If you have three string tensors of different lengths, this is OK.
tensor_of_strings = tf.constant(["Gray wolf",
"Quick brown fox",
"Lazy dog"])
# Note that the shape is (3,). The string length is not included.
print(tensor_of_strings)
tf.Tensor([b'Gray wolf' b'Quick brown fox' b'Lazy dog'], shape=(3,), dtype=string)
在上面的打印输出中,b
前缀表示 tf.string
dtype 不是 Unicode 字符串,而是字节字符串。有关在 TensorFlow 中如何使用 Unicode 文本的详细信息,请参阅 Unicode 教程。
如果传递 Unicode 字符,则会使用 utf-8 编码。
tf.constant("🥳👍")
<tf.Tensor: shape=(), dtype=string, numpy=b'\xf0\x9f\xa5\xb3\xf0\x9f\x91\x8d'>
在 tf.strings
中可以找到用于操作字符串的一些基本函数,包括 tf.strings.split
。
# You can use split to split a string into a set of tensors
print(tf.strings.split(scalar_string_tensor, sep=" "))
tf.Tensor([b'Gray' b'wolf'], shape=(2,), dtype=string)
# ...but it turns into a `RaggedTensor` if you split up a tensor of strings,
# as each string might be split into a different number of parts.
print(tf.strings.split(tensor_of_strings))
<tf.RaggedTensor [[b'Gray', b'wolf'], [b'Quick', b'brown', b'fox'], [b'Lazy', b'dog']]>
三个字符串分割,形状:[3, None] |
---|
And tf.strings.to_number
:
text = tf.constant("1 10 100")
print(tf.strings.to_number(tf.strings.split(text, " ")))
tf.Tensor([ 1. 10. 100.], shape=(3,), dtype=float32)
虽然不能使用 tf.cast
将字符串张量转换为数值,但是可以先将其转换为字节,然后转换为数值。
byte_strings = tf.strings.bytes_split(tf.constant("Duck"))
byte_ints = tf.io.decode_raw(tf.constant("Duck"), tf.uint8)
print("Byte strings:", byte_strings)
print("Bytes:", byte_ints)
Byte strings: tf.Tensor([b'D' b'u' b'c' b'k'], shape=(4,), dtype=string)
Bytes: tf.Tensor([ 68 117 99 107], shape=(4,), dtype=uint8)
# Or split it up as unicode and then decode it
unicode_bytes = tf.constant("アヒル 🦆")
unicode_char_bytes = tf.strings.unicode_split(unicode_bytes, "UTF-8")
unicode_values = tf.strings.unicode_decode(unicode_bytes, "UTF-8")
print("\nUnicode bytes:", unicode_bytes)
print("\nUnicode chars:", unicode_char_bytes)
print("\nUnicode values:", unicode_values)
Unicode bytes: tf.Tensor(b'\xe3\x82\xa2\xe3\x83\x92\xe3\x83\xab \xf0\x9f\xa6\x86', shape=(), dtype=string)
Unicode chars: tf.Tensor([b'\xe3\x82\xa2' b'\xe3\x83\x92' b'\xe3\x83\xab' b' ' b'\xf0\x9f\xa6\x86'], shape=(5,), dtype=string)
Unicode values: tf.Tensor([ 12450 12498 12523 32 129414], shape=(5,), dtype=int32)
tf.string
dtype 可用于 TensorFlow 中的所有原始字节数据。tf.io
模块包含在数据与字节类型之间进行相互转换的函数,包括解码图像和解析 csv 的函数。
稀疏张量#
在某些情况下,数据很稀疏,例如在一个非常宽的嵌入向量空间中。为了高效存储稀疏数据,TensorFlow 支持 tf.sparse.SparseTensor
和相关运算。
“tf.SparseTensor”,形状:[3, 4] |
---|
# Sparse tensors store values by index in a memory-efficient manner
sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],
values=[1, 2],
dense_shape=[3, 4])
print(sparse_tensor, "\n")
# You can convert sparse tensors to dense
print(tf.sparse.to_dense(sparse_tensor))
SparseTensor(indices=tf.Tensor(
[[0 0]
[1 2]], shape=(2, 2), dtype=int64), values=tf.Tensor([1 2], shape=(2,), dtype=int32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
tf.Tensor(
[[1 0 0 0]
[0 0 2 0]
[0 0 0 0]], shape=(3, 4), dtype=int32)