一、数据填充:tf.pad()
为了方便网络的并行计算,需要将不同长度的数据扩张为相同长度,通常是在需要补充长度的数据开始或结束处填充足够数量的特定数值,这些特定数值一般代表了无效意义。这种操作成为填充(Padding)。
填充操作可以通过tf.pad(x,paddings)函数实现,参数paddings是包含了多个[leftPaddings,RightPaddings]的嵌套方案List。
tf.pad(
tensor,
paddings, //类似网页设计中的paddings,类型为int32
mode='CONSTANT',
// 一共有三种模式:
// mode = “CONSTANT” 默认使用常量【0】进行填充
// mode = "REFLECT" 镜像填充,
// mode = "SYMMETRIC" 对称填充
constant_values=0,
name=None
)
该方法能够给数据周围填0,填的参数是:需要填充的数据+填0的位置
填0的位置是一个数组形式,对应如下:[[上行,下行],[左列,右列]],具体例子如下:
较为常用的是上下左右各一行。
给图片进行padding的时候,通常数据的维度是[b,h,w,c],那么增加两行,两列的话,是在中间的h和w增加:
1、二维数据扩充
1.1 tf.pad(tensor=a, paddings=[[1, 0], [0, 1]])
- 第一个【[ ]】是在第一维数据上的扩充,即上下
- 第二个【[ ]】是在第二维数据上的扩充,即左右
import tensorflow as tf
a = tf.reshape(tf.range(9), [3, 3])
print("a = \n", a)
print("-" * 100)
# 第一个【[ ]】是在第一维数据上的扩充,即上下
# 第二个【[ ]】是在第二维数据上的扩充,即左右
b = tf.pad(a, [[1, 0], [0, 1]])
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[0 1 2]
[3 4 5]
[6 7 8]], shape=(3, 3), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[0 0 0 0]
[0 1 2 0]
[3 4 5 0]
[6 7 8 0]], shape=(4, 4), dtype=int32)
Process finished with exit code 0
1.2 tf.pad(tensor=a, paddings=[[2, 0], [0, 1]], constant_values=-1)
import tensorflow as tf
a = tf.reshape(tf.range(9), [3, 3])
print("a = \n", a)
print("-" * 100)
# 第一个【[ ]】是在第一维数据上的扩充,即上下
# 第二个【[ ]】是在第二维数据上的扩充,即左右
b = tf.pad(tensor=a, paddings=[[2, 0], [0, 1]], constant_values=-1)
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[0 1 2]
[3 4 5]
[6 7 8]], shape=(3, 3), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[-1 -1 -1 -1]
[-1 -1 -1 -1]
[ 0 1 2 -1]
[ 3 4 5 -1]
[ 6 7 8 -1]], shape=(5, 4), dtype=int32)
Process finished with exit code 0
2、三维数据扩充
import tensorflow as tf
a = tf.reshape(tf.range(1, 9), [2, 2, 2])
print("a = \n", a)
print("-" * 100)
# 第一个【[ ]】是在第一维维数据上的扩充,即前后
# 第二个【[ ]】是在第二维数据上的扩充,即上下
# 第三个【[ ]】是在第三维数据上的扩充,即左右
paddings = tf.constant([[0, 0], [0, 0], [1, 1]])
b = tf.pad(tensor=a, paddings=paddings)
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[[1 2]
[3 4]]
[[5 6]
[7 8]]], shape=(2, 2, 2), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[[0 1 2 0]
[0 3 4 0]]
[[0 5 6 0]
[0 7 8 0]]], shape=(2, 2, 4), dtype=int32)
Process finished with exit code 0
3、参数:mode
默认情况下,mode=“CONSTANT”
3.1 mode=“REFLECT”
对于【REFLECT】模式,·paddings = tf.constant([M, N])中的M、N不得大于tensor.dim_size(D)-1,如上,当N为2时,就会报错
import tensorflow as tf
a = tf.reshape(tf.range(4), [2, 2])
print("a = \n", a)
print("-" * 100)
b = tf.pad(tensor=a, paddings=[[1, 1], [1, 1]], mode="REFLECT")
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[0 1]
[2 3]], shape=(2, 2), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[3 2 3 2]
[1 0 1 0]
[3 2 3 2]
[1 0 1 0]], shape=(4, 4), dtype=int32)
Process finished with exit code 0
如果将 b = tf.pad(tensor=a, paddings=[[1, 1], [1, 1]], mode="REFLECT")
改为 b = tf.pad(tensor=a, paddings=[[1, 2], [1, 1]], mode="REFLECT")
就会报错。
3.2 mode=“SYMMETRIC”
对于【SYMMETRIC】模式,·paddings = tf.constant([M, N])中的M、N不得大于tensor.dim_size(D),如上,当N为3时,就会报错
import tensorflow as tf
a = tf.reshape(tf.range(4), [2, 2])
print("a = \n", a)
print("-" * 100)
b = tf.pad(tensor=a, paddings=[[2, 2], [2, 2]], mode="SYMMETRIC")
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[0 1]
[2 3]], shape=(2, 2), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[3 2 2 3 3 2]
[1 0 0 1 1 0]
[1 0 0 1 1 0]
[3 2 2 3 3 2]
[3 2 2 3 3 2]
[1 0 0 1 1 0]], shape=(6, 6), dtype=int32)
Process finished with exit code 0
如果将 b = tf.pad(tensor=a, paddings=[[2, 2], [2, 2]], mode="SYMMETRIC")
改为 b = tf.pad(tensor=a, paddings=[[2, 3], [2, 2]], mode="SYMMETRIC")
就会报错。
二、数据复制:tf.tile(input, multiples, name=None)
该方法可以复制数据,需要填的参数:数据,维度+对应的复制次数。
multiples: 数量变化:
- 1表示不变;
- 2表示数量变为2,数据类型为【Tensor, dtype = int32 or int64】
# multiples: 数量变化,1表示不变,2表示数量变为2,数据类型为【Tensor, dtype = int32 or int64】
tf.tile(
input,
multiples,
name=None
)
1、参数:multiples=[1, 2]
import tensorflow as tf
a = tf.reshape(tf.range(9), [3, 3])
print("a = \n", a)
print("-" * 100)
b = tf.tile(input=a, multiples=[1, 2])
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[0 1 2]
[3 4 5]
[6 7 8]], shape=(3, 3), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[0 1 2 0 1 2]
[3 4 5 3 4 5]
[6 7 8 6 7 8]], shape=(3, 6), dtype=int32)
Process finished with exit code 0
2、参数:multiples=[2, 1]
import tensorflow as tf
a = tf.reshape(tf.range(9), [3, 3])
print("a = \n", a)
print("-" * 100)
b = tf.tile(input=a, multiples=[2, 1])
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[0 1 2]
[3 4 5]
[6 7 8]], shape=(3, 3), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[0 1 2]
[3 4 5]
[6 7 8]
[0 1 2]
[3 4 5]
[6 7 8]], shape=(6, 3), dtype=int32)
Process finished with exit code 0
三、tf.tile()、tf.broadcast_to()区别
broadcast_to = expand_dims + tile
通常情况下,只要操作符合broadcast原则就可以,连broadcast_to这个操作都不需要用,就会自动扩展并复制进行操作。
1、tf.expand_dims() + tf.tile()
import tensorflow as tf
a = tf.constant([[1, 2, 3], [4, 5, 6]], tf.int32)
print("a = \n", a)
print("-" * 100)
aa = tf.expand_dims(a, axis=0)
print("aa = \n", aa)
print("-" * 50)
b = tf.tile(aa, [2, 1, 1])
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[1 2 3]
[4 5 6]], shape=(2, 3), dtype=int32)
----------------------------------------------------------------------------------------------------
aa =
tf.Tensor(
[[[1 2 3]
[4 5 6]]], shape=(1, 2, 3), dtype=int32)
--------------------------------------------------
b =
tf.Tensor(
[[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]], shape=(2, 2, 3), dtype=int32)
Process finished with exit code 0
2、tf.broadcast_to()【可以省略维度扩张】
import tensorflow as tf
a = tf.constant([[1, 2, 3], [4, 5, 6]], tf.int32)
print("a = \n", a)
print("-" * 100)
b = tf.broadcast_to(input=a, shape=[2, 2, 3])
print("b = \n", b)
打印结果:
a =
tf.Tensor(
[[1 2 3]
[4 5 6]], shape=(2, 3), dtype=int32)
----------------------------------------------------------------------------------------------------
b =
tf.Tensor(
[[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]], shape=(2, 2, 3), dtype=int32)
Process finished with exit code 0
参考资料:
TensorFlow高阶操作之填充与复制
TensorFlow数据填充复制
TensorFlow进阶(4.填充和复制)
深度学习(15)TensorFlow高阶操作四: 填充与复制
tensorflow(十五):填充与复制(pad、 tile、 broadcast_to)