I am building an audio classifier in which the NN is going to be trained to classify audios into just two classes. The following is my "train.py" module:
import os
import tensorflow as tf
import numpy as np
from configs import PARENT_DIR_TO_SAVE_CHUNKS, VALIDATION_PERCENT_OUT_OF_TOTAL, TEST_PERCENT_OUT_OF_TOTAL, PARENT_DIR_TO_PCM_GOOD_CHUNKS, PARENT_DIR_TO_PCM_BAD_CHUNKS
from utils import decode_audio, do_process_path_of_audio, get_label, get_waveform_and_label, plot, get_spectrogram
def main():
goods = [os.path.join(PARENT_DIR_TO_SAVE_CHUNKS, "GOOD",file) for file in os.listdir(os.path.join(PARENT_DIR_TO_SAVE_CHUNKS, "GOOD"))]
bads = [os.path.join(PARENT_DIR_TO_SAVE_CHUNKS, "BAD",file) for file in os.listdir(os.path.join(PARENT_DIR_TO_SAVE_CHUNKS, "BAD"))]
all = goods + bads
filenames = tf.convert_to_tensor(all)
filenames = tf.random.shuffle(filenames)
print(filenames)
length_of_val_samples = int((VALIDATION_PERCENT_OUT_OF_TOTAL / 100) * len(filenames))
length_of_test_samples = int((TEST_PERCENT_OUT_OF_TOTAL / 100) * len(filenames))
train_files = filenames[:len(filenames) - length_of_val_samples - length_of_test_samples]
val_files = filenames[len(filenames) - length_of_val_samples - length_of_test_samples:\
len(filenames) - length_of_val_samples]
test_files = filenames[-(length_of_test_samples):]
print('Training set size:', len(train_files))
print('Validation set size:', len(val_files))
print('Test set size:', len(test_files))
(files, waveforms) = do_process_path_of_audio(train_files)
print(waveforms)
# plot(waveforms)
# print(waveforms.take(1))
for waveform, label in waveforms.take(1):
label = label.numpy().decode('utf-8')
spectrogram = get_spectrogram(waveform)
# print('Label:', label)
# print('Waveform shape:', waveform.shape)
# print('Spectrogram shape:', spectrogram.shape)
if __name__ == "__main__":
main()
And the following contains the related functions inside my "preprocess.py" module:
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import os
def decode_audio(audio_binary):
audio, _ = tf.audio.decode_wav(audio_binary)
print(_)
print(audio)
return tf.squeeze(audio, axis=-1)
def get_label(file_path):
parts = tf.strings.split(file_path, os.path.sep)
print(file_path)
return parts[-2]
def get_waveform_and_label(file_path):
label = get_label(file_path)
audio_binary = tf.io.read_file(file_path)
waveform = decode_audio(audio_binary)
return waveform, label
def do_process_path_of_audio(files):
AUTOTUNE = tf.data.AUTOTUNE
files_ds = tf.data.Dataset.from_tensor_slices(files)
waveform_ds = files_ds.map(get_waveform_and_label, num_parallel_calls=AUTOTUNE)
return (files_ds, waveform_ds)
def plot(waveforms):
rows = 3
cols = 3
n = rows*cols
fig, axes = plt.subplots(rows, cols, figsize=(10, 12))
print("======>", waveforms.take(15))
for i, (audio, label) in enumerate(waveforms.take(n)):
r = i // cols
c = i % cols
ax = axes[r][c]
ax.plot(audio.numpy())
ax.set_yticks(np.arange(-1.2, 1.2, 0.2))
label = label.numpy().decode('utf-8')
ax.set_title(label)
plt.show()
def get_spectrogram(waveform):
zero_padding = tf.zeros([16000] - tf.shape(waveform), dtype=tf.float32)
waveform = tf.cast(waveform, tf.float32)
equal_length = tf.concat([waveform, zero_padding], 0)
spectrogram = tf.signal.stft(
equal_length, frame_length=255, frame_step=128)
spectrogram = tf.abs(spectrogram)
return spectrogram
Now when I reach the line:
for waveform, label in waveforms.take(1)
I get the following error: OP_REQUIRES failed at decode_wav_op.cc:55 : Invalid argument: Can only read 16-bit WAV files, but received 32
I have check the sample_rate of my dataset audios and they are all in 16000. I have searched all over the Internet but found no one has asked sth like this. Any Idea how to solve this.