TensorFlow高阶操作之填充与复制
2020-02-04 本文已影响0人
酵母小木
【碎语】在电影《柳烈的音乐专辑》里面,我得到的启示是“遇见你的时候,要照顾好自己;独自一人的时候,更要照顾好自己。要一直保持优秀”。里面有一句台词,“面包、爱情、飞机,它们有一个共同点”,“起步很慢”。你的回答是“我既不要面包,也不要飞机”。傻瓜,想起你,我就会督促自己努力。
1. 【tf.pad()】函数
tf.pad(
tensor,
paddings, //类似网页设计中的paddings,类型为int32
mode='CONSTANT',
// 一共有三种模式:
// mode = “CONSTANT” 默认使用常量【0】进行填充
// mode = "REFLECT" 镜像填充,
// mode = "SYMMETRIC" 对称填充
constant_values=0,
name=None
)
//二维数据扩充
In [3]: a = tf.reshape(tf.range(9), [3, 3])
In [4]: a
Out[4]: <tf.Tensor: id=9, shape=(3, 3), dtype=int32, numpy=
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])>
//第一个【[ ]】是在第一维数据上的扩充,即上下
//第二个【[ ]】是在第二维数据上的扩充,即左右
In [5]: tf.pad(a, [[1, 0], [0, 1]])
Out[5]: <tf.Tensor: id=11, shape=(4, 4), dtype=int32, numpy=
array([[0, 0, 0, 0],
[0, 1, 2, 0],
[3, 4, 5, 0],
[6, 7, 8, 0]])>
//三维数据扩充
In [7]: a = tf.reshape(tf.range(8), [2, 2, 2])
In [8]: a
Out[8]: <tf.Tensor: id=17, shape=(2, 2, 2), dtype=int32, numpy=
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])>
//第一个【[ ]】是在第一维维数据上的扩充,即前后
//第二个【[ ]】是在第二维数据上的扩充,即上下
//第三个【[ ]】是在第三维数据上的扩充,即左右
In [21]: paddings = tf.constant([[0, 0], [0, 0], [1, 1]])
In [22]: tf.pad(a, paddings, "CONSTANT")
Out[22]: <tf.Tensor: id=37, shape=(2, 2, 4), dtype=int32, numpy=
array([[[0, 0, 1, 0],
[0, 2, 3, 0]],
[[0, 4, 5, 0],
[0, 6, 7, 0]]])>
【注】关于【REFLECT】【SYMMETRIC】两种模式的注意事项
In [23]: a = tf.reshape(tf.range(4), [2, 2])
In [24]: a
Out[24]: <tf.Tensor: id=43, shape=(2, 2), dtype=int32, numpy=
array([[0, 1],
[2, 3]])>
In [25]: tf.pad(a, [[1, 1], [1, 1]], "REFLECT")
Out[25]: <tf.Tensor: id=45, shape=(4, 4), dtype=int32, numpy=
array([[3, 2, 3, 2],
[1, 0, 1, 0],
[3, 2, 3, 2],
[1, 0, 1, 0]])>
In [26]: tf.pad(a, [[1, 2], [1, 1]], "REFLECT")
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
对于【REFLECT】模式,·paddings = tf.constant([M, N])
中的M
、N
不得大于tensor.dim_size(D)-1
,如上,当N为2时,就会报错
In [30]: tf.pad(a, [[0, 2], [0, 0]], "SYMMETRIC")
Out[30]: <tf.Tensor: id=53, shape=(4, 2), dtype=int32, numpy=
array([[0, 1],
[2, 3],
[2, 3],
[0, 1]])>
In [31]: tf.pad(a, [[0, 3], [0, 0]], "SYMMETRIC")
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
对于【SYMMETRIC】模式,·paddings = tf.constant([M, N])
中的M
、N
不得大于tensor.dim_size(D)
,如上,当N为3时,就会报错
2. 【tf.tile()】函数
tf.tile(
input,
multiples,
name=None
)
//multiples: 数量变化,1表示不变,2表示数量变为2,数据类型为【Tensor, dtype = int32 or int64】
//演示代码
In [32]: a = tf.reshape(tf.range(9), [3, 3])
Out[33]: <tf.Tensor: id=60, shape=(3, 3), dtype=int32, numpy=
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])>
In [34]: tf.tile(a, [1, 2])
Out[34]: <tf.Tensor: id=62, shape=(3, 6), dtype=int32, numpy=
array([[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8]])>
In [35]: tf.tile(a, [2, 1])
Out[35]: <tf.Tensor: id=64, shape=(6, 3), dtype=int32, numpy=
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])>
In [36]: a = tf.constant([[1, 2, 3], [4, 5, 6]], tf.int32)
In [37]: b = tf.constant([1, 2], tf.int32)
In [38]: tf.tile(a, b)
Out[38]:<tf.Tensor: id=67, shape=(2, 6), dtype=int32, numpy=
array([[1, 2, 3, 1, 2, 3],
[4, 5, 6, 4, 5, 6]])>
【注】关于【tf.broadcast_to()】【tf.tile()】两者之间的差异
In [40]: a = tf.constant([[1, 2, 3], [4, 5, 6]], tf.int32)
Out[41]: <tf.Tensor: id=68, shape=(2, 3), dtype=int32, numpy=
array([[1, 2, 3],
[4, 5, 6]])>
In [42]: aa = tf.expand_dims(a, axis=0)
Out[43]: <tf.Tensor: id=70, shape=(1, 2, 3), dtype=int32, numpy=
array([[[1, 2, 3],
[4, 5, 6]]])>
In [44]: tf.tile(aa, [2, 1, 1])
Out[44]: <tf.Tensor: id=72, shape=(2, 2, 3), dtype=int32, numpy=
array([[[1, 2, 3],
[4, 5, 6]],
[[1, 2, 3],
[4, 5, 6]]])>
//可以省略维度扩张
In [48]: tf.broadcast_to(a, [2, 2, 3])
Out[48]: <tf.Tensor: id=77, shape=(2, 2, 3), dtype=int32, numpy=
array([[[1, 2, 3],
[4, 5, 6]],
[[1, 2, 3],
[4, 5, 6]]])>
In [46]: tf.broadcast_to(aa, [2, 2, 3])
Out[46]: <tf.Tensor: id=75, shape=(2, 2, 3), dtype=int32, numpy=
array([[[1, 2, 3],
[4, 5, 6]],
[[1, 2, 3],
[4, 5, 6]]])>
由于【tf.broadcast_to()】并不在内存上进行复制,所以效率和性能上要高于【tf.tile()】