如何将langdetect的语言概率向量添加到Keras序贯模型中?

ncgqoxb0  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(128)

我目前正在研究歌唱语言识别问题(以及机器学习的基础知识)。我在互联网上找到了很多关于这方面的工作,但其中一些没有提供任何代码(甚至是伪代码),这就是为什么我试图使用他们的机器学习模型描述来重现它们。
一个很好的例子是由Keunwoo Choi和Yuxuan Wang编写的LISTEN, READ, AND IDENTIFY: MULTIMODAL SINGING LANGUAGE IDENTIFICATION OF MUSIC
总而言之,他们将两个层面串联起来:音频层(以声谱图的形式)、文本层(使用LangDetect的元数据上的语言概率向量、56维向量)。
The text branch is a 3-layer MLP where each layer consists of a 128-unit fully-connected layer, a batch normalization layer, and a ReLU activation [22].
对于文本模型,我得到了这样的结果:

text_model = Sequential()
text_model.add(Input((56,), name='input'))
text_model.add(BatchNormalization())
text_model.add(Dense(128, activation='relu'))

langdetect.detect_langs(metadata)会传回[de:0.8571399874707945, en:0.14285867860989504]
我不确定我是否正确描述了我的模型,我不明白如何将它正确地(langdetect概率向量)放入keras模型。

mcvgt66p

mcvgt66p1#

首先,需要将langdetect输出转换为一个恒定长度的向量。库中有55种语言,因此我们需要创建一个长度为55的向量,其中第i个元素表示文本来自第i种语言的概率。可以这样做:

import tensorflow as tf

import numpy as np
import langdetect

langdetect.detector_factory.init_factory()
LANGUAGES_LIST = langdetect.detector_factory._factory.langlist

def get_probabilities_vector(text):
    
    predictions = langdetect.detect_langs(text)
    output = np.zeros(len(LANGUAGES_LIST))
    
    for p in predictions:
        output[LANGUAGES_LIST.index(p.lang)] = p.prob
        
    return tf.constant(output)

然后你需要创建一个有多个输入的模型,这可以通过functional API来实现,例如,如下所示(根据用例更改输入):

def create_model():
    
    audio_input = tf.keras.Input(shape=(256,))
    langdetect_input = tf.keras.Input(shape=(55,))
    
    x = tf.keras.layers.concatenate([audio_input, langdetect_input])
    x = tf.keras.layers.Dense(128, activation='relu')(x)
    output = tf.keras.layers.Dense(55)(x)
    
    model = tf.keras.Model(
        inputs={
            'audio': audio_input,
            'text': langdetect_input
        },
        outputs=output)
        
    return model

在某些输入上测试模型:

model = create_model()

audio_input = tf.constant(np.random.rand(256))
langdetect_input = get_probabilities_vector('This is just a test input')

model({
    'audio': tf.expand_dims(audio_input, 0),
    'text': tf.expand_dims(langdetect_input, 0)
})

>>> <tf.Tensor: shape=(1, 55), dtype=float32, numpy=
array([[ 0.23361185,  0.19011918, -0.45230836, -0.0602392 , -0.20067683,
         0.9698535 , -1.0724173 ,  0.08978442,  0.052798  , -0.16554174,
         0.9238764 ,  1.0331644 ,  0.4508734 , -0.2450786 , -1.0605856 ,
         0.3239496 , -1.0073977 , -0.2129285 , -0.6817296 ,  0.05288622,
         0.9089616 , -0.11521344,  0.25696573, -0.07688305, -0.36123943,
        -0.0317415 , -0.18303779,  0.13786468,  0.88620317,  0.11393422,
        -0.5215691 , -0.28585738,  0.54988045, -0.02300271, -0.4347821 ,
        -0.57744324,  0.14031887,  0.8255624 , -0.13157232, -1.1060234 ,
        -0.24097277,  0.12950295,  0.4586677 ,  0.37702668,  0.7558856 ,
        -0.05933011,  0.53903174,  0.27433476, -0.18464057,  1.0673125 ,
        -0.05723387, -0.03429477,  0.4431308 , -0.14510366, -0.28087378]],
      dtype=float32)>

我使用expand_dims函数扩展输入的维度,使输入具有(1, 256)(1, 55)的形状(这与模型在训练期间预期的输入(batch_size, 256)(batch_size, 55)类似)。
这只是一个草稿,但这是你的问题大致可以解决。

相关问题