【问题标题】:Why does Keras.preprocessing.sequence pad_sequences process characters instead of words?为什么 Keras.preprocessing.sequence pad_sequences 处理字符而不是单词?
【发布时间】:2020-09-26 02:14:16
【问题描述】:

我正在将语音转录为文本,但在 Keras 中使用 pad_sequences 时遇到了一个问题(我认为)。我预训练了一个在数据帧上使用pad_sequences 的模型,它将数据放入一个数组中,每个值的列数和行数相同。但是,当我在转录文本时使用 pad_sequences 时,该语音字符串中的字符数是作为 numpy 数组返回的行数。

假设我有一个包含 4 个字符的字符串,那么它将返回一个 4 X 500 Numpy 数组。对于 6 个字符的字符串,它将返回 6 X 500 Numpy 数组等等。

我的澄清代码:

import speech_recognition as sr
import pyaudio
import pandas as pd
from helperFunctions import *

jurors = ['Zack', 'Ben']
storage = []
storage_df = pd.DataFrame()


while len(storage) < len(jurors):
    print('Juror' + ' ' + jurors[len(storage)] + ' ' + 'is speaking:')
    init_rec = sr.Recognizer()
    with sr.Microphone() as source:
        audio_data = init_rec.adjust_for_ambient_noise(source)
        audio_data = init_rec.listen(source) #each juror speaks for 10 seconds
        audio_text = init_rec.recognize_google(audio_data)
        print('End of juror' + ' ' + jurors[len(storage)] + ' ' + 'speech')
        storage.append(audio_text)
        cleaned = clean_text(audio_text)
        tokenized = tokenize_text(cleaned)
        padded_text = padding(cleaned, tokenized) #fix padded text elongating rows

我使用辅助函数脚本:

def clean_text(text, stem=False):
    text_clean = '@\S+|https?:\S|[^A-Za-z0-9]+'
    text = re.sub(text_clean, ' ', str(text).lower()).strip()
    #text = tf.strings.substr(text, 0, 300) #restrict text size to 300 chars
    return text

def tokenize_text(text):
    tokenizer = Tokenizer()
    tokenizer.fit_on_texts(text)
    return tokenizer

def padding(text, tokenizer):
    text = pad_sequences(tokenizer.texts_to_sequences(text), 
                       maxlen = 500)
    return text

返回的文本将被输入到预先训练的模型中,我很确定不同长度的行会导致问题。

【问题讨论】:

    标签: python keras nlp speech-to-text text-processing


    【解决方案1】:

    Tokenizer 的方法,例如 fit_on_textstexts_to_sequences,需要一个文本/字符串的列表作为输入(顾名思义,即 texts)。但是,您将单个文本/字符串传递给它们,因此它会迭代其字符,而不是假设它实际上是一个列表!

    解决此问题的一种方法是在每个函数的开头添加一个检查,以确保输入数据类型实际上是一个列表。例如:

    def padding(text, tokenizer):
        if isinstanceof(text, str):
            text = [text]
        # the rest would not change...
    

    您也应该对tokenize_text 函数执行此操作。进行此更改后,您的自定义函数将适用于单个字符串以及字符串列表。


    作为重要的附注,如果您在问题中输入的代码属于预测阶段,则其中存在根本错误:您应该使用与训练模型时相同的 Tokenizer 实例,以确保映射和标记化的完成方式与训练阶段相同。实际上,为每个或所有测试样本创建一个新的Tokenizer 实例是没有意义的(除非它具有与训练阶段使用的相同的映射和配置)。

    【讨论】:

    • 谢谢!实际上,我在发布此文档后立即阅读了一些文档,说明我想保存和重用我的标记化权重。您的解释使它更加清晰,并且代码有效!
    • 嗨@today我读了你的答案,这是非常准确的,但我在同一个场景中还有另一个问题,如果我在数据框中有多个文本列怎么办,我们如何标记和 pad_sequences 那些列并再次将它们重新分配给数据框。这是我发布的问题,stackoverflow.com/questions/67769093/…
    猜你喜欢
    • 2022-07-18
    • 2021-05-23
    • 1970-01-01
    • 2019-06-20
    • 2014-06-08
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多