TensorFlow2.0(四):填充与复制

  • 2019 年 10 月 7 日
  • 筆記

 

 

1 pad()

 

tf.pad函数主要是用来对tensor的大小进行扩展,包括水平、垂直、深度(通道)等,方法定义如下:

pad(tensor, paddings, mode=”CONSTANT”, name=None, constant_values=0)

输入参数:

  • tensor:输入的tensor

  • paddings:设置填充的大小

  • mode:填充方式,默认是CONSTANT,还有REFLECT和SYMMETRIC

  • name:名称

  • constant_values:CONSTANT填充方式的填充值,默认是0

参数paddings必须是形状为(n, 2)的一个list,这里的n是tensor的秩,也就是维度大小。例如当tensor为一个shape为(12,)的tensor时,paddings必须是形如[[x,y]]的一个list,x表示在第一维度前填充值的个数,y表示在第一维度后填充值的个数:

In [2]:
import tensorflow as tf  

In [37]:
a = tf.range(1,13)  

In [38]:
a  

Out[38]:
<tf.Tensor: id=87, shape=(12,), dtype=int32, numpy=array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])>

In [39]:
tf.pad(a, [[3,0]])  # 3表示在第一维度前填充3个0,0表示不填充  

Out[39]:
<tf.Tensor: id=90, shape=(15,), dtype=int32, numpy=array([ 0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])>

 

当tensor是二维时,paddings必须是shape为(2,2)的list:

In [40]:
a = tf.reshape(a, [3, 4])  

In [41]:
a  

Out[41]:
<tf.Tensor: id=93, shape=(3, 4), dtype=int32, numpy=  array([[ 1,  2,  3,  4],         [ 5,  6,  7,  8],         [ 9, 10, 11, 12]])>

In [42]:
tf.pad(a, [[1,1],[3,0]], constant_values=3)  # 第一维度前后各填充一行,第二维度前填充两行,后不填充,填充值为3  

Out[42]:
<tf.Tensor: id=97, shape=(5, 7), dtype=int32, numpy=  array([[ 3,  3,  3,  3,  3,  3,  3],         [ 3,  3,  3,  1,  2,  3,  4],         [ 3,  3,  3,  5,  6,  7,  8],         [ 3,  3,  3,  9, 10, 11, 12],         [ 3,  3,  3,  3,  3,  3,  3]])>

 

对于3维tensor,paddings是一个shape为(3,2)的list:

In [43]:
a = tf.reshape(a, [2, 2, 3])  

In [44]:
a  

Out[44]:
<tf.Tensor: id=100, shape=(2, 2, 3), dtype=int32, numpy=  array([[[ 1,  2,  3],          [ 4,  5,  6]],           [[ 7,  8,  9],          [10, 11, 12]]])>

In [45]:
tf.pad(a, [[1, 0],[1,1],[1,0]])  # 第一维度前填充1块数据,后不填充,第二维度前后各填充1行,第三维度前填充1列,后不填充  

Out[45]:
<tf.Tensor: id=103, shape=(3, 4, 4), dtype=int32, numpy=  array([[[ 0,  0,  0,  0],          [ 0,  0,  0,  0],          [ 0,  0,  0,  0],          [ 0,  0,  0,  0]],           [[ 0,  0,  0,  0],          [ 0,  1,  2,  3],          [ 0,  4,  5,  6],          [ 0,  0,  0,  0]],           [[ 0,  0,  0,  0],          [ 0,  7,  8,  9],          [ 0, 10, 11, 12],          [ 0,  0,  0,  0]]])>

In [46]:
a = tf.range(1,13)  

In [47]:
a = tf.reshape(a,[3,4])  

In [48]:
a  

Out[48]:
<tf.Tensor: id=110, shape=(3, 4), dtype=int32, numpy=  array([[ 1,  2,  3,  4],         [ 5,  6,  7,  8],         [ 9, 10, 11, 12]])>

 

当指定填充模式mode为’REFLECT’时,指的是以各维度边缘为对称轴进行填充(不包括边缘数据也就是对称轴本身),且填充的规模不能大于该维度原有规模-1:

