es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

STFT no está invertido correctamente sin uso de una ventana en Tensorflow.

Tensorflow no está reconstruyendo la señal original al aplicar la transformación STFT seguida de la inversa STFT. Los problemas surgen cuando los marcos de la STFT se superponen: parece que cada marco contribuye con un peso de 1 independientemente de la cantidad de marcos superpuestos N = frame_size / frame_step. Como resultado, la parte central de la señal es N veces mayor que la original. Aquí hay un código mínimo para reproducir el error:

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

size = 2048
frame_length = 512
frame_step = 128
waveform = np.sin(np.arange(size) * 1 / 100)

stft = tf.signal.stft(waveform, frame_length, frame_step, window_fn=None)
inverse_stft = tf.signal.inverse_stft(stft, frame_length, frame_step, window_fn=None)

plt.plot(waveform)
plt.plot(inverse_stft)
plt.show()
plt.clf()

Observa que no estoy utilizando ventana alguna. Si uso la ventana Hann, la parte central funciona bien pero los bordes disminuyen suavemente a cero, un error relacionado pero sorprendentemente diferente. La implementación de scipy funciona bien en todas las circunstancias.

¿Me estoy perdiendo algo?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está relacionado con el hecho de que cada trama en STFT está contribuyendo con el mismo peso, independientemente de la superposición. Esto lleva a que la parte central de la señal sea N veces más grande que la original al aplicar la STFT inversa, donde N = frame_size / frame_step.

    Una posible solución podría ser aplicar una función de ventana a las tramas antes de calcular la STFT, ya que esto reduciría efectivamente el peso de las tramas superpuestas en la parte central de la señal. En el código provisto, la ventana Hann podría usarse de la siguiente manera:

    # Aplicar ventana Hann a cada trama
    window = tf.signal.hann_window(frame_length, periodic=True, dtype=tf.float64)
    waveform = tf.cast(waveform, tf.float64)
    frames = tf.signal.frame(waveform, frame_length, frame_step, pad_end=True, pad_value=0)
    windowed_frames = frames * window
    
    # Calcular la STFT
    stft = tf.signal.stft(windowed_frames, frame_length, frame_step, window_fn=None)
    
    # Realizar STFT inversa
    inverse_stft = tf.signal.inverse_stft(stft, frame_length, frame_step, window_fn=None)
    
    # Plotear resultados
    plt.plot(waveform)
    plt.plot(inverse_stft)
    plt.show()
    plt.clf()
    

    Esto debería dar como resultado una señal reconstruida que se asemeje de cerca a la original, incluso con tramas superpuestas.

Comments are closed.