As a first experiment, I will try to predict the next acoustic sample given a specific number of previous samples. A feedforward neural network (NN) with one hidden layer will be used to perform this task. You will find all my scripts under this repository to generate the dataset (generate_dataset.py) and train a NN (mlp.py).
The work that I will present is mainly inspired by Hubert‘s first experiment and will confirm his results. Please forgive me if everything is not very clean or if it is hard-coded in some places. I never used Theano before and I wanted to give it a try quickly! Please feel free to ask me questions or point out mistakes that I would have made.
Main ideas
I started to code from the script provided in the Theano tutorial for MNIST classification using a NN (here). The NN that I implemented is pretty much the same since they are both NN with one hidden layer.
Nevertheless, there are several differences between my NN and the NN of that tutorial:
- The activation function of the output layer is linear instead of a softmax.
- The output is a real number instead of an integer.
- At the end we only get one unit output (
) instead of 10.
- The error function corresponds to the quadratic error (
where
is the size of the mini-batch) instead of the log-likelihood.
I also used Hubert’s script to generate the dataset. However, the way that he saved the data doesn’t correspond to the input format of the Theano tutorial I mentioned above. That is why I modified his script to save the dataset in a .pkl file à la MNIST with a matrix for the previous samples and a vector for the next samples to predict.
Practical implementation
Generate a .pkl .npz file
Similar to Hubert, I chose the very first subject of the first dialect, in /DR1/FCJF0/. It contains 10 sentences. You will find my script here.
The first nine sentences were split into frames of 241 samples. Remember that 240 samples correspond to 15 ms since the .wav files are samples at 16kHz. The 241th sample is used for prediction given the previous 240 samples. This results in a
matrix plus a vector that contains the sample that we want to predict. Next I randomly shuffled this big matrix and saved 50% for training, 25% for validation and 25% for testing.
What about the tenth sentence? I used it separately since I didn’t want to randomize it for two purposes: reconstruction and generation. The former consists of a window of a fixed size that moves across the tenth sentence to predict the next sample at each iteration. The latter uses the prediction of the next sample as an input for the next moving window.
Another very important thing is the normalization as David Belius pointed out. As he suggested, I just divided all the samples by 560 which corresponds to the standard deviation.
Load the data
Use the load_data2() function if you also want to keep apart one sentence. In that case, the .pkl file will contain 4 datasets instead of 3 (train_set, valid_set, test_set, sentence). If you don’t, just use load_data() like the tutorial. Note that I worked in float64. (Go to utils.py to get the functions)
Hyperparameters and others
- Learning rate = 0.01
- Minibatch size = 20
- Number of epochs = 100
- Number of hidden units = 10
- L2 regularization parameter = 0.0001
- tanh() activation function for the hidden layer
- Linear activation for the output layer
Results
Here is the learning curve:
After roughly 30 epochs, both errors only vary slightly…
Speech reconstruction
As I explained above, I tried to reconstruct the 10th sentence. On a practical note, I generated a matrix of
that contains overlapping windows of that sentence and I tried to predict the next value.

It seems that the results look a lot like what Benjamin has. I plotted the acoustic in the same manner as he did (go to affiche.py in my repo).
Speech synthesis
The biggest challenge is to generate a whole sentence from an initial set of 240 samples. I began arbitrarily at the index 2500 and tried to generate the next 30000 samples. At each iteration the window of samples used for prediction is shifted in order to add the previous predicted value.

Generation of the acoustic based on a NN trained for 5 epochs

Generation of the acoustic based on a NN trained for 100 epochs
The results are similar to those obtained by Hubert in his first experiment (a combination of sine waves). However, it is strange that after training the NN for 100 epochs, the generation of the acoustic leads to 0 values.
Next steps
One major drawback of this method is that we have to generate a dataset. For example, the size of the .pkl file was over 700 mo and it only contains 10 sentences… I didn’t try to zip it, but even though that is a lot compared to the 10 raw .npy (or .wav) files that only weight 1 mo in total. There should be a smarter way to run the data through the NN since the information is redondant. As we discussed in class, this issue is important if we want to train on the whole dataset.
I didn’t really look for better hyperparameters. The small changes that I tried (e.g. having more hidden units) lead to the same results.
For the next days, I will try to include the phonemes in the model and I will also try to implement a more complex architecture.
EDIT (Feb 25): For those who want to try out my scripts. I made a few changes since the first commit (Feb 18). I created a utils.py script in which you can find the functions to load the datasets. I also implemented in my main script (mlp.py) functions to save and load the parameters of the best model.
EDIT (March 3rd): The dataset for training is now in a .npz format instead of .pkl.
You must be logged in to post a comment.