语音合成TTS论文优选:A HYBRID TEXT NORMALIZATION SYSTEM USING MULTI-HEAD SELF-ATTENTION FOR MANDARIN

声明:语音合成(TTS)论文优选系列主要分享论文,分享论文不做直接翻译,所写的内容主要是我对论文内容的概括和个人看法。如有转载,请标注来源。

欢迎关注微信公众号:低调奋进

A HYBRID TEXT NORMALIZATION SYSTEM USING MULTI-HEAD SELF-ATTENTION FOR MANDARIN

该文章是字节跳动AI实验室在2020.02.09发表的文章,该文章主要对TTS前端的tn模块进行优化。我们知道中文的前端TN是很琐碎的的东西,很多企业选择使用基于规则的处理方案,本文章在基于规则的方案基础上提出了混合规则和神经网络模型的方案,使tn的准确度更高,具体的文章链接https://arxiv.org/pdf/1911.04128.pdf

1 研究背景

TN(text normalization)的工作主要是把NSW(non-standard words)转成SFW(spoken-form words),用于消除歧义。例如“2020”是按照数据读法还是年月读法?"1:3"读成时间还是比分?“1”是都读“yi1"还是"yao1"?这些情况需要根据该词的上下文来判断。现有处理tn的方案主要有基于规则的方案和基于神经网络的方案。基于规则的方案主要通过正则表达式来进行匹配,该方案需要大量的实例来进行测试,主要特点是处理灵活但不便于优化提高准确度。基于神经网络的方案则可能造成不可逆的错误(目前很多公司还是基于规则,优化TTS前端工作相对后端来说还是很少)。为解决以上问题,本文提出了基于规则和神经网络混合的解决方案。

2 详细的系统结构

本文的详细结构如图1所示,本文把数字和符号相关NSW使用神经网络进行处理分类,其余的NSW例如缩写等使用规则进行处理。Neural TN model只进行分类判断,例如”2020“是按照何种方式来读,该模型的结构如图2所示的multi-head的结构。neural model产生的输出还需要使用正则进行判断是否与预测的pattern匹配,如果不匹配则还需要使用规则进行处理,匹配则进行SFW转换,由此提高TN的准确度。

语音合成TTS论文优选:text normalization

语音合成TTS论文优选:text normalization

由图3可知,训练模型的pattern数据分布严重不均衡,为了处理数据不均衡,本文提出了以下的LOSS函数。

语音合成TTS论文优选:text normalization

语音合成TTS论文优选:text normalization

3 实验结果

本文实验很简单,主要对比本文提出方案的准确度提升,这里看图表很容易看出本方案提高了1%,不做详细介绍。

语音合成TTS论文优选:text normalization

语音合成TTS论文优选:text normalization

语音合成TTS论文优选:text normalization

4 总结

本文的工作是对TTS前端TN模块进行优化,提出基于规则和神经模型混合方案,其中神经模型主要对NSW进行pattern分类,整体提升1%。(前端工作很繁琐,费事费力,提高不是太明显)

