簡體   English   中英

Tensorflow:如何將可變時間步長輸入提供給 RNN

[英]Tensorflow: how to feed a variable-time-step input to a RNN

我有一個簡單的 X_train 和 Y_train 數據:

x_train = [
  array([ 6,  1,  9, 10,  7,  7,  1,  9, 10,  3, 10,  1,  4]), 
  array([ 2,  8,  8,  1,  1,  4,  2,  5,  1,  2,  7,  2,  1,  1, 4,  5, 10, 4])
]
y_train = [23, 17]

Arrays 是 numpy arrays。 我現在正在嘗試使用tf.data.Dataset class 將這些加載為張量。 在我使用以下代碼成功完成類似的事情之前:

    dataset = data.Dataset.from_tensor_slices((x_train, y_train))

As this input is fed into a RNN, I have used the expand_dims method in the first RNN layer (the expand_dimension is passed as a function to overcome an apparent bug in tensorflow: see https://github.com/keras-team/keras /issues/5298#issuecomment-281914537 ):

def expand_dimension(x):
    from tensorflow import expand_dims
    return expand_dims(x, axis=-1)

model = models.Sequential(
    [
        layers.Lambda(expand_dimension,
                      input_shape=[None]),
        layers.LSTM(units=64, activation='tanh'),
        layers.Dense(units=1)
    ]
)

這雖然有效,但因為我有相同長度的 arrays。 在我發布的示例中,第一個數組有 13 個數字,第二個數組有 18 個。在這種情況下,上面的方法不起作用,推薦的方法似乎是使用tf.data.Dataset.from_generator 閱讀本文如何使用 Tensorflow 數據集管道進行可變長度輸入? ,接受的解決方案顯示類似於以下內容的內容(為簡單起見,我在這里不關心y_train ):

dataset = tf.data.Dataset.from_generator(lambda: x_train, 
                                         tf.as_dtype(x_train[0].dtype),
                                         tf.TensorShape([None, ]))

但是,自此答案以來,tensorflow 中的語法已更改,現在需要使用output_signature參數(請參閱https://www.tensorflow/Dataset#from_docs/python.org/api_gen

我嘗試了不同的方法,但我發現很難從 tensorflow 文檔中理解output_signature在我的情況下應該是什么。 任何幫助將非常感激。

簡短的回答是,您可以定義output_signature如下。

import tensorflow as tf
import numpy as np
x_train = [
  np.array([ 6,  1,  9, 10,  7,  7,  1,  9, 10,  3, 10,  1,  4]), 
  np.array([ 2,  8,  8,  1,  1,  4,  2,  5,  1,  2,  7,  2,  1,  1, 4,  5, 10, 4])
]
y_train = [23, 17]

dataset = tf.data.Dataset.from_generator(
    lambda: x_train, 
    output_signature=tf.TensorSpec(
        [None, ], 
        dtype=tf.as_dtype(x_train[0].dtype)
    )
)

我還將擴展和改進您在這里所做的一些事情,以改善您的管道。

同時使用輸入和標簽

dataset = tf.data.Dataset.from_generator(
    lambda: zip(x_train, y_train), 
    output_signature=(
        tf.TensorSpec([None, ], dtype=tf.as_dtype(x_train[0].dtype)),
        tf.TensorSpec([], dtype=tf.as_dtype(y_train.dtype))
    )
)

for x in dataset:
  print(x)

哪個會 output,

(<tf.Tensor: shape=(13,), dtype=int64, numpy=array([ 6,  1,  9, 10,  7,  7,  1,  9, 10,  3, 10,  1,  4])>, <tf.Tensor: shape=(), dtype=int64, numpy=23>)
(<tf.Tensor: shape=(18,), dtype=int64, numpy=
array([ 2,  8,  8,  1,  1,  4,  2,  5,  1,  2,  7,  2,  1,  1,  4,  5, 10,
        4])>, <tf.Tensor: shape=(), dtype=int64, numpy=17>)

警告:如果您嘗試tf.data.Dataset.batch()項目,這可能會稍微復雜一些。 然后你需要使用RaggedTensorSpec而不是TensorSpec 此外,我還沒有對將參差不齊的張量輸入 RNN 進行太多實驗。 但是我認為對於您提出的問題,這些都超出了 scope 的范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM