TensorFlow2.0填充张量函数:tf.pad用法详解
1 填充张量函数:
tf.pad(
tensor,
paddings,
mode='CONSTANT',
name=None,
constant_values=0
)
1.1参数:
- tensor:待填充的张量.
- paddings:int32类型、形状 (n, 2) 的张量。n是tensor的秩(通过tf.rank(tensor)可以得到秩)。具体用法在后面讲。
- mode:用于填充的值,取决于mode参数。
- 默认取值为 “CONSTANT”,填充为参数constant_values的值。不受自身维度的长度影响。
- “REFLECT” 反射,在tensor自身取值填充,以tensor起始或末尾值进行镜像映射到的值进行填充;最大填充长度必须小于该维度的元素长度。
- “SYMMETRIC” 对称,tensor自身取值填充,在该维度起始值前或末尾值后为对称轴,取值填充,最大填充长度为该维度元素长度。
- 不区分大小写
- name:操作的名称(可选).
- constant_values:默认值为0 。在 “CONSTANT” 模式下,要使用的标量填充值。必须与 tensor 具有相同数据类型。
1.2 返回值:扩展填充后的张量。
2 paddings 参数的用法和作用:
学习的时候,自己对paddings的用法和作用总是一知半解,所以分别对一阶、二阶、三阶张量进行了操作,全部操作一遍就懂了它的用法和作用。
2.1 对一阶张量进行填充扩展:
tf.rank(input) # 返回输入的tensor对象的秩
一阶张量的行列中,最小的是行数为1,因此秩为1,故paddings的形状为(1, 2),即一行两列。
2.1.1 在一阶张量前面增加2列:
import tensorflow as tf
one = tf.constant([1, 2, 3, 4, 5])
# 在一阶张量one前面增加2列,并填充为constant_values的默认值0
one_new = tf.pad(one, [[2, 0]])
print("一阶张量的秩:", int(tf.rank(one)))
print("填充扩展前:\n", one)
print("填充扩展后:\n", one_new)
---------打印结果:-----------
一阶张量的秩: 1
填充扩展前:
tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
填充扩展后:
tf.Tensor([0 0 1 2 3 4 5], shape=(7,), dtype=int32)
2.1.2 在一阶张量末尾增加3列:
import tensorflow as tf
one = tf.constant([1, 2, 3, 4, 5])
# 在一阶张量one末尾增加3列,并填充为constant_values的默认值0
one_new = tf.pad(one, [[0, 3]])
print("填充扩展前:\n", one)
print("填充扩展后:\n", one_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
填充扩展后:
tf.Tensor([1 2 3 4 5 0 0 0], shape=(8,), dtype=int32)
2.1.3 在一阶张量前面增加2列、末尾增加1列:
import tensorflow as tf
one = tf.constant([1, 2, 3, 4, 5])
# 在one前面增加2列、末尾增加1列,并填充为constant_values的默认值0
one_new = tf.pad(one, [[2, 1]])
print("填充扩展前:\n", one)
print("填充扩展后:\n", one_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
填充扩展后:
tf.Tensor([0 0 1 2 3 4 5 0], shape=(8,), dtype=int32)
2.1.4 小结:
一阶张量通过tf.pad()函数只能在张量前后扩展列数,返回的张量仍然是一阶张量。
2.2 对二阶张量进行填充扩展:
二阶张量的秩为2,因此paddings的形状为(2, 2),即两行两列。
import numpy as np
import tensorflow as tf
two = tf.constant(np.arange(1, 13).reshape(3, 4))
print("二阶张量的秩:", int(tf.rank(two)))
---------打印结果:-----------
二阶张量的秩: 2
2.2.1 对二阶张量的行进行扩展
import numpy as np
import tensorflow as tf
two = tf.constant(np.arange(1, 13).reshape(3, 4))
# 在张量上面增加2行,下面增加1列,并填充为constant_values的默认值0
two_new = tf.pad(two, [[2, 1], [0, 0]])
print("填充扩展前:\n", two)
print("填充扩展后:\n", two_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor(
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]], shape=(3, 4), dtype=int64)
填充扩展后:
tf.Tensor(
[[ 0 0 0 0]
[ 0 0 0 0]
[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]
[ 0 0 0 0]], shape=(6, 4), dtype=int64)
2.2.2 对二阶张量的列进行扩展
import numpy as np
import tensorflow as tf
two = tf.constant(np.arange(1, 13).reshape(3, 4))
# 在张量前面增加1列,后面增加1列,并填充为constant_values的默认值0
two_new = tf.pad(two, [[0, 0], [1, 1]])
print("填充扩展前:\n", two)
print("填充扩展后:\n", two_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor(
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]], shape=(3, 4), dtype=int64)
填充扩展后:
tf.Tensor(
[[ 0 1 2 3 4 0]
[ 0 5 6 7 8 0]
[ 0 9 10 11 12 0]], shape=(3, 6), dtype=int64)
2.2.3 同时扩展二阶张量的行和列
import numpy as np
import tensorflow as tf
two = tf.constant(np.arange(1, 13).reshape(3, 4))
# 在张量前面增加1列,后面增加1列,并填充为constant_values的默认值0
two_new = tf.pad(two, [[1, 1], [1, 1]])
print("填充扩展前:\n", two)
print("填充扩展后:\n", two_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor(
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]], shape=(3, 4), dtype=int64)
填充扩展后:
tf.Tensor(
[[ 0 0 0 0 0 0]
[ 0 1 2 3 4 0]
[ 0 5 6 7 8 0]
[ 0 9 10 11 12 0]
[ 0 0 0 0 0 0]], shape=(5, 6), dtype=int64)
2.2.4 小结:
二阶张量通过tf.pad()函数,可以在张量的上下扩展行数,也可以在前后扩展列数,返回的张量仍然是二阶张量。
2.3 对三阶张量进行填充扩展:
import numpy as np
import tensorflow as tf
three = tf.constant(np.arange(1, 25).reshape(2, 3, 4))
print("三阶张量的秩:", int(tf.rank(three)))
---------打印结果:-----------
三阶张量的秩: 3
三阶张量的秩为3,因此paddings的形状为(3, 2)。
2.3.1 对三阶张量的最外层维度进行填充扩展,暂称为块
张量three的形状为(2, 3, 4)。最外层维度暂称为块,则每一块的形状为3行4列。当我们扩展的块形状也是3行4列。
import numpy as np
import tensorflow as tf
three = tf.constant(np.arange(1, 25).reshape(2, 3, 4))
# 在张量上面增加1块,下面增加1块,并填充为constant_values的默认值0
three_new = tf.pad(three, [[1, 1], [0, 0], [0, 0]])
print("填充扩展前:\n", three)
print("填充扩展后:\n", three_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor(
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]], shape=(2, 3, 4), dtype=int64)
填充扩展后:
tf.Tensor(
[[[ 0 0 0 0]
[ 0 0 0 0]
[ 0 0 0 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]]
[[ 0 0 0 0]
[ 0 0 0 0]
[ 0 0 0 0]]], shape=(4, 3, 4), dtype=int64)
2.3.2 对三阶张量的行进行填充扩展
import numpy as np
import tensorflow as tf
three = tf.constant(np.arange(1, 25).reshape(2, 3, 4))
# 在张量上面增加1行,下面增加1列,并填充为constant_values的默认值0
three_new = tf.pad(three, [[0, 0], [1, 1], [0, 0]])
print("填充扩展前:\n", three)
print("填充扩展后:\n", three_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor(
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]], shape=(2, 3, 4), dtype=int64)
填充扩展后:
tf.Tensor(
[[[ 0 0 0 0]
[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]
[ 0 0 0 0]]
[[ 0 0 0 0]
[13 14 15 16]
[17 18 19 20]
[21 22 23 24]
[ 0 0 0 0]]], shape=(2, 5, 4), dtype=int64)
2.3.3 对三阶张量的行进行填充扩展
import numpy as np
import tensorflow as tf
three = tf.constant(np.arange(1, 25).reshape(2, 3, 4))
# 在张量前面增加1列,后面增加1列,并填充为constant_values的默认值0
three_new = tf.pad(three, [[0, 0], [0, 0], [1, 1]])
print("填充扩展前:\n", three)
print("填充扩展后:\n", three_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor(
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]], shape=(2, 3, 4), dtype=int64)
填充扩展后:
tf.Tensor(
[[[ 0 1 2 3 4 0]
[ 0 5 6 7 8 0]
[ 0 9 10 11 12 0]]
[[ 0 13 14 15 16 0]
[ 0 17 18 19 20 0]
[ 0 21 22 23 24 0]]], shape=(2, 3, 6), dtype=int64)
2.3.4 小结:
三阶张量的形状由(块, 行, 列)三部分组成,paddings的3行依次也分别对应着三阶张量的块、行、列:
- paddings第一行指定对三阶张量的块进行操作;
- paddings第二行指定对三阶张量的行进行操作;
- paddings第三行指定对三阶张量的列进行操作。
3 mode参数的用法:
取值为 “CONSTANT”、“REFLECT” 或 “SYMMETRIC”(不区分大小写)。
为了简化篇幅,以下3个演示,均以一阶张量为例:
3.1 mode= “CONSTANT”
mode默认取值为 “CONSTANT”,填充为参数constant_values的值。不受自身维度的长度影响。
import tensorflow as tf
a = tf.constant([1, 2, 3, 4, 5])
# 在张量a的前面增加2列,
a_new = tf.pad(a, [[2, 1]], mode='constant', constant_values=9)
print("填充扩展前:\n", a)
print("填充扩展后:\n", a_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
填充扩展后:
tf.Tensor([9 9 1 2 3 4 5 9], shape=(8,), dtype=int32)
3.2 mode=“REFLECT”
“REFLECT” 映射填充。在tensor自身取值填充,以tensor起始或末尾值进行镜像映射到的值进行填充;最大填充长度必须小于该维度的元素长度。
如下面的代码,a的长度最大为5,则 paddings的元素取值最大为4。
import tensorflow as tf
a = tf.constant([1, 2, 3, 4, 5])
# 在a的前面增加4列,后面增加1列,
a_new = tf.pad(a, [[4, 1]], mode='reflect', constant_values=9)
print("填充扩展前:\n", a)
print("填充扩展后:\n", a_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
填充扩展后:
tf.Tensor([5 4 3 2 1 2 3 4 5 4], shape=(10,), dtype=int32)
具体映射效果参考图示:
3.3 mode=“SYMMETRIC”
“SYMMETRIC” 对称,tensor自身取值填充,在该维度起始值前或末尾值后为对称轴,取值填充,最大填充长度为该维度元素长度。
如:a长度为5,paddings元素值最大可以为5。
import tensorflow as tf
a = tf.constant([1, 2, 3, 4, 5])
a_new = tf.pad(a, [[5, 5]], mode='symmetric', constant_values=9)
print("填充扩展前:\n", a)
print("填充扩展后:\n", a_new)
---------打印结果:-----------
填充扩展前:
tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
填充扩展后:
tf.Tensor([5 4 3 2 1 1 2 3 4 5 5 4 3 2 1], shape=(15,), dtype=int32)
具体对称效果参考图示:
3.4 小结:
从运行结果我们可以看出,参数constant_values只有当mode= "CONSTANT"的时候生效。