In [52]:
tf.pad(a, [[2,1],[3,1]],mode='REFLECT')  # 对第二个维度填充时,如果大于3就回产生异常,因为3已经可以把第二维度所有数据复制一遍  

Out[52]:
<tf.Tensor: id=120, shape=(6, 8), dtype=int32, numpy=  array([[12, 11, 10,  9, 10, 11, 12, 11],         [ 8,  7,  6,  5,  6,  7,  8,  7],         [ 4,  3,  2,  1,  2,  3,  4,  3],         [ 8,  7,  6,  5,  6,  7,  8,  7],         [12, 11, 10,  9, 10, 11, 12, 11],         [ 8,  7,  6,  5,  6,  7,  8,  7]])>

 

SYMMETRIC填充模式与REFLECT填充模式一样,都是以边缘为对称轴进行赋值填充,不过SYMMETRIC模式会对对称轴进行赋值,所以指定的规模最大可以为原规模:

In [53]:
tf.pad(a, [[2,1],[4,1]],mode='SYMMETRIC')  # 这时候对第二个维度填充规模可以为4,但是超过4旧货产生异常  

Out[53]:
<tf.Tensor: id=123, shape=(6, 9), dtype=int32, numpy=  array([[ 8,  7,  6,  5,  5,  6,  7,  8,  8],         [ 4,  3,  2,  1,  1,  2,  3,  4,  4],         [ 4,  3,  2,  1,  1,  2,  3,  4,  4],         [ 8,  7,  6,  5,  5,  6,  7,  8,  8],         [12, 11, 10,  9,  9, 10, 11, 12, 12],         [12, 11, 10,  9,  9, 10, 11, 12, 12]])>

 

2 tile()

tile()方法对指定维度进行复制,定义如下:

tile(input, multiples, name=None):

  • input:需要复制的tensor
  • multiples: 各维度需要复制的次数,0表示去除数据,1表示不复制,2表示复制一次

参数multiples是一个长度与tensor的秩相等的list,例如当tensor的shape为(12,)时,multiples的shape也必须为只有一个元素的list,例如multiples=[2],表示对第一维度复制1次:

In [55]:
a  

Out[55]:
<tf.Tensor: id=128, shape=(12,), dtype=int32, numpy=array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])>

In [56]:
tf.tile(a,[2])  

Out[56]:
<tf.Tensor: id=131, shape=(24,), dtype=int32, numpy=  array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,  1,  2,  3,  4,  5,          6,  7,  8,  9, 10, 11, 12])>

 

当tensor的shape为(3,4)时,multiples是一个包含两个元素的list:

In [57]:
a = tf.reshape(a, [3,4])  

In [61]:
tf.tile(a, [2,3])  # 第一维度复制1次,第二维度复制2次  

Out[61]:
<tf.Tensor: id=145, shape=(6, 12), dtype=int32, numpy=  array([[ 1,  2,  3,  4,  1,  2,  3,  4,  1,  2,  3,  4],         [ 5,  6,  7,  8,  5,  6,  7,  8,  5,  6,  7,  8],         [ 9, 10, 11, 12,  9, 10, 11, 12,  9, 10, 11, 12],         [ 1,  2,  3,  4,  1,  2,  3,  4,  1,  2,  3,  4],         [ 5,  6,  7,  8,  5,  6,  7,  8,  5,  6,  7,  8],         [ 9, 10, 11, 12,  9, 10, 11, 12,  9, 10, 11, 12]])>

 

当tensor的shape为(2,2,3时,multiples是一个包含3个元素list:

In [62]:
a = tf.reshape(a, [2,2,3])  

In [64]:
tf.tile(a, [2,1,2])  

Out[64]:
<tf.Tensor: id=153, shape=(4, 2, 6), dtype=int32, numpy=  array([[[ 1,  2,  3,  1,  2,  3],          [ 4,  5,  6,  4,  5,  6]],           [[ 7,  8,  9,  7,  8,  9],          [10, 11, 12, 10, 11, 12]],           [[ 1,  2,  3,  1,  2,  3],          [ 4,  5,  6,  4,  5,  6]],           [[ 7,  8,  9,  7,  8,  9],          [10, 11, 12, 10, 11, 12]]])>