### 回答1: 以下是使用 Keras 实现 Multi-Head Self-Attention 的代码示例: ```python from tensorflow import keras from tensorflow.keras import layers class MultiHeadSelfAttention(layers.Layer): def __init__(self, embed_dim, num_heads=8): super(MultiHeadSelfAttention, self).__init__() self.embed_dim = embed_dim self.num_heads = num_heads if embed_dim % num_heads != 0: raise ValueError( f"embed_dim ({embed_dim}) must be divisible by num_heads ({num_heads})" ) self.projection_dim = embed_dim // num_heads self.query_dense = layers.Dense(embed_dim) self.key_dense = layers.Dense(embed_dim) self.value_dense = layers.Dense(embed_dim) self.combine_heads = layers.Dense(embed_dim) def attention(self, query, key, value): score = tf.matmul(query, key, transpose_b=True) dim_key = tf.cast(tf.shape(key)[-1], tf.float32) scaled_score = score / tf.math.sqrt(dim_key) weights = tf.nn.softmax(scaled_score, axis=-1) output = tf.matmul(weights, value) return output, weights def separate_heads(self, x, batch_size): x = tf.reshape(x, (batch_size, -1, self.num_heads, self.projection_dim)) return tf.transpose(x, perm=[0, 2, 1, 3]) def call(self, inputs): # x.shape = [batch_size, seq_len, embedding_dim] batch_size = tf.shape(inputs)[0] query = self.query_dense(inputs) # (batch_size, seq_len, embed_dim) key = self.key_dense(inputs) # (batch_size, seq_len, embed_dim) value = self.value_dense(inputs) # (batch_size, seq_len, embed_dim) query = self.separate_heads( query, batch_size ) # (batch_size, num_heads, seq_len, projection_dim) key = self.separate_heads( key, batch_size ) # (batch_size, num_heads, seq_len, projection_dim) value = self.separate_heads( value, batch_size ) # (batch_size, num_heads, seq_len, projection_dim) attention, weights = self.attention(query, key, value) attention = tf.transpose( attention, perm=[0, 2, 1, 3] ) # (batch_size, seq_len, num_heads, projection_dim) concat_attention = tf.reshape( attention, (batch_size, -1, self.embed_dim) ) # (batch_size, seq_len, embed_dim) output = self.combine_heads( concat_attention ) # (batch_size, seq_len, embed_dim) return output ``` 在上面的代码中,我们定义了一个名为 `MultiHeadSelfAttention` 的自定义 Keras 层。在 `__init__` 方法中,我们定义了以下变量: - `embed_dim`:嵌入维度。 - `num_heads`:头的数量。 - `projection_dim`:每个头的投影维度。 - `query_dense`、`key_dense` 和 `value_dense`:三个全连接层,用于将输入嵌入到 `embed_dim` 维空间中。 - `combine_heads`:全连接层,用于将多头注意力的输出组合成一个 `embed_dim` 维张量。 在 `call` 方法中,我们首先使用 `query_dense`、`key_dense` 和 `value_dense` 将输入嵌入到 `embed_dim` 维空间中。然后,我们将查询、键和值分别投影到 `num_heads` 个子空间中,并计算每个子空间的注意力输出。最后,我们将 `num_heads` 个子空间的注意力输出组合成一个 `embed_dim` 维张量,并通过 `combine_heads` 层进行组合。 ### 回答2: Keras是一个流行的深度学习库,它提供了方便的API来实现各种神经网络模型。其中,多头自注意力(multi-head self-attention)是一种在自然语言处理中广泛使用的技术,可以用于提取输入序列之间的重要关系。 下面是使用Keras实现多头自注意力的代码示例: ```python import tensorflow.keras as keras from keras.layers import Layer, Dense class MultiHeadSelfAttention(Layer): def __init__(self, n_heads, d_model, **kwargs): super(MultiHeadSelfAttention, self).__init__(**kwargs) self.n_heads = n_heads self.d_model = d_model self.wq = Dense(d_model) self.wk = Dense(d_model) self.wv = Dense(d_model) self.dense = Dense(d_model) def call(self, inputs): q = self.wq(inputs) k = self.wk(inputs) v = self.wv(inputs) q = self.split_heads(q) k = self.split_heads(k) v = self.split_heads(v) attention_weights = keras.layers.dot([q, k], axes=[-1, -1]) attention_weights = keras.layers.Activation('softmax')(attention_weights) output = keras.layers.dot([attention_weights, v], axes=[-1, 1]) output = self.combine_heads(output) output = self.dense(output) return output def split_heads(self, x): batch_size = keras.backend.shape(x)[0] seq_length = keras.backend.shape(x)[1] d_model = self.d_model split_size = d_model // self.n_heads x = keras.backend.reshape(x, (batch_size, seq_length, self.n_heads, split_size)) return keras.backend.permute_dimensions(x, (0, 2, 1, 3)) def combine_heads(self, x): batch_size = keras.backend.shape(x)[0] seq_length = keras.backend.shape(x)[2] d_model = self.d_model x = keras.backend.permute_dimensions(x, (0, 2, 1, 3)) return keras.backend.reshape(x, (batch_size, seq_length, d_model)) ``` 上述代码中,我们创建了一个名为MultiHeadSelfAttention的自定义层,它继承自Keras的Layer类。在构造函数中,我们指定了注意力头数n_heads和模型维度d_model。在call函数中,我们分别通过全连接层将输入序列映射为查询(q)、键(k)和值(v)的表示。然后,我们将这些表示进行头分割,计算注意力权重,并应用这些权重来聚合值。最后,我们通过全连接层将聚合后的结果映射回原始维度。 通过使用上述代码示例,我们可以在Keras中轻松实现多头自注意力机制,并将其用于自然语言处理等任务中。 ### 回答3: Keras是一个流行的深度学习框架,可以用于实现各种神经网络模型,包括self-attention模型。Multi-head self-attention是一种扩展的self-attention模型,用于加强模型对输入数据中不同部分的关注能力。 具体实现multi-head self-attention模型的代码如下: 1. 引入所需的Keras库和模块: ```python from tensorflow import keras from tensorflow.keras.layers import Dense, Input, Dropout, LayerNormalization from tensorflow.keras import Model ``` 2. 定义multi-head self-attention层的类: ```python class MultiHeadSelfAttention(keras.layers.Layer): def __init__(self, d_model, num_heads): super(MultiHeadSelfAttention, self).__init__() self.num_heads = num_heads self.d_model = d_model self.depth = int(d_model / num_heads) self.query_dense = Dense(d_model) self.key_dense = Dense(d_model) self.value_dense = Dense(d_model) self.dense = Dense(d_model) def split_heads(self, x, batch_size): x = keras.backend.reshape(x, (batch_size, -1, self.num_heads, self.depth)) return keras.backend.transpose(x, perm=[0, 2, 1, 3]) def call(self, inputs): query = inputs key = inputs value = inputs batch_size = keras.backend.shape(query)[0] query = self.query_dense(query) key = self.key_dense(key) value = self.value_dense(value) query = self.split_heads(query, batch_size) key = self.split_heads(key, batch_size) value = self.split_heads(value, batch_size) scaled_attention_outputs, attention_weights = self.compute_attention(query, key, value) scaled_attention = keras.backend.transpose(scaled_attention_outputs, perm=[0, 2, 1, 3]) concat_attention = keras.backend.reshape(scaled_attention, (batch_size, -1, self.d_model)) outputs = self.dense(concat_attention) return outputs, attention_weights def compute_attention(self, query, key, value): matmul_qk = keras.backend.batch_dot(query, key, axes=[-1, -1]) scaled_attention_logits = matmul_qk / keras.backend.sqrt(keras.backend.cast(self.depth, dtype=keras.backend.floatx())) attention_weights = keras.backend.softmax(scaled_attention_logits) attention_outputs = keras.backend.batch_dot(attention_weights, value, axes=[-1, 2]) return attention_outputs, attention_weights ``` 3. 构建完整的模型: ```python def create_model(d_model=256, num_heads=8): inputs = Input(shape=(seq_length, d_model)) attention_layer = MultiHeadSelfAttention(d_model, num_heads) attention_outputs, attention_weights = attention_layer(inputs) dropout = Dropout(0.1)(attention_outputs) normalization = LayerNormalization(epsilon=1e-6)(dropout) dense = Dense(d_model, activation='relu')(normalization) outputs = Dense(num_classes, activation='softmax')(dense) model = Model(inputs=inputs, outputs=outputs) return model ``` 这段代码实现了一个包含multi-head self-attention层的完整模型,输入shape为(seq_length, d_model),输出为一个softmax分类器的结果。考虑到不同应用场景下的具体要求,可以根据实际需要自定义模型的层数、宽度以及其他配置,来构建一个更适合具体任务的multi-head self-attention模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫永强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>