Machine learning Keras文本预处理-将标记器对象保存到文件以进行评分

Machine learning Keras文本预处理-将标记器对象保存到文件以进行评分,machine-learning,neural-network,nlp,deep-learning,keras,Machine Learning,Neural Network,Nlp,Deep Learning,Keras,我已经使用Keras库通过以下步骤(大致)训练了一个情绪分类器模型 使用标记器对象/类将文本语料库转换为序列 使用model.fit()方法构建模型 评估这个模型 现在,对于使用此模型进行评分,我能够将模型保存到文件中并从文件中加载。但是,我还没有找到将标记器对象保存到文件的方法。如果没有这一点,我将不得不处理语料库每次我需要得分,即使是一个句子。有办法解决这个问题吗?最常用的方法是使用或。这里有一个关于如何使用pickle保存标记器的示例: 导入pickle #拯救 以open('tokeni

我已经使用Keras库通过以下步骤(大致)训练了一个情绪分类器模型

  • 使用标记器对象/类将文本语料库转换为序列
  • 使用model.fit()方法构建模型
  • 评估这个模型

  • 现在,对于使用此模型进行评分,我能够将模型保存到文件中并从文件中加载。但是,我还没有找到将标记器对象保存到文件的方法。如果没有这一点,我将不得不处理语料库每次我需要得分,即使是一个句子。有办法解决这个问题吗?

    最常用的方法是使用或。这里有一个关于如何使用
    pickle
    保存
    标记器的示例:

    导入pickle
    #拯救
    以open('tokenizer.pickle','wb')作为句柄:
    pickle.dump(标记器、句柄、协议=pickle.HIGHEST\u协议)
    #装载
    使用open('tokenizer.pickle','rb')作为句柄:
    标记器=pickle.load(句柄)
    
    我在keras回购协议中创建了该问题。在API更改之前,该问题有一个指向gist的链接,gist中有代码来演示如何保存和恢复标记器,而不必使用标记器安装的原始文档。我更喜欢将所有模型信息存储在JSON文件中(因为原因,但主要是混合了JS/Python环境),这将允许这样做,即使使用sort_keys=True,接受的答案也清楚地演示了如何保存标记器。以下是对装配或保存后(通常)评分问题的评论。假设一个列表
    text
    由两个列表
    Train\u text
    Test\u text
    组成,其中
    Test\u text
    中的令牌集是
    Train\u text
    中令牌集的子集(乐观假设)。然后
    fit_on_text(Train_text)
    text_to_sequences(Test_text)
    给出与第一次调用
    fit_on_text(text)
    text_to_sequences(Test_text)
    不同的结果

    具体例子:

    from keras.preprocessing.text import Tokenizer
    
    docs = ["A heart that",
             "full up like",
             "a landfill",
            "no surprises",
            "and no alarms"
             "a job that slowly"
             "Bruises that",
             "You look so",
             "tired happy",
             "no alarms",
            "and no surprises"]
    docs_train = docs[:7]
    docs_test = docs[7:]
    # EXPERIMENT 1: FIT  TOKENIZER ONLY ON TRAIN
    T_1 = Tokenizer()
    T_1.fit_on_texts(docs_train)  # only train set
    encoded_train_1 = T_1.texts_to_sequences(docs_train)
    encoded_test_1 = T_1.texts_to_sequences(docs_test)
    print("result for test 1:\n%s" %(encoded_test_1,))
    
    # EXPERIMENT 2: FIT TOKENIZER ON BOTH TRAIN + TEST
    T_2 = Tokenizer()
    T_2.fit_on_texts(docs)  # both train and test set
    encoded_train_2 = T_2.texts_to_sequences(docs_train)
    encoded_test_2 = T_2.texts_to_sequences(docs_test)
    print("result for test 2:\n%s" %(encoded_test_2,))
    
    结果:

    result for test 1:
    [[3], [10, 3, 9]]
    result for test 2:
    [[1, 19], [5, 1, 4]]
    

    当然,如果不满足上述乐观假设,并且测试文本中的令牌集与列车测试中的令牌集不相交,那么测试1将产生一个空括号列表。
    []。

    令牌化器类具有将日期保存为JSON格式的功能:

    tokenizer\u json=tokenizer.to\u json()
    将io.open('tokenizer.json','w',encoding='utf-8')作为f:
    f、 写入(json.dumps(标记器\u json,确保\u ascii=False))
    
    可以使用
    keras\u预处理中的
    tokenizer\u from\u json
    函数加载数据。text

    以open('tokenizer.json')作为f的
    :
    data=json.load(f)
    tokenizer=tokenizer_from_json(数据)
    
    我找到了以下由提供的代码片段

    保存对象:

    import pickle
    
    with open('data_objects.pickle', 'wb') as handle:
        pickle.dump(
            {'input_tensor': input_tensor, 
             'target_tensor': target_tensor, 
             'inp_lang': inp_lang,
             'targ_lang': targ_lang,
            }, handle, protocol=pickle.HIGHEST_PROTOCOL)
    
    加载对象:

    with open("dataset_fr_en.pickle", 'rb') as f:
        data = pickle.load(f)
        input_tensor = data['input_tensor']
        target_tensor = data['target_tensor']
        inp_lang = data['inp_lang']
        targ_lang = data['targ_lang']
    

    您是否在测试集中的文本上再次调用tokenizer.fit_?否。如果您再次调用fit*,它可能会更改索引。加载pickle的标记器已准备好使用。请稍候。为了将来运行模型,您必须同时保存模型和标记器?当然!他们有两个不同的角色,标记器将文本转换为向量,在训练和测试之间有相同的向量空间很重要。链接的gist看起来是“重新加载”训练过的标记器的好方法。然而,最初的问题可能涉及将先前保存的标记器“扩展”到新的(测试)文本;这一部分似乎仍然是开放的(否则,如果模型不用于“评分”新数据,为什么要“保存”它呢?)我认为他们的意图是明确的,“没有这个,每次我需要评分哪怕是一个句子,我都必须处理语料库”。由此,我推断他们希望跳过标记化步骤,在其他数据上评估经过训练的模型。他们不会问任何其他问题,这是你所期待的。他们和大多数人一样,只想在不同的数据集上使用以前标记过的数据,这在大多数教程中都会被跳过。因此,我认为我的答案1)回答了问题,2)提供了工作代码。公平分数。问题是“将标记器对象保存到文件以进行评分”,因此人们可能会认为他们也在询问评分(可能是新数据)。故事的寓意是:如果使用单词嵌入和keras的标记器,则在非常大的语料库中仅对文本使用一次fit;或者改用字符n-grams。我不明白你想要传达的信息是什么:为什么一开始就适合测试文档?根据定义,无论您在做什么,测试都必须保存在一个保险库中,就好像您一开始不知道自己有测试一样。@gented:您可能把无监督文本解析与有监督的ML混淆了。如果我错了,请纠正我,但keras的标记器没有附加用于泛化的丢失函数;因此,这不是一个(有监督的)机器学习问题——这似乎是你的假设。我试图传达的信息在我上面的第一条评论(“故事的寓意…”)中进行了总结,这可能值得重新阅读。@gented good points。对不起,如果命名法把你弄糊涂了;我与公认答案中的评论保持了一定的一致性。Keras中似乎不再提供来自json的标记器,或者更确切地说,它没有在他们的文档中列出,或者在conda@Max中的包中可用。你仍然这样做吗?@benbyford我使用PyPI的
    Keras Preprocessing==1.0.9
    包,函数
    tokenizer_to_json
    应该很快在tensorflow>2.0.0上可用,请同时参阅keras_preprocessing中的
    。可以使用来自_json的文本导入标记器_