Repository: magenta/ddsp

Issue:
All alternative spectral losses throw an error
SpectralLoss:
I am trying to use alternative loss weights, but all of them throw an error except logmag_weight and mag_weight:

```
INFO:tensorflow:Error reported to Coordinator: in user code:

    /usr/local/lib/python3.6/dist-packages/ddsp/training/models.py:64 __call__  *
        results = super().__call__(*args, **kwargs)
    /usr/local/lib/python3.6/dist-packages/ddsp/training/models.py:123 call  *
        loss = loss_obj(features['audio'], audio_gen)
    /usr/local/lib/python3.6/dist-packages/ddsp/losses.py:107 call  *
        target = diff(target_mag, axis=1)
    /usr/local/lib/python3.6/dist-packages/ddsp/spectral_ops.py:158 diff  *
        size = shape.as_list()

    AttributeError: 'list' object has no attribute 'as_list'
```

or in case of trying to use loudness:
```
INFO:tensorflow:Error reported to Coordinator: in user code:

    /usr/local/lib/python3.6/dist-packages/ddsp/training/models.py:64 __call__  *
        results = super().__call__(*args, **kwargs)
    /usr/local/lib/python3.6/dist-packages/ddsp/training/models.py:123 call  *
        loss = loss_obj(features['audio'], audio_gen)
    /usr/local/lib/python3.6/dist-packages/ddsp/losses.py:138 call  *
        target = spectral_ops.compute_loudness(target_audio, n_fft=2048)
    /usr/local/lib/python3.6/dist-packages/ddsp/spectral_ops.py:209 compute_loudness  *
        s = stft_fn(audio, frame_size=n_fft, overlap=overlap, pad_end=True)
    /usr/local/lib/python3.6/dist-packages/ddsp/spectral_ops.py:61 stft_np  *
        audio = np.pad(audio, padding, 'constant')
    <__array_function__ internals>:6 pad  **
        
    /usr/local/lib/python3.6/dist-packages/numpy/lib/arraypad.py:741 pad
        array = np.asarray(array)
    /usr/local/lib/python3.6/dist-packages/numpy/core/_asarray.py:85 asarray
        return array(a, dtype, copy=False, order=order)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py:749 __array__
        " array.".format(self.name))

    NotImplementedError: Cannot convert a symbolic Tensor (fn:0) to a numpy array.
```

Discussion:

Patch:
diff --git a/ddsp/losses.py b/ddsp/losses.py
index be3828c..76dfbfd 100644
--- a/ddsp/losses.py
+++ b/ddsp/losses.py
@@ -135,8 +135,9 @@ class SpectralLoss(tfkl.Layer):
                                                      self.loss_type)
 
     if self.loudness_weight > 0:
-      target = spectral_ops.compute_loudness(target_audio, n_fft=2048)
-      value = spectral_ops.compute_loudness(audio, n_fft=2048)
+      target = spectral_ops.compute_loudness(target_audio, n_fft=2048,
+                                             use_tf=True)
+      value = spectral_ops.compute_loudness(audio, n_fft=2048, use_tf=True)
       loss += self.loudness_weight * mean_difference(target, value,
                                                      self.loss_type)
 
diff --git a/ddsp/spectral_ops.py b/ddsp/spectral_ops.py
index df9df08..b9466d0 100644
--- a/ddsp/spectral_ops.py
+++ b/ddsp/spectral_ops.py
@@ -155,10 +155,9 @@ def diff(x, axis=-1):
   begin_front = [0 for _ in range(len(shape))]
   begin_front[axis] = 1
 
-  size = shape.as_list()
-  size[axis] -= 1
-  slice_front = tf.slice(x, begin_front, size)
-  slice_back = tf.slice(x, begin_back, size)
+  shape[axis] -= 1
+  slice_front = tf.slice(x, begin_front, shape)
+  slice_back = tf.slice(x, begin_back, shape)
   d = slice_front - slice_back
   return d
 
diff --git a/ddsp/version.py b/ddsp/version.py
index 3c2b321..e714ae9 100644
--- a/ddsp/version.py
+++ b/ddsp/version.py
@@ -19,4 +19,4 @@ Stored in a separate file so that setup.py can reference the version without
 pulling in all the dependencies in __init__.py.
 """
 
-__version__ = '0.2.1'
+__version__ = '0.2.2'


Test patch:
diff --git a/ddsp/losses_test.py b/ddsp/losses_test.py
index c4cb431..0357c1f 100644
--- a/ddsp/losses_test.py
+++ b/ddsp/losses_test.py
@@ -23,10 +23,19 @@ import tensorflow.compat.v2 as tf
 class SpectralLossTest(tf.test.TestCase):
 
   def test_output_shape_is_correct(self):
-    loss_obj = losses.SpectralLoss()
-
-    input_audio = tf.random.uniform((3, 16000), dtype=tf.float32)
-    target_audio = tf.random.uniform((3, 16000), dtype=tf.float32)
+    """Test correct shape with all losses active."""
+    loss_obj = losses.SpectralLoss(
+        mag_weight=1.0,
+        delta_time_weight=1.0,
+        delta_delta_time_weight=1.0,
+        delta_freq_weight=1.0,
+        delta_delta_freq_weight=1.0,
+        logmag_weight=1.0,
+        loudness_weight=1.0,
+    )
+
+    input_audio = tf.random.uniform((3, 8000), dtype=tf.float32)
+    target_audio = tf.random.uniform((3, 8000), dtype=tf.float32)
 
     loss = loss_obj(input_audio, target_audio)
 
diff --git a/ddsp/spectral_ops_test.py b/ddsp/spectral_ops_test.py
index ee40198..fd14940 100644
--- a/ddsp/spectral_ops_test.py
+++ b/ddsp/spectral_ops_test.py
@@ -40,6 +40,25 @@ class STFTTest(tf.test.TestCase):
     self.assertAllClose(np.abs(s_np), np.abs(s_tf), rtol=1e-3, atol=1e-3)
 
 
+class DiffTest(tf.test.TestCase):
+
+  def test_shape_is_correct(self):
+    n_batch = 2
+    n_time = 125
+    n_freq = 100
+    mag = tf.ones([n_batch, n_time, n_freq])
+
+    diff = spectral_ops.diff
+    delta_t = diff(mag, axis=1)
+    self.assertEqual(delta_t.shape[1], mag.shape[1]-1)
+    delta_delta_t = diff(delta_t, axis=1)
+    self.assertEqual(delta_delta_t.shape[1], mag.shape[1]-2)
+    delta_f = diff(mag, axis=2)
+    self.assertEqual(delta_f.shape[2], mag.shape[2]-1)
+    delta_delta_f = diff(delta_f, axis=2)
+    self.assertEqual(delta_delta_f.shape[2], mag.shape[2]-2)
+
+
 class LoudnessTest(tf.test.TestCase):
 
   def test_tf_and_np_are_consistent(self):