问题描述
我想用Tensorflow实现具有CTC丢失的语音识别器。输入要素的长度可变,因为每种语音发音的长度都可以变化。标记的长度也可变,因为每次转录都不同。我手动填充要素以创建批次,在我的模型中,我拥有tf.keras.layers.Masking()层来创建并通过网络传播遮罩。我还使用填充创建了批处理标签。
这是一个虚拟的例子。假设我有两个长度分别为3和5帧的讲话。每帧都由一个功能代表(通常是13个MFCC,但为了简化起见,我将其简化为一个)。因此,要创建批处理,我将简短的话语填充为0:
features = np.array([1.5 2.3 4.6 0.0 0.0],[1.7 2.6 3.4 2.3 1.0])
标签是这些话语的转录。假设长度分别为2和3。标签的批处理形状将为[2、3、26],其中批处理大小为2,最大长度为3,英文字符为26(一次性编码)。
模型是:
input_ = tf.keras.Input(shape=(None,1))
x = tf.keras.layers.Masking()(input_)
x = tf.keras.layers.GRU(26,return_sequences=True)(input_)
output_ = tf.keras.layers.Softmax(axis=-1)(x)
model = tf.keras.Model(input_,output_)
损失函数类似于:
def ctc_loss(y_true,y_pred):
# Do something here to get logit_length and label_length?
# ...
loss = tf.keras.backend.ctc_batch_cost(y_true,y_pred,logit_length,label_length)
我的问题是如何获取logit_length和label_length。我想将logit_length编码在掩码中,但是如果执行y_pred._keras_mask,则结果为None。对于label_length,信息在张量本身中,但是我不确定获取它的最有效方法。
谢谢。
更新:
按照你的回答,我使用tf.math.count_nonzero来获取label_length,并将logit_length设置为logit层的长度。
因此损失函数中的形状为(批量大小= 10):
y_true.shape = (10,None)
y_pred.shape = (10,None,27)
label_length.shape = (10,1)
logit_lenght.shape = (10,1)
当然y_true和y_pred的“ None”是不相同的,因为一个是批处理的最大字符串长度,另一个是批处理的最大时间范围。但是,当我使用这些参数调用model.fit()并在tf.keras.backend.ctc_batch_cost()丢失时,出现错误:
Traceback (most recent call last):
File "train.py",line 164,in <module>
model.fit(dataset,batch_size=batch_size,epochs=10)
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py",line 66,in _method_wrapper
return method(self,*args,**kwargs)
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py",line 848,in fit
tmp_logs = train_function(iterator)
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py",line 580,in __call__
result = self._call(*args,**kwds)
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py",line 644,in _call
return self._stateless_fn(*args,**kwds)
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/eager/function.py",line 2420,in __call__
return graph_function._filtered_call(args,kwargs) # pylint: disable=protected-access
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/eager/function.py",line 1661,in _filtered_call
return self._call_flat(
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/eager/function.py",line 1745,in _call_flat
return self._build_call_outputs(self._inference_function.call(
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/eager/function.py",line 593,in call
outputs = execute.execute(
File "/home/pablo/miniconda3/envs/lightvoice/lib/python3.8/site-packages/tensorflow/python/eager/execute.py",line 59,in quick_execute
tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle,device_name,op_name,tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: Incompatible shapes: [10,92] vs. [10,876]
[[node Equal (defined at train.py:164) ]]
(1) Invalid argument: Incompatible shapes: [10,876]
[[node Equal (defined at train.py:164) ]]
[[ctc_loss/Log/_62]]
0 successful operations.
0 derived errors ignored. [Op:__inference_train_function_3156]
Function call stack:
train_function -> train_function
似乎在抱怨y_true(92)的长度与y_pred(876)的长度不同,我认为不应该这样。我想念什么?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)