【发布时间】:2022-01-22 00:32:49
【问题描述】:
我正在尝试实现一个自定义层,它将标记化的单词序列预处理成一个矩阵,其中预定义的元素数量等于词汇表的大小。本质上,我正在尝试实现一个“词袋”层。这是我能想到的最接近的:
def get_encoder(vocab_size=args.vocab_size):
encoder = TextVectorization(max_tokens=vocab_size)
encoder.adapt(train_dataset.map(lambda text, label: text))
return encoder
class BagOfWords(tf.keras.layers.Layer):
def __init__(self, vocab_size=args.small_vocab_size, batch_size=args.batch_size):
super(BagOfWords, self).__init__()
self.vocab_size = vocab_size
self.batch_size = batch_size
def build(self, input_shape):
super().build(input_shape)
def call(self, inputs):
if inputs.shape[-1] == None:
return tf.constant(np.zeros([self.batch_size, self.vocab_size])) # 32 is the batch size
outputs = tf.zeros([self.batch_size, self.vocab_size])
if inputs.shape[-1] != None:
for i in range(inputs.shape[0]):
for ii in range(inputs.shape[-1]):
ouput_idx = inputs[i][ii]
outputs[i][ouput_idx] = outputs[i][ouput_idx] + 1
return outputs
model = keras.models.Sequential()
model.add(encoder)
model.add(bag_of_words)
model.add(keras.layers.Dense(64, activation='relu'))
model.add(keras.layers.Dense(1, activation='sigmoid'))
在模型上调用 fit() 时出现错误并不奇怪:“不兼容的形状:[8,1] 与 [32,1]”。这发生在最后一步,当批大小小于 32 时。
我的问题是:抛开性能不谈,如何为我的词袋矩阵定义输出张量,使其具有动态形状以进行批处理并使我的代码正常工作?
编辑 1 在评论之后,我意识到代码确实不起作用,因为它永远不会进入“else”分支。 我对其进行了一些编辑,使其仅使用 tf 函数:
class BagOfWords(tf.keras.layers.Layer):
def __init__(self, vocab_size=args.small_vocab_size, batch_size=args.batch_size):
super(BagOfWords, self).__init__()
self.vocab_size = vocab_size
self.batch_size = batch_size
self.outputs = tf.Variable(tf.zeros([batch_size, vocab_size]))
def build(self, input_shape):
super().build(input_shape)
def call(self, inputs):
if tf.shape(inputs)[-1] == None:
return tf.zeros([self.batch_size, self.vocab_size])
self.outputs.assign(tf.zeros([self.batch_size, self.vocab_size]))
for i in range(tf.shape(inputs)[0]):
for ii in range(tf.shape(inputs)[-1]):
output_idx = inputs[i][ii]
if output_idx >= tf.constant(self.vocab_size, dtype=tf.int64):
output_idx = tf.constant(1, dtype=tf.int64)
self.outputs[i][output_idx].assign(self.outputs[i][output_idx] + 1)
return outputs
但这并没有帮助:AttributeError: 'Tensor' object has no attribute 'assign'。
【问题讨论】:
-
无论批量大小如何,您的代码都不起作用。张量项分配不会那样工作。
-
@AloneTogether 感谢您的回答。很奇怪,因为我仔细检查了它是否有效。不管我的代码是否有效,您能指出您将如何实现这种层吗?
标签: python tensorflow keras