【问题标题】:Tensorflow fit ValueError: Shape mismatch: The shape of labels (received (16640,)) should equal the shape of logits except for the last dimensionTensorflow fit ValueError:形状不匹配:标签的形状(收到(16640,))应该等于除最后一个维度之外的logits的形状
【发布时间】:2021-12-07 23:49:12
【问题描述】:

我从一个标记化的文本创建一个 tf 数据集,然后转换为序列,然后是 numpy 数组

tokenizer = Tokenizer()
tokenizer.fit_on_texts(bible_text)#Builds the word index
sequences = tokenizer.texts_to_sequences(bible_text)

##-->[[5, 1, 914, 32, 1352, 1, 214, 2, 1, 111],
## [2, 1, 111, 31, 252, 2091, 2, 1874, 2, 547, 31, 38, 1, 196, 3, 1, 899, 2, 1, 298, 3, 32, 878, 38, 1, 196, 3, 1, 266],
## [2, 32, 33, 79, 54, 16, 369, 2, 54, 31, 369], [2, 32, 215, 1, 369, 6, 17, 31, 156, 2, 32, 955, 1, 369, 34, 1, 547], ...]

sequences=pad_sequences(sequences, padding='post')

##-->[[   5    1  914   32 1352    1  214    2    1  111    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    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
##     0    0    0    0    0    0    0    0    0    0    0    0    0    0
##     0    0    0    0    0    0]
##...]

word_index=tokenizer.word_index 

##for k,v in sorted(word_index.items(), key=operator.itemgetter(1))[:10]:
##   print (k,v)

##--> the 1
##and 2
##of 3
##to 4
##in 5
##that 6
##shall 7
##he 8
##lord 9
##his 10
##
##[...]

vocab_size = len(tokenizer.word_index) + 1

构建输入和目标序列

input_sequences, target_sequences = sequences[:,:-1], sequences[:,1:]
seq_length=input_sequences.shape[1] ##-->89
num_verses=input_sequences.shape[0]

input_sequences=np.array(input_sequences)
target_sequences=np.array(target_sequences)

和数据集

dataset= tf.data.Dataset.from_tensor_slices((input_sequences, target_sequences))

这个数据集设置似乎没有什么特别的问题。我在这里定义模型

EPOCHS=2
BATCH_SIZE=256
VAL_FRAC=0.2  
LSTM_UNITS=1024
DENSE_UNITS=vocab_size
EMBEDDING_DIM=256
BUFFER_SIZE=10000

len_val=int(num_verses*VAL_FRAC)

#build validation dataset
validation_dataset = dataset.take(len_val)
validation_dataset = (
    validation_dataset
    .shuffle(BUFFER_SIZE)
    .padded_batch(BATCH_SIZE, drop_remainder=True)
    .prefetch(tf.data.experimental.AUTOTUNE))

#build training dataset
train_dataset = dataset.skip(len_val)
train_dataset = (
    train_dataset
    .shuffle(BUFFER_SIZE)
    .padded_batch(BATCH_SIZE, drop_remainder=True)
    .prefetch(tf.data.experimental.AUTOTUNE))

