无效参数:维度 -972891 必须 >= 0
Posted
技术标签:
【中文标题】无效参数:维度 -972891 必须 >= 0【英文标题】:Invalid argument: Dimension -972891 must be >= 0 【发布时间】:2021-06-12 16:14:40 【问题描述】:我使用以下代码 sn-ps 创建了一个使用 tf.data 进行语音识别的数据管道:
def get_waveform_and_label(file_path):
label = tf.strings.split(file_path, os.path.sep)[-2]
audio_binary = tf.io.read_file(file_path)
audio, _ = tf.audio.decode_wav(audio_binary)
waveform = tf.squeeze(audio, axis=-1)
return waveform, label
def get_spectrogram(waveform):
# Padding for files with less than 16000 samples
# Generate zeros w.r.t how many the waveform lacks
zero_padding = tf.zeros([16000] - tf.shape(waveform), dtype=tf.float32)
# Concatenate audio with padding so that all audio clips will be of the same length
waveform = tf.cast(waveform, tf.float32)
waveform = tf.concat([waveform, zero_padding], 0)
spectrogram = tf.signal.stft(waveform, frame_length=255, frame_step=128)
spectrogram = tf.abs(spectrogram)
return spectrogram
def get_spectrogram_and_label_id(audio, label):
spectrogram = get_spectrogram(audio)
spectrogram = tf.expand_dims(spectrogram, -1)
label_id = tf.argmax(label == np.array(labels))
label_onehot = tf.one_hot(label_id, len(labels))
return spectrogram, label_onehot
files_ds = tf.data.Dataset.from_tensor_slices(files)
waveform_ds = files_ds.map(get_waveform_and_label, num_parallel_calls=tf.data.AUTOTUNE)
spectrogram_ds = waveform_ds.map(get_spectrogram_and_label_id, num_parallel_calls=tf.data.AUTOTUNE)
这些sn-ps是从https://www.tensorflow.org/tutorials/audio/simple_audio#build_and_train_the_model借来的。
我的模型定义如下:
import tensorflow as tf
inputs = tf.keras.layers.Input(shape=(input_shape))
x = tf.keras.layers.BatchNormalization()(inputs)
x = tf.keras.layers.Conv2D(8,13, padding='same', activation='relu', strides=1)(x)
x = tf.keras.layers.MaxPooling2D(3)(x)
x = tf.keras.layers.Dropout(0.4)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Conv2D(32, 11, padding='same', activation='relu', strides=1)(x)
x = tf.keras.layers.MaxPooling2D(3)(x)
x = tf.keras.layers.Dropout(0.4)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Conv2D(256, 9, padding='same', activation='relu', strides=1)(x)
x = tf.keras.layers.MaxPooling2D(3)(x)
x = tf.keras.layers.Dropout(0.4)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(512, activation='relu')(x)
outputs = tf.keras.layers.Dense(len(labels), activation="softmax")(x)
model = tf.keras.models.Model(inputs, outputs)
model.compile(loss="categorical_crossentropy",
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
model.summary()
当我开始训练过程时,这个错误会在几次迭代后出现:
> InvalidArgumentError: 2 root error(s) found.
> (0) Invalid argument:
> Dimension -972891 must be >= 0 [[node zeros]]
> [[IteratorGetNext]]
> [[categorical_crossentropy/softmax_cross_entropy_with_logits/Shape_2/_6]]
> (1) Invalid argument: Dimension -972891 must be >= 0 [[node
> zeros]] [[IteratorGetNext]] 0 successful operations. 0 derived
> errors ignored. [Op:__inference_train_function_6412]
>
> Function call stack: train_function -> train_function
【问题讨论】:
【参考方案1】:我发现问题发生在填充步骤中,我的意思是
zero_padding = tf.zeros([16000] - tf.shape(waveform), dtype=tf.float32)
waveform = tf.cast(waveform, tf.float32)
waveform = tf.concat([waveform, zero_padding], 0)
我已将填充步骤替换为 tf.signal.frame,问题已解决。
【讨论】:
你是怎么做到的?使用 tf.signal.frame 后可以分享一下你的代码 sn-p 吗?【参考方案2】:出现这个错误是因为tf.shape(waveform)的输出大于16000,需要将16000增加到大于tf.shape(waveform)给出的值em>。
我建议在上面添加一行print(tf.shape(waveform)),这样你就可以看到需要增加什么了。
【讨论】:
【参考方案3】:我在尝试时也遇到了同样的问题,检查波形文件的频率(采样率)是否为 16000,如果不是,您可以使用 ffmpeg 将其更改为 16000 或任何其他工具。问题仍然存在,您只需检查波形文件的样本数(样本数应为 16000)。
如果不是,您可以更改持续时间或样本数,因为这三个相关为 采样率 = 采样数 / 时间 因此,即使您的采样率降低,您的采样数也会减少,但如果 wav 文件不是 1 秒,它会大于 16000。
【讨论】:
以上是关于无效参数:维度 -972891 必须 >= 0的主要内容,如果未能解决你的问题,请参考以下文章
无效参数:“使用”必须是在 iframe 中提取图像源的字符串
Microsoft Edge 的“无效参数:'handle' 必须是字符串”错误以及如何添加“w3c:false”功能?
selenium.common.exceptions.InvalidArgumentException:消息:无效参数:“使用”必须是使用等待和预期条件的字符串
必须在传递给 C 运行时函数的 QWidget 和无效参数之前构造一个 QApplication
TypeError:获取参数数组的类型无效 numpy.ndarray,必须是字符串或张量。 (不能将 ndarray 转换为张量或操作。)