为什么我的模型使用 Ragged Tensors 而不是 Dense Tensors 学习?

问题描述

我有一个跟在“语法”后面的字母串。我的训练集上还有布尔标签,表示字符串是否遵循“语法”。基本上,我的模型正在尝试学习确定一串字母是否符合规则。这是一个相当简单的问题(我从教科书中得到的)。

我正在像这样生成我的数据集:

def generate_dataset(size):
    good_strings = [string_to_ids(generate_string(embedded_reber_grammar))
                    for _ in range(size // 2)]
    bad_strings = [string_to_ids(generate_corrupted_string(embedded_reber_grammar))
                   for _ in range(size - size // 2)]
    all_strings = good_strings + bad_strings
    X = tf.ragged.constant(all_strings,ragged_rank=1)

    # X = X.to_tensor(default_value=0)

    y = np.array([[1.] for _ in range(len(good_strings))] +
                 [[0.] for _ in range(len(bad_strings))])
    return X,y

注意行 X = X.to_tensor(default_value=0)。如果这一行被注释掉,我的模型学习就好了。但是,如果不注释掉,则学习失败,验证集表现与机会相同(50-50)。

这是我的实际模型:

np.random.seed(42)
tf.random.set_seed(42)

embedding_size = 5

model = keras.models.Sequential([
    keras.layers.InputLayer(input_shape=[None],dtype=tf.int32,ragged=True),keras.layers.Embedding(input_dim=len(POSSIBLE_CHARS) + 1,output_dim=embedding_size),keras.layers.GRU(30),keras.layers.Dense(1,activation="sigmoid")
])
optimizer = keras.optimizers.SGD(lr=0.02,momentum = 0.95,nesterov=True)
model.compile(loss="binary_crossentropy",optimizer=optimizer,metrics=["accuracy"])
history = model.fit(X_train,y_train,epochs=5,validation_data=(X_valid,y_valid))

我使用 0 作为密集张量的默认值。 strings_to_ids 不对任何值使用 0,而是从 1 开始。此外,当我切换到使用密集张量时,我将 ragged=True 更改为 False. 我不知道为什么使用密集张量会导致模型失败,因为我之前在类似练习中使用过密集张量。

有关其他详细信息,请参阅书中的解决方案 (exercise 8) 或我自己的合作实验室 notebook

解决方法

所以结果是密集张量的形状在训练集和验证集上是不同的。这是因为两组之间最长的序列长度不同(与测试集相同)。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...