Моделирование с несколькими входами в TensorFlow с генератором

#python-3.x #tensorflow #generator #tf.keras #tensorflow2.x

#python-3.x #tensorflow #генератор #tf.keras #tensorflow2.x

Вопрос:

 import numpy as np
import tensorflow as tf

class ProbDistWRTChoices(tf.keras.layers.Layer):
    def __init__(self, maxChoice):
        super().__init__()
        self.maxChoice = maxChoice

    def call(self, inputs):
        utility, rowlengths = inputs
        utility = tf.reshape(utility, -1)
        utility = tf.RaggedTensor.from_row_lengths(values = utility, row_lengths = rowlengths)
        utility = utility.to_tensor(default_value = -1e9, shape = (None, self.maxChoice))
        prob = tf.nn.softmax(utility, axis=-1)
        return prob

    
class MNLogit(tf.keras.Model):

    def __init__(self, maxChoice):
        super(MNLogit, self).__init__()
        self.dense = tf.keras.layers.Dense(1, use_bias = False, kernel_initializer = 'glorot_uniform',activation=None)
        self.probabilityCalculator = ProbDistWRTChoices(maxChoice)

    def call(self, inputs):
        print(inputs)
        x, rowlengths = inputs
        print (x.shape, rowlengths.shape)
        x = self.dense(x)
        x = self.probabilityCalculator([x, rowlengths])
        print (x.shape)
        print(x.numpy())
        print( "          =========          ")
        return x


model = MNLogit(maxChoice=100)
model.compile(
    optimizer = tf.keras.optimizers.Adam(), 
    loss = tf.keras.losses.SparseCategoricalCrossentropy(), 
    metrics = [
        tf.keras.metrics.SparseTopKCategoricalAccuracy(k = 1, name = 'Accuracy'),
        tf.keras.metrics.SparseTopKCategoricalAccuracy(k = 5, name = 'Top5_Accuracy'),
        tf.keras.metrics.SparseTopKCategoricalAccuracy(k = 10, name = 'Top10_Accuracy')
    ]
)


    row_lengths = np.array([100, 100, 100,  88, 100,  68,  99, 100, 100, 100, 100, 100, 100,
                       100, 100, 100, 100, 100, 100,  46, 100, 100, 100, 100, 100, 100, 87, 100, 100,  74, 100, 100])
    targets = np.array([ 4,  0, 99,  0,  8, 53, 36, 13, 31,  7,  3, 91, 13, 75, 66, 86, 55, 20,  1,  6, 75, 42, 97, 
                    9, 37, 16, 87, 14,  1, 26, 46, 57])
    X = np.random.random((3062, 10))
    values = [([X, row_lengths], targets) for i in range(100)]
    
    def generator(values):
        """
        Yields the next training batch.
        """
        
        iterator = iter(values)
        while True:
            yield next(iterator)
    
    train_gen = generator(values)
    model.fit(train_gen, epochs=10, steps_per_epoch = 1)
    
    **O/P because of the print statement:**
     
    
    > (<tf.Tensor: shape=(3062, 10), dtype=float32, numpy=
    > array([[0.45570728, 0.2092263 , 0.68047154, ..., 0.7563979 , 0.5050498
    > ,
    >         0.679467  ],
    >        [0.78198177, 0.39459062, 0.1891338 , ..., 0.34017387, 0.93216115,
    >         0.05743273],
    >        [0.37135497, 0.88671786, 0.08154485, ..., 0.4763579 , 0.49207243,
    >         0.01604719],
    >        ...,
    >        [0.99842083, 0.41491947, 0.17116761, ..., 0.27906555, 0.10698277,
    >         0.52499497],
    >        [0.06340311, 0.14407901, 0.8654476 , ..., 0.74813706, 0.18045615,
    >         0.6346456 ],
    >        [0.54209155, 0.22341223, 0.5253111 , ..., 0.86075026, 0.79696625,
    >         0.80810267]], dtype=float32)>, <tf.Tensor: shape=(32,), dtype=int64, numpy= array([100, 100, 100,  88, 100,  68,  99, 100,
    > 100, 100, 100, 100, 100,
    >        100, 100, 100, 100, 100, 100,  46, 100, 100, 100, 100, 100, 100,
    >         87, 100, 100,  74, 100, 100])>) (3062, 10) (32,) (32, 100) [[0.00836133 0.00883811 0.01003097 ... 0.01875334 0.00826117
    > 0.00648314]  [0.01327305 0.01223391 0.00698607 ... 0.00874015 0.01100503 0.01377677]  [0.01167065 0.00867095 0.00506141 ... 0.00904635 0.01058154 0.00611446]  ...  [0.01133993 0.01008244 0.01226319 ... 0.         0.         0.        ]  [0.01300668 0.01112028 0.00956304 ... 0.02183897 0.00758292 0.0092134 ]  [0.00588106 0.00859331 0.01139334 ... 0.01909281 0.00397551
    > 0.01512818]]
    >           =========           Epoch 1/10 (<tf.Tensor 'IteratorGetNext:0' shape=(None, None) dtype=float32>, <tf.Tensor
    > 'ExpandDims:0' shape=(None, 1) dtype=int64>) (None, None) (None, 1)
    > --------------------------------------------------------------------------- ValueError
  

Я не понимаю, почему во 2-й раз модель не получает никаких входных данных от генератора (предполагается, что это генератор, который в основном выдает одни и те же данные).

Ввод намеренно случайный. Есть ли какие-либо проблемы с моим генератором? Я знаю, что это не очень хорошая практика, но логически я думал, что это должно сработать для создания примера цели. Но я застрял.

Я намеренно добавил некоторые операторы печати для понимания и объяснения.

Ответ №1:

Я думаю, что у вас ошибка в этой строке:

 X = np.random.random((3062, 10))
  

Вероятно, должно быть:

 X = np.random.random((32, 10))
  

Комментарии:

1. Нет, 2-й ввод — это длины строк для неровного тензора. Если бы все объекты имели одинаковое количество вариантов, связанных с ним, это было бы 3200 X 10. Не более 100 строк для каждой выходной строки. Вывод этой строки ** utility = utility.to_tensor(default_value = -1e9, shape = (None, self.maxChoice)) ** будет размером 32 X 100. В инструкции print вы увидите эту строку «(3062, 10) (32,) (32, 100)» последнее — это форма выходного сигнала.