#build the model: 2 stacked LSTM
print('Build model...')
model = tf.keras.Sequential()
model.add(Embedding(vocab_size, EMBEDDING_DIM))
model.add(LSTM(LSTM_UNITS, return_sequences=True, input_shape=(seq_length, vocab_size)))
model.add(Dropout(0.2))
model.add(LSTM(512, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(DENSE_UNITS))
model.add(Activation('softmax'))

loss=tf.losses.SparseCategoricalCrossentropy(from_logits=False)

model.compile(optimizer='adam',
              loss=loss,
              metrics=[
                  tf.keras.metrics.SparseCategoricalAccuracy()]
              )

model.summary()

我收到以下错误 - 它属于 fit 方法

ValueError: Shape mismatch: The shape of labels (received (16640,)) should equal the shape of logits except for the last dimension (received (256, 3067)).

任何想法,可能有什么问题?

编辑

如果我将损失更改为 categorical_crossentropy

   /usr/local/lib/python3.6/dist-packages/keras/backend.py:4839 categorical_crossentropy
        target.shape.assert_is_compatible_with(output.shape)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_shape.py:1161 assert_is_compatible_with
        raise ValueError("Shapes %s and %s are incompatible" % (self, other))

    ValueError: Shapes (256, 65) and (256, 3067) are incompatible

编辑

我使用了 AloneTogether 指示的模型,这解决了拟合步骤。但是我在对新数据进行预测时遇到了问题

preds = model.predict(x, verbose=0)[0][0]

因为预测的总和不完全为 1

>>> preds
array([1.6435336e-04, 1.4827750e-04, 1.4495676e-04, ..., 8.9204557e-05,
       8.9799374e-05, 8.7148059e-05], dtype=float32)
>>> sum(preds)
1.0000000457002898

这似乎就是为什么我不能从这个“分布”中取样

def sample(a, temperature=1.0):
    #helper function to sample an index from a probability array
    a = np.log(a) / temperature
    a = np.exp(a) / np.sum(np.exp(a))
    return np.argmax(np.random.multinomial(1, a, 1))

任何线索为什么会出现这种行为,有什么解决方法吗?

【问题讨论】:

  • 您的示例中的next_words 是什么?
  • @AloneTogether 谢谢,我做了一些改动,添加了一个嵌入层并改变了我构建序列的方式,数据集不再是空的,但我陷入了形状问题
  • 只是出于好奇,您的用例到底是什么?

标签: python tensorflow keras deep-learning tensorflow-datasets


【解决方案1】:

您的预处理步骤看起来不错。假设您想生成一个序列作为输出(您的目标是序列),请尝试如下调整您的模型:

model = tf.keras.Sequential()
model.add(tf.keras.layers.Embedding(vocab_size, EMBEDDING_DIM))
model.add(tf.keras.layers.LSTM(LSTM_UNITS, return_sequences=True))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.LSTM(512, return_sequences=True))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(DENSE_UNITS, activation='softmax')))

请注意,您的最后一个 LSTM 层现在再次返回序列。时间分布层只是将具有softmax激活函数的全连接层应用于每个时间步i,以计算词汇表中每个单词的概率。每个全连接层使用的节点数等于词汇表的大小,以便为每个单词提供公平的预测机会。

要根据某些输入从分布中采样,您可以执行以下操作:

temperature = 1.0
sample = input_sequences[0] # "You are unsure whether or not to trust him but very thankful that you wore a turtle neck"
sample = tf.expand_dims(sample, axis=0)
predictions = model.predict(sample) / temperature
index_word=tokenizer.index_word 

predictions = tf.squeeze(predictions, axis=0)
sampled_indices = tf.random.categorical(predictions, num_samples=1)
word_list = list(np.vectorize(index_word.get)(sampled_indices))

print(sampled_indices)
print(word_list)

'''
tf.Tensor(
[[ 7]
 [45]
 [52]
 [41]
 [29]
 [21]
 [21]
 [35]
 [27]
 [ 6]
 [38]
 [44]
 [25]
 [39]
 [13]
 [19]
 [26]], shape=(17, 1), dtype=int64)
[array(['about'], dtype='<U7'), array(['thorns'], dtype='<U7'), array(['would'], dtype='<U7'), array(['is'], dtype='<U7'), array(['but'], dtype='<U7'), array(['by'], dtype='<U7'), array(['by'], dtype='<U7'), array(['all'], dtype='<U7'), array(['to'], dtype='<U7'), array(['she'], dtype='<U7'), array(['wander'], dtype='<U7'), array(['have'], dtype='<U7'), array(['whether'], dtype='<U7'), array(['lost'], dtype='<U7'), array(['are'], dtype='<U7'), array(['your'], dtype='<U7'), array(['or'], dtype='<U7')]
'''

当然,我训练的模型会吐出乱码,因为它是在 10 个样本上训练了 2 个 epoch,但希望你明白这一点。我使用了一个采样器函数 (tf.random.categorical) 从温度加权 softmax 函数在每个时间步产生的多项分布中进行采样。例如,让w 是基于词汇表v 在时间步长 1 的概率分布。采样器函数采用w 并绘制一个整数值,表示在这个多项分布中具有高概率的单词。我希望你能明白。

【讨论】:

  • 谢谢,实际上这个模型会通过拟合阶段,但是我在做预测时遇到了另一个问题
  • &gt;&gt;&gt; preds array([1.6435336e-04, 1.4827750e-04, 1.4495676e-04, ..., 8.9204557e-05, 8.9799374e-05, 8.7148059e-05], dtype=float32) &gt;&gt;&gt; sum(preds) 1.0000000457002898 如您所见,预测的总和不完全为 1,我认为这阻止了我从这个“分布”中抽样
  • 我更新了帖子,你的提议很棒,不过还有一个问题
  • 更新答案。
猜你喜欢
  • 2021-04-24
  • 2020-02-12
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
相关资源
最近更新 更多