当前位置: 首页 > 工具软件 > Dim > 使用案例 >

深度学习 - 7.TF x Keras expand_dim 扩充维度

董胡非
2023-12-01

应用场景:

面对有时候需要对数据维度进行扩充,例如低维数据向转高维度或者不规则张量 ragged Tensor的填充,这时候就需要expand_dims登场、同时还有 tf.tile 和 preprocessing.sequence.pad_sequences 帮忙。

一.expand_dims

tf.expand_dims 可以扩充数组维度,参数包括:

    array:需要扩充的数组,这里 tensor,np.array 或者 python.list 都可以

    axis:需要扩充的维度,这里假设 n 维数据,则只能扩充至 n+1 维,否则会报错

index = np.array([
    [71, 1331, 4231, 0, 0, 0],
    [73, 8, 3215, 55, 927, 0],
    [83, 91, 1, 645, 1253, 927],
])

# expand_dim 扩充维度 3 x 6 -> 3 x 6 x 1
expand = tf.expand_dims(index, axis=-1)
print(expand)

原始数据维度 3x6,扩充后变为 3x6x1 ,如果设置axis=0,则扩充为 1x3x6,同理 axis=1,扩充至 3x1x6,axis=2 作用与 axis=-1一致,都是在最后追加一维。

tf.Tensor(
[[[  71]    
  [1331]
  [4231]
  [   0]
  [   0]
  [   0]]

 [[  73]
  [   8]
  [3215]
  [  55]
  [ 927]
  [   0]]

 [[  83]
  [  91]
  [   1]
  [ 645]
  [1253]
  [ 927]]], shape=(3, 6, 1), dtype=int64)
 

二.tf.tile

前面的expand_dims是在当前维度增加新的维度,tf.tile不会增加新的维度,只是扩充当前 shape,参数包括:

    array:需要扩充的数组,这里 tensor,np.array 或者 python.list 都可以

    list:各维度元素扩充倍数,这里需要与原始 shape 维度一致,原始 m x n,list参数 k x j => tile后维度 (m*k) x (n*j)

# tile 扩展维度
# Easy 2x2 3x4 => 6x8
index = [
    [1,2],
    [3,4],
]
print(tf.tile(index,[3,4]))

2x2 3x4 对应位置相乘得到 6x8,实际上就是将对应数据在相应维度上复制对应次数,[1,2] 和 [3,4]先在axis=0维度复制三次变成 6x2 ,然后再在axis=1维度上复制4次,由6x2变为6x8

tf.Tensor(
[[1 2 1 2 1 2 1 2]
 [3 4 3 4 3 4 3 4]
 [1 2 1 2 1 2 1 2]
 [3 4 3 4 3 4 3 4]
 [1 2 1 2 1 2 1 2]
 [3 4 3 4 3 4 3 4]], shape=(6, 8), dtype=int32)

三.preprocessing.sequence.pad_sequences

在处理序列数据时,各个样本常常具有不同长度,就是常说的不规则向量 ragged Tensor,这里需要给对应向量填充至维度统一,才能进行后续训练等,就像one-hot一样,包含如下参数:

    array:需要扩充的数组,这里 tensor,np.array 或者 python.list 都可以

    padding:填充方式,post是在后面补0,pre则是在前面补0,可以根据自己需求选择

# Hard 3x6 => 3x6x1 => 3x6x10
raw_inputs = [
    [711, 632, 71],
    [73, 8, 3215, 55, 927],
    [83, 91, 1, 645, 1253, 927],
]

padded_inputs = tf.keras.preprocessing.sequence.pad_sequences(
    raw_inputs, padding="post"
)

由于深度学习模型的输入数据必须为单一张量(batch_size, 6, vocab_size),短于最长条目的样本需要用占位符值进行填充(或者,也可以在填充短样本前截断长样本)。这里长度分别为3,5,6,所以以6为基准进行填充。

[[ 711  632   71    0    0    0]
 [  73    8 3215   55  927    0]
 [  83   91    1  645 1253  927]]

结合前两个方法继续扩充该向量,先追加一维:

print(tf.expand_dims(padded_inputs, axis=-1)
tf.Tensor(
[[[ 711]
  [ 632]
  [  71]
  [   0]
  [   0]
  [   0]]

 [[  73]
  [   8]
  [3215]
  [  55]
  [ 927]
  [   0]]

 [[  83]
  [  91]
  [   1]
  [ 645]
  [1253]
  [ 927]]], shape=(3, 6, 1), dtype=int32)

再把最后一维增加10倍:

print(tf.tile(tf.expand_dims(padded_inputs, axis=-1), [1, 1, 10]))

刚才是2维所以后面扩充的list是2维,这里数据是三维,所以对应list也是三维,当某一维度数字为1时,代表不进行扩充。


tf.Tensor(
[[[ 711  711  711  711  711  711  711  711  711  711]
  [ 632  632  632  632  632  632  632  632  632  632]
  [  71   71   71   71   71   71   71   71   71   71]
  [   0    0    0    0    0    0    0    0    0    0]
  [   0    0    0    0    0    0    0    0    0    0]
  [   0    0    0    0    0    0    0    0    0    0]]

 [[  73   73   73   73   73   73   73   73   73   73]
  [   8    8    8    8    8    8    8    8    8    8]
  [3215 3215 3215 3215 3215 3215 3215 3215 3215 3215]
  [  55   55   55   55   55   55   55   55   55   55]
  [ 927  927  927  927  927  927  927  927  927  927]
  [   0    0    0    0    0    0    0    0    0    0]]

 [[  83   83   83   83   83   83   83   83   83   83]
  [  91   91   91   91   91   91   91   91   91   91]
  [   1    1    1    1    1    1    1    1    1    1]
  [ 645  645  645  645  645  645  645  645  645  645]
  [1253 1253 1253 1253 1253 1253 1253 1253 1253 1253]
  [ 927  927  927  927  927  927  927  927  927  927]]], shape=(3, 6, 10), dtype=int32)

更多推荐算法相关深度学习:深度学习导读专栏 

 类似资料: