В приведенном ниже примере может быть то, что вы ищете, или, по крайней мере, направить вас в правильном направлении. Это немного экспериментально с моей стороны, но я считаю, что оно имеет правильную структуру. Он был создан в Google Colab с Tensorflow 2.0. Первый раздел предназначен для обеспечения воспроизводимости обработки, а остальная часть иллюстрирует общую идею использования «TimeDistributed Layer» наряду с маскированием и заполнением. Кстати, я считаю, что эта идея похожа на то, что предлагал @El Sheikh (первый комментарий выше). Примечание. Я использовал здесь SimpleRNN, но я считаю, что эта идея применима и к LSTM. Я надеюсь, что это поможет вам двигаться в правильном направлении.
%tensorflow_version 2.x
import numpy as np
import tensorflow as tf
import random as rn
# The below is necessary for starting Numpy generated random numbers
# in a well-defined initial state.
np.random.seed(42)
# The below is necessary for starting core Python generated random numbers
# in a well-defined state.
rn.seed(12345)
# Force TensorFlow to use single thread.
# Multiple threads are a potential source of non-reproducible results.
# For further details, see: https://stackoverflow.com/questions/42022950/
session_conf = tf.compat.v1.ConfigProto(intra_op_parallelism_threads=1,
inter_op_parallelism_threads=1)
# The below tf.set_random_seed() will make random number generation
# in the TensorFlow backend have a well-defined initial state.
# For further details, see:
# https://www.tensorflow.org/api_docs/python/tf/set_random_seed
tf.compat.v1.set_random_seed(1234)
sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(), config=session_conf)
tf.compat.v1.keras.backend.set_session(sess)
# The code above here is provided to make the below reproducible each time you
# run.
#
# Main code follows:
from tensorflow import keras
from tensorflow.keras import layers
# Input structure
# Sentence1 ..... SentenceM
# Word11 Word21 Word31 ..... Wordn11 Word11 .... WordnM1
# Word12 Word22 Word32 Wordn12 Word12 WordnM2
# Word13 Word23 Word33 Wordn13 Word13 WordnM3
# example parameters
word_vec_dimension = 3 # dimension of the embedding
sentence_representation = 4 # dimensionality of sentence vector
#
# This represents a single test document.
# Each row is a sentence and the words are represented by 3 dimensionsal
# integer vectors.
#
raw_inputs = [ [ [1, 5, 7], [2, 6, 7] ],
[ [9, 6, 3], [1, 8, 2], [4, 5, 9], [8, 2, 1] ],
[ [1, 6, 2], [4, 2, 9] ],
[ [2, 6, 2], [8, 2, 9] ],
[ [3, 6, 2], [2, 2, 9], [1, 6, 2] ],
]
print(raw_inputs)
# Create the model
#
# Allow for variable number of words per sentence and variable number of
# sentences:
# Input shape(num_samples, [SentenceCount], [WordCount], word_vector_dim)
#
# Note: Using None for Sentence Count, and None for Word count to allow
# for variable sequences length in both these dimensions.
#
inputs = keras.Input(shape=(None, None, word_vec_dimension), name='inputlayer')
x = tf.keras.layers.Masking(mask_value=0.0)(inputs) # Force RNNs to ignore timesteps with zero vectors.
x = tf.keras.layers.TimeDistributed(layers.SimpleRNN(sentence_representation,
use_bias=False,
activation=None),
name='TD1')(x)
outputs = x
# more layers here if needed:
model = tf.keras.Model(inputs=inputs, outputs=outputs, name='Sentiment')
model.compile(optimizer='rmsprop', loss='mse', accuracy='mse' )
model.summary()
# Set up fitting calls
import numpy as np
# document 1
x_train = raw_inputs # use the dummy document for testing
# Set zeros in locations where there is no data to indicate mask to RNN's so
# they ignore that timestep.
padded_inputs = tf.keras.preprocessing.sequence.pad_sequences(x_train,
padding='post')
print(x_train)
# Insert a dummy dimension 1 to represent the sample dimension.
padded_inputs = np.expand_dims(padded_inputs,axis=0)/1.0 # Make float type
print(padded_inputs)
print(padded_inputs.shape)
y_train = np.array([[ 1.0, 2.0, 3.0, 4.0 ]])
print(y_train.shape)
# Train model:
model.fit(padded_inputs,y_train,epochs=1)
print('get_weights:')
print(model.get_layer(name='TD1').get_weights())
print('get_predictions:')
print(model.predict(padded_inputs))