DeepLearning.ai深度学习课程笔记
  • Introduction
  • 第一门课 神经网络和深度学习(Neural-Networks-and-Deep-Learning)
    • 第一周:深度学习引言(Introduction to Deep Learning)
      • 1.1 神经网络的监督学习(Supervised Learning with Neural Networks)
      • 1.2 为什么神经网络会流行?(Why is Deep Learning taking off?)
    • 第二周:神经网络的编程基础(Basics of Neural Network programming)
      • 2.1 二分类(Binary Classification)
      • 2.2 逻辑回归(Logistic Regression)
      • 2.3 逻辑回归的代价函数(Logistic Regression Cost Function)
      • 2.4 逻辑回归的梯度下降(Logistic Regression Gradient Descent)
      • 2.5 梯度下降的例子(Gradient Descent on m Examples)
      • 2.6 向量化 logistic 回归的梯度输出(Vectorizing Logistic Regression’s Gradient Output)
      • 2.7 (选修)logistic 损失函数的解释(Explanation of logistic regression cost function )
      • Logistic Regression with a Neural Network mindset 代码
      • lr_utils.py
    • 第三周:浅层神经网络(Shallow neural networks)
      • 3.1 神经网络概述(Neural Network Overview)
      • 3.2 神经网络的表示(Neural Network Representation )
      • 3.3 计算一个神经网络的输出(Computing a Neural Network's output )
      • 3.4 多样本向量化(Vectorizing across multiple examples )
      • 3.5 激活函数(Activation functions)
      • 3.6 为什么需要( 非线性激活函数?(why need a nonlinear activation function?)
      • 3.7 激活函数的导数(Derivatives of activation functions )
      • 3.8 神经网络的梯度下降(Gradient descent for neural networks)
      • 3.9 (选修)直观理解反向传播(Backpropagation intuition )
      • 3.10 随机初始化(Random+Initialization)
      • Planar data classification with one hidden layer
      • planar_utils.py
      • testCases.py
    • 第四周:深层神经网络(Deep Neural Networks)
      • 4.1 深层神经网络(Deep L-layer neural network)
      • 4.2 前向传播和反向传播(Forward and backward propagation)
      • 4.3 深层网络中的前向传播(Forward propagation in a Deep Network )
      • 4.4 为什么使用深层表示?(Why deep representations?)
      • 4.5 搭建神经网络块(Building blocks of deep neural networks)
      • 4.6 参数 VS 超参数(Parameters vs Hyperparameters)
      • Building your Deep Neural Network Step by Step
      • dnn_utils.py
      • testCases.py
      • Deep Neural Network Application
      • dnn_app_utils.py
  • 第二门课 改善深层神经网络:超参数调试、 正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regulariza
    • 第二门课 改善深层神经网络:超参数调试、正则化以及优化(Improving Deep Neural Networks:Hyperparameter tuning, Regularization and
      • 第一周:深度学习的实用层面(Practical aspects of Deep Learning)
        • 1.1 训练,验证,测试集(Train / Dev / Test sets)
        • 1.2 偏差,方差(Bias /Variance)
        • 1.3 机器学习基础(Basic Recipe for Machine Learning)
        • 1.4 正则化(Regularization)
        • 1.5 为什么正则化有利于预防过拟合呢?(Why regularization reduces overfitting?)
        • 1.6 dropout 正则化(Dropout Regularization)
        • 1.7 理解 dropout(Understanding Dropout)
        • 1.8 其他正则化方法(Other regularization methods)
        • 1.9 归一化输入(Normalizing inputs)
        • 1.10 梯度消失/梯度爆炸(Vanishing / Exploding gradients)
        • 1.11 神经网络的权重初始化(Weight Initialization for Deep Networks)
        • 1.12 梯度的数值逼近(Numerical approximation of gradients)
        • 1.13 梯度检验(Gradient checking)
        • 1.14 梯度检验应用的注意事项(Gradient Checking Implementation Notes)
        • Initialization
        • Gradient Checking
        • Regularization
        • reg_utils.py
        • testCases.py
      • 第二周:优化算法 (Optimization algorithms)
        • 2.1 Mini-batch 梯度下降(Mini-batch gradient descent)
        • 2.2 理解 mini-batch 梯度下降法(Understanding mini-batch gradient descent)
        • 2.3 指数加权平均数(Exponentially weighted averages)
        • 2.4 理解指数加权平均数(Understanding exponentially weighted averages )
        • 2.5 指 数 加 权 平 均 的 偏 差 修 正 ( Bias correction in exponentially weighted averages )
        • 2.6 动量梯度下降法(Gradient descent with Momentum )
        • 2.7 RMSprop( root mean square prop)
        • 2.8 Adam 优化算法(Adam optimization algorithm)
        • 2.9 学习率衰减(Learning rate decay)
        • 2.10 局部最优的问题(The problem of local optima)
        • Optimization
        • opt_utils.py
        • testCases.py
      • 第 三 周 超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架 (Hyperparameter tuning)
        • 3.1 调试处理(Tuning process)
        • 3.2 为超参数选择合适的范围(Using an appropriate scale to pick hyperparameters)
        • 3.3 超参数训练的实践: Pandas VS Caviar(Hyperparameters tuning in practice: Pandas vs. Caviar)
        • 3.4 归一化网络的激活函数( Normalizing activations in a network)
        • 3.5 将 Batch Norm 拟合进神经网络(Fitting Batch Norm into a neural network)
        • 3.6 Batch Norm 为什么奏效?(Why does Batch Norm work?)
        • 3.7 测试时的 Batch Norm(Batch Norm at test time)
        • 3.8 Softmax 回归(Softmax regression)
        • 3.9 训练一个 Softmax 分类器(Training a Softmax classifier)
        • tensorflow tutorial
        • improv_utils.py
        • tf_utils.py
  • 第三门课 结构化机器学习项目(Structuring Machine Learning Projects)
    • 第三门课 结构化机器学习项目(Structuring Machine Learning Projects)
      • 第一周 机器学习(ML)策略(1)(ML strategy(1))
        • 1.1 为什么是 ML 策略?(Why ML Strategy?)
        • 1.2 正交化(Orthogonalization)
        • 1.3 单一数字评估指标(Single number evaluation metric)
        • 1.4 满足和优化指标(Satisficing and optimizing metrics)
        • 1.5 训练/开发/测试集划分(Train/dev/test distributions)
        • 1.6 开发集和测试集的大小(Size of dev and test sets)
        • 1.7 什么时候该改变开发/测试集和指标?(When to change dev/test sets and metrics)
        • 1.8 为什么是人的表现?( Why human-level performance?)
        • 1.9 可避免偏差(Avoidable bias)
        • 1.10 理解人的表现(Understanding human-level performance)
        • 1.11 超过人的表现(Surpassing human- level performance)
        • 1.12 改善你的模型的表现(Improving your model performance)
      • 第二周:机器学习策略(2)(ML Strategy (2))
        • 2.1 进行误差分析(Carrying out error analysis)
        • 2.2 清楚标注错误的数据(Cleaning up Incorrectly labeled data)
        • 2.3 快速搭建你的第一个系统,并进行迭代(Build your first system quickly, then iterate)
        • 2.4 在不同的划分上进行训练并测试(Training and testing on different distributions)
        • 2.5 不匹配数据划分的偏差和方差(Bias and Variance with mismatched data distributions)
        • 2.6 定位数据不匹配(Addressing data mismatch)
        • 2.7 迁移学习(Transfer learning)
        • 2.8 多任务学习(Multi-task learning)
        • 2.9 什么是端到端的深度学习?(What is end-to-end deep learning?)
        • 2.10 是否要使用端到端的深度学习?(Whether to use end-to-end learning?)
  • 第四门课 卷积神经网络(Convolutional Neural Networks)
    • 第四门课 卷积神经网络(Convolutional Neural Networks)
      • 第一周 卷积神经网络(Foundations of Convolutional Neural Networks)
        • 1.1 计算机视觉(Computer vision)
        • 1.2 边缘检测示例(Edge detection example)
        • 1.3 更多边缘检测内容(More edge detection)
        • 1.4 Padding
        • 1.5 卷积步长(Strided convolutions)
        • 1.6 三维卷积(Convolutions over volumes)
        • 1.7 单层卷积网络(One layer of a convolutional network)
        • 1.8 简单卷积网络示例(A simple convolution network example)
        • 1.9 池化层(Pooling layers)
        • 1.10 卷积神经网络示例(Convolutional neural network example)
        • 1.11 为什么使用卷积?(Why convolutions?)
        • Convolution model Step by Step
        • Convolutional Neural Networks: Application
        • cnn_utils
      • 第二周 深度卷积网络:实例探究(Deep convolutional models: case studies)
        • 2.1 经典网络(Classic networks)
        • 2.2 残差网络(Residual Networks (ResNets))
        • 2.3 残差网络为什么有用?(Why ResNets work?)
        • 2.4 网络中的网络以及 1×1 卷积(Network in Network and 1×1 convolutions)
        • 2.5 谷歌 Inception 网络简介(Inception network motivation)
        • 2.6 Inception 网络(Inception network)
        • 2.7 迁移学习(Transfer Learning)
        • 2.8 数据扩充(Data augmentation)
        • 2.9 计算机视觉现状(The state of computer vision)
        • Residual Networks
        • Keras tutorial - the Happy House
        • kt_utils.py
      • 第三周 目标检测(Object detection)
        • 3.1 目标定位(Object localization)
        • 3.2 特征点检测(Landmark detection)
        • 3.3 目标检测(Object detection)
        • 3.4 卷积的滑动窗口实现(Convolutional implementation of sliding windows)
        • 3.5 Bounding Box预测(Bounding box predictions)
        • 3.6 交并比(Intersection over union)
        • 3.7 非极大值抑制(Non-max suppression)
        • 3.8 Anchor Boxes
        • 3.9 YOLO 算法(Putting it together: YOLO algorithm)
        • 3.10 候选区域(选修)(Region proposals (Optional))
        • Autonomous driving application - Car detection
        • yolo_utils.py
      • 第四周 特殊应用:人脸识别和神经风格转换(Special applications: Face recognition &Neural style transfer)
        • 4.1 什么是人脸识别?(What is face recognition?)
        • 4.2 One-Shot学习(One-shot learning)
        • 4.3 Siamese 网络(Siamese network)
        • 4.4 Triplet 损失(Triplet 损失)
        • 4.5 面部验证与二分类(Face verification and binary classification)
        • 4.6 什么是深度卷积网络?(What are deep ConvNets learning?)
        • 4.7 代价函数(Cost function)
        • 4.8 内容代价函数(Content cost function)
        • 4.9 风格代价函数(Style cost function)
        • 4.10 一维到三维推广(1D and 3D generalizations of models)
        • Art Generation with Neural Style Transfer
        • nst_utils.py
        • Face Recognition for the Happy House
        • fr_utils.py
        • inception_blocks.py
  • 第五门课 序列模型(Sequence Models)
    • 第五门课 序列模型(Sequence Models)
      • 第一周 循环序列模型(Recurrent Neural Networks)
        • 1.1 为什么选择序列模型?(Why Sequence Models?)
        • 1.2 数学符号(Notation)
        • 1.3 循环神经网络模型(Recurrent Neural Network Model)
        • 1.4 通过时间的反向传播(Backpropagation through time)
        • 1.5 不同类型的循环神经网络(Different types of RNNs)
        • 1.6 语言模型和序列生成(Language model and sequence generation)
        • 1.7 对新序列采样(Sampling novel sequences)
        • 1.8 循环神经网络的梯度消失(Vanishing gradients with RNNs)
        • 1.9 GRU单元(Gated Recurrent Unit(GRU))
        • 1.10 长短期记忆(LSTM(long short term memory)unit)
        • 1.11 双向循环神经网络(Bidirectional RNN)
        • 1.12 深层循环神经网络(Deep RNNs)
        • Building your Recurrent Neural Network
        • rnn_utils.py
        • Dinosaurus Island -- Character level language model final
        • utils.py
        • shakespeare_utils.py
        • Improvise a Jazz Solo with an LSTM Network
      • 第二周 自然语言处理与词嵌入(Natural Language Processing and Word Embeddings)
        • 2.1 词汇表征(Word Representation)
        • 2.2 使用词嵌入(Using Word Embeddings)
        • 2.3 词嵌入的特性(Properties of Word Embeddings)
        • 2.4 嵌入矩阵(Embedding Matrix)
        • 2.5 学习词嵌入(Learning Word Embeddings)
        • 2.6 Word2Vec
        • 2.7 负采样(Negative Sampling)
        • 2.8 GloVe 词向量(GloVe Word Vectors)
        • 2.9 情感分类(Sentiment Classification)
        • 2.10 词嵌入除偏(Debiasing Word Embeddings)
        • Operations on word vectors
        • w2v_utils.py
        • Emojify
        • emo_utils.py
      • 第三周 序列模型和注意力机制(Sequence models & Attention mechanism)
        • 3.1 基础模型(Basic Models)
        • 3.2 选择最可能的句子(Picking the most likely sentence)
        • 3.3 集束搜索(Beam Search)
        • 3.4 改进集束搜索(Refinements to Beam Search)
        • 3.5 集束搜索的误差分析(Error analysis in beam search)
        • 3.6 Bleu 得分(选修)(Bleu Score (optional))
        • 3.7 注意力模型直观理解(Attention Model Intuition)
        • 3.8注意力模型(Attention Model)
        • 3.9语音识别(Speech recognition)
        • 3.10触发字检测(Trigger Word Detection)
        • Neural machine translation with attention
        • nmt_utils.py
        • Trigger word detection
        • td_utils.py
Powered by GitBook
On this page
  • 1 - Problem statement
  • 1.1 - Dataset
  • 1.2 - Overview of our model
  • 2 - Building the model
  • 3 - Generating music
  • Congratulations!

Was this helpful?

  1. 第五门课 序列模型(Sequence Models)
  2. 第五门课 序列模型(Sequence Models)
  3. 第一周 循环序列模型(Recurrent Neural Networks)

Improvise a Jazz Solo with an LSTM Network

Welcome to your final programming assignment of this week! In this notebook, you will implement a model that uses an LSTM to generate music. You will even be able to listen to your own music at the end of the assignment.

You will learn to:

  • Apply an LSTM to music generation.

  • Generate your own jazz music with deep learning.

Please run the following cell to load all the packages required in this assignment. This may take a few minutes.

from __future__ import print_function
import IPython
import sys
from music21 import *
import numpy as np
from grammar import *
from qa import *
from preprocess import *
from music_utils import *
from data_utils import *
from keras.models import load_model, Model
from keras.layers import Dense, Activation, Dropout, Input, LSTM, Reshape, Lambda, RepeatVector
from keras.initializers import glorot_uniform
from keras.utils import to_categorical
from keras.optimizers import Adam
from keras import backend as K

Using TensorFlow backend.

1 - Problem statement

You would like to create a jazz music piece specially for a friend's birthday. However, you don't know any instruments or music composition. Fortunately, you know deep learning and will solve this problem using an LSTM netwok.

You will train a network to generate novel jazz solos in a style representative of a body of performed work.

1.1 - Dataset

You will train your algorithm on a corpus of Jazz music. Run the cell below to listen to a snippet of the audio from the training set:

IPython.display.Audio('./data/30s_seq.mp3')

We have taken care of the preprocessing of the musical data to render it in terms of musical "values." You can informally think of each "value" as a note, which comprises a pitch and a duration. For example, if you press down a specific piano key for 0.5 seconds, then you have just played a note. In music theory, a "value" is actually more complicated than this--specifically, it also captures the information needed to play multiple notes at the same time. For example, when playing a music piece, you might press down two piano keys at the same time (playng multiple notes at the same time generates what's called a "chord"). But we don't need to worry about the details of music theory for this assignment. For the purpose of this assignment, all you need to know is that we will obtain a dataset of values, and will learn an RNN model to generate sequences of values.

Our music generation system will use 78 unique values. Run the following code to load the raw music data and preprocess it into values. This might take a few minutes.

X, Y, n_values, indices_values = load_music_utils()
print('shape of X:', X.shape)
print('number of training examples:', X.shape[0])
print('Tx (length of sequence):', X.shape[1])
print('total # of unique values:', n_values)
print('Shape of Y:', Y.shape)
shape of X: (60, 30, 78)
number of training examples: 60
Tx (length of sequence): 30
total # of unique values: 78
Shape of Y: (30, 60, 78)

You have just loaded the following:

  • X: This is an (m, TxT_xTx​, 78) dimensional array. We have m training examples, each of which is a snippet of Tx=30T_x =30Tx​=30 musical values. At each time step, the input is one of 78 different possible values, represented as a one-hot vector. Thus for example, X[i,t,:] is a one-hot vector representating the value of the i-th example at time t.

  • Y: This is essentially the same as X, but shifted one step to the left (to the past). Similar to the dinosaurus assignment, we're interested in the network using the previous values to predict the next value, so our sequence model will try to predict y⟨t⟩y^{\langle t \rangle}y⟨t⟩ given x⟨1⟩,…,x⟨t⟩x^{\langle 1\rangle}, \ldots, x^{\langle t \rangle}x⟨1⟩,…,x⟨t⟩. However, the data in Y is reordered to be dimension (Ty,m,78)(T_y, m, 78)(Ty​,m,78), where Ty=TxT_y = T_xTy​=Tx​. This format makes it more convenient to feed to the LSTM later.

  • n_values: The number of unique values in this dataset. This should be 78.

  • indices_values: python dictionary mapping from 0-77 to musical values.

1.2 - Overview of our model

Here is the architecture of the model we will use. This is similar to the Dinosaurus model you had used in the previous notebook, except that in you will be implementing it in Keras. The architecture is as follows:

Figure 1: LSTM model. X=(x⟨1⟩,x⟨2⟩,...,x⟨Tx⟩)X = (x^{\langle 1 \rangle}, x^{\langle 2 \rangle}, ..., x^{\langle T_x \rangle})X=(x⟨1⟩,x⟨2⟩,...,x⟨Tx​⟩) is a window of size TxT_xTx​ scanned over the musical corpus. Each x⟨t⟩x^{\langle t \rangle}x⟨t⟩ is an index corresponding to a value (ex: "A,0.250,< m2,P-4 >") while y^\hat{y}y^​ is the prediction for the next value

We will be training the model on random snippets of 30 values taken from a much longer piece of music. Thus, we won't bother to set the first input x⟨1⟩=0⃗x^{\langle 1 \rangle} = \vec{0}x⟨1⟩=0, which we had done previously to denote the start of a dinosaur name, since now most of these snippets of audio start somewhere in the middle of a piece of music. We are setting each of the snippts to have the same length Tx=30T_x = 30Tx​=30 to make vectorization easier.

2 - Building the model

In this part you will build and train a model that will learn musical patterns. To do so, you will need to build a model that takes in X of shape (m,Tx,78)(m, T_x, 78)(m,Tx​,78) and Y of shape (Ty,m,78)(T_y, m, 78)(Ty​,m,78). We will use an LSTM with 64 dimensional hidden states. Lets set n_a = 64.

n_a = 64

Here's how you can create a Keras model with multiple inputs and outputs. If you're building an RNN where even at test time entire input sequence x⟨1⟩,x⟨2⟩,…,x⟨Tx⟩x^{\langle 1 \rangle}, x^{\langle 2 \rangle}, \ldots, x^{\langle T_x \rangle}x⟨1⟩,x⟨2⟩,…,x⟨Tx​⟩ were given in advance, for example if the inputs were words and the output was a label, then Keras has simple built-in functions to build the model. However, for sequence generation, at test time we don't know all the values of x⟨t⟩x^{\langle t\rangle}x⟨t⟩ in advance; instead we generate them one at a time using x⟨t⟩=y⟨t−1⟩x^{\langle t\rangle} = y^{\langle t-1 \rangle}x⟨t⟩=y⟨t−1⟩. So the code will be a bit more complicated, and you'll need to implement your own for-loop to iterate over the different time steps.

The function djmodel() will call the LSTM layer TxT_xTx​ times using a for-loop, and it is important that all TxT_xTx​ copies have the same weights. I.e., it should not re-initiaiize the weights every time---the TxT_xTx​ steps should have shared weights. The key steps for implementing layers with shareable weights in Keras are: 1. Define the layer objects (we will use global variables for this). 2. Call these objects when propagating the input.

reshapor = Reshape((1, 78)) # Used in Step 2.B of djmodel(), below
LSTM_cell = LSTM(n_a, return_state = True) # Used in Step 2.C
densor = Dense(n_values, activation='softmax') # Used in Step 2.D

Each of reshapor, LSTM_cell and densor are now layer objects, and you can use them to implement djmodel(). In order to propagate a Keras tensor object X through one of these layers, use layer_object(X) (or layer_object([X,Y]) if it requires multiple inputs.). For example, reshapor(X) will propagate X through the Reshape((1,78)) layer defined above.

Exercise: Implement djmodel(). You will need to carry out 2 steps:

  1. Create an empty list "outputs" to save the outputs of the LSTM Cell at every time step.

  2. Loop for t∈1,…,Txt \in 1, \ldots, T_xt∈1,…,Tx​:

x = Lambda(lambda x: X[:,t,:])(X)

Look over the Keras documentation to figure out what this does. It is creating a "temporary" or "unnamed" function (that's what Lambda functions are) that extracts out the appropriate one-hot vector, and making this function a Keras Layer object to apply to X.

B. Reshape x to be (1,78). You may find the reshapor() layer (defined below) helpful.

C. Run x through one step of LSTM_cell. Remember to initialize the LSTM_cell with the previous step's hidden state aaa and cell state ccc. Use the following formatting:

a, _, c = LSTM_cell(input_x, initial_state=[previous hidden state, previous cell state])

D. Propagate the LSTM's output activation value through a dense+softmax layer using densor. E. Append the predicted value to the list of "outputs"

# GRADED FUNCTION: djmodel

def djmodel(Tx, n_a, n_values):
    """
    Implement the model

    Arguments:
    Tx -- length of the sequence in a corpus
    n_a -- the number of activations used in our model
    n_values -- number of unique values in the music data 

    Returns:
    model -- a keras model with the 
    """

    # Define the input of your model with a shape 
    X = Input(shape=(Tx, n_values))

    # Define s0, initial hidden state for the decoder LSTM
    a0 = Input(shape=(n_a,), name='a0')
    c0 = Input(shape=(n_a,), name='c0')
    a = a0
    c = c0

    ### START CODE HERE ### 
    # Step 1: Create empty list to append the outputs while you iterate (≈1 line)
    outputs = []

    # Step 2: Loop
    for t in range(Tx):

        # Step 2.A: select the "t"th time step vector from X. 
        x = Lambda(lambda x: X[:, t, :])(X)
        # Step 2.B: Use reshapor to reshape x to be (1, n_values) (≈1 line)
        x = reshapor(x)
        # Step 2.C: Perform one step of the LSTM_cell
        a, _, c = LSTM_cell(x, initial_state=[a, c])
        # Step 2.D: Apply densor to the hidden state output of LSTM_Cell
        out = densor(a)
        # Step 2.E: add the output to "outputs"
        outputs.append(out)

    # Step 3: Create model instance
    model = Model(inputs = [X, a0, c0], outputs = outputs)

    ### END CODE HERE ###

    return model

Run the following cell to define your model. We will use Tx=30, n_a=64 (the dimension of the LSTM activations), and n_values=78. This cell may take a few seconds to run.

model = djmodel(Tx = 30 , n_a = 64, n_values = 78)

You now need to compile your model to be trained. We will Adam and a categorical cross-entropy loss.

opt = Adam(lr=0.01, beta_1=0.9, beta_2=0.999, decay=0.01)


model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])

Finally, lets initialize a0 and c0 for the LSTM's initial state to be zero.

m = 60
a0 = np.zeros((m, n_a))
c0 = np.zeros((m, n_a))

Lets now fit the model! We will turn Y to a list before doing so, since the cost function expects Y to be provided in this format (one list item per time-step). So list(Y) is a list with 30 items, where each of the list items is of shape (60,78). Lets train for 100 epochs. This will take a few minutes.

model.fit([X, a0, c0], list(Y), epochs=100)
Epoch 1/100
60/60 [==============================] - 5s - loss: 125.9133 - dense_1_loss_1: 4.3548 -.....

....
Epoch 100/100
60/60 [==============================] - 0s - loss: 6.0665 - dense_1_loss_1: 3.7384 ....

You should see the model loss going down. Now that you have trained a model, lets go on the the final section to implement an inference algorithm, and generate some music!

3 - Generating music

You now have a trained model which has learned the patterns of the jazz soloist. Lets now use this model to synthesize new music.

3.1 - Predicting & Sampling

At each step of sampling, you will take as input the activation a and cell state c from the previous state of the LSTM, forward propagate by one step, and get a new output activation as well as cell state. The new activation a can then be used to generate the output, using densor as before.

To start off the model, we will initialize x0 as well as the LSTM activation and and cell value a0 and c0 to be zeros.

You are about to build a function that will do this inference for you. Your function takes in your previous model and the number of time steps Ty that you want to sample. It will return a keras model that would be able to generate sequences for you. Furthermore, the function takes in a dense layer of 78 units and the number of activations.

Exercise: Implement the function below to sample a sequence of musical values. Here are some of the key steps you'll need to implement inside the for-loop that generates the TyT_yTy​ output characters:

Step 2.A: Use LSTM_Cell, which inputs the previous step's c and a to generate the current step's c and a.

Step 2.B: Use densor (defined previously) to compute a softmax on a to get the output for the current step.

Step 2.C: Save the output you have just generated by appending it to outputs.

x = Lambda(one_hot)(out)

[Minor technical note: Rather than sampling a value at random according to the probabilities in out, this line of code actually chooses the single most likely note at each step using an argmax.]

# GRADED FUNCTION: music_inference_model

def music_inference_model(LSTM_cell, densor, n_values = 78, n_a = 64, Ty = 100):
    """
    Uses the trained "LSTM_cell" and "densor" from model() to generate a sequence of values.

    Arguments:
    LSTM_cell -- the trained "LSTM_cell" from model(), Keras layer object
    densor -- the trained "densor" from model(), Keras layer object
    n_values -- integer, umber of unique values
    n_a -- number of units in the LSTM_cell
    Ty -- integer, number of time steps to generate

    Returns:
    inference_model -- Keras model instance
    """

    # Define the input of your model with a shape 
    x0 = Input(shape=(1, n_values))

    # Define s0, initial hidden state for the decoder LSTM
    a0 = Input(shape=(n_a,), name='a0')
    c0 = Input(shape=(n_a,), name='c0')
    a = a0
    c = c0
    x = x0

    ### START CODE HERE ###
    # Step 1: Create an empty list of "outputs" to later store your predicted values (≈1 line)
    outputs = []

    # Step 2: Loop over Ty and generate a value at every time step
    for t in range(Ty):

        # Step 2.A: Perform one step of LSTM_cell (≈1 line)
        a, _, c = LSTM_cell(x, initial_state= [a, c])

        # Step 2.B: Apply Dense layer to the hidden state output of the LSTM_cell (≈1 line)
        out = densor(a)

        # Step 2.C: Append the prediction "out" to "outputs". out.shape = (None, 78) (≈1 line)
        outputs.append(out)

        # Step 2.D: Select the next value according to "out", and set "x" to be the one-hot representation of the
        #           selected value, which will be passed as the input to LSTM_cell on the next step. We have provided 
        #           the line of code you need to do this. 
        x = Lambda(one_hot)(out)

    # Step 3: Create model instance with the correct "inputs" and "outputs" (≈1 line)
    inference_model = Model(inputs = [x0, a0, c0], outputs = outputs)

    ### END CODE HERE ###

    return inference_model

Run the cell below to define your inference model. This model is hard coded to generate 50 values.

inference_model = music_inference_model(LSTM_cell, densor, n_values = 78, n_a = 64, Ty = 50)

Finally, this creates the zero-valued vectors you will use to initialize x and the LSTM state variables a and c.

x_initializer = np.zeros((1, 1, 78))
a_initializer = np.zeros((1, n_a))
c_initializer = np.zeros((1, n_a))
# GRADED FUNCTION: predict_and_sample

def predict_and_sample(inference_model, x_initializer = x_initializer, a_initializer = a_initializer, 
                       c_initializer = c_initializer):
    """
    Predicts the next value of values using the inference model.

    Arguments:
    inference_model -- Keras model instance for inference time
    x_initializer -- numpy array of shape (1, 1, 78), one-hot vector initializing the values generation
    a_initializer -- numpy array of shape (1, n_a), initializing the hidden state of the LSTM_cell
    c_initializer -- numpy array of shape (1, n_a), initializing the cell state of the LSTM_cel

    Returns:
    results -- numpy-array of shape (Ty, 78), matrix of one-hot vectors representing the values generated
    indices -- numpy-array of shape (Ty, 1), matrix of indices representing the values generated
    """

    ### START CODE HERE ###
    # Step 1: Use your inference model to predict an output sequence given x_initializer, a_initializer and c_initializer.
    pred = inference_model.predict([x_initializer, a_initializer, c_initializer])
    # Step 2: Convert "pred" into an np.array() of indices with the maximum probabilities
    indices = np.array(np.argmax(pred, -1))
    # Step 3: Convert indices to one-hot vectors, the shape of the results should be (1, )
    results = to_categorical(indices)
    ### END CODE HERE ###

    return results, indices
results, indices = predict_and_sample(inference_model, x_initializer, a_initializer, c_initializer)
print("np.argmax(results[12]) =", np.argmax(results[12]))
print("np.argmax(results[17]) =", np.argmax(results[17]))
print("list(indices[12:18]) =", list(indices[12:18]))
np.argmax(results[12]) = 67
np.argmax(results[17]) = 74
list(indices[12:18]) = [array([67]), array([54]), array([67]), array([56]), array([76]), array([74])]

3.3 - Generate music

Finally, you are ready to generate music. Your RNN generates a sequence of values. The following code generates music by first calling your predict_and_sample() function. These values are then post-processed into musical chords (meaning that multiple values or notes can be played at the same time).

Most computational music algorithms use some post-processing because it is difficult to generate music that sounds good without such post-processing. The post-processing does things such as clean up the generated audio by making sure the same sound is not repeated too many times, that two successive notes are not too far from each other in pitch, and so on. One could argue that a lot of these post-processing steps are hacks; also, a lot the music generation literature has also focused on hand-crafting post-processors, and a lot of the output quality depends on the quality of the post-processing and not just the quality of the RNN. But this post-processing does make a huge difference, so lets use it in our implementation as well.

Lets make some music!

Run the following cell to generate music and record it into your out_stream. This can take a couple of minutes.

out_stream = generate_music(inference_model)

To listen to your music, click File->Open... Then go to "output/" and download "my_music.midi". Either play it on your computer with an application that can read midi files if you have one, or use one of the free online "MIDI to mp3" conversion tools to convert this to mp3.

As reference, here also is a 30sec audio clip we generated using this algorithm.

IPython.display.Audio('./data/30s_trained_model.mp3')

Congratulations!

You have come to the end of the notebook.

Here's what you should remember:

  • A sequence model can be used to generate musical values, which are then post-processed into midi music.

  • Fairly similar models can be used to generate dinosaur names or to generate music, with the major difference being the input fed to the model.

  • In Keras, sequence generation involves defining layers with shared weights, which are then repeated for the different time steps 1,…,Tx1, \ldots, T_x1,…,Tx​.

Congratulations on completing this assignment and generating a jazz solo!

References

The ideas presented in this notebook came primarily from three computational music papers cited below. The implementation here also took significant inspiration and used many components from Ji-Sung Kim's github repository.

We're also grateful to François Germain for valuable feedback.

Previousshakespeare_utils.pyNext第二周 自然语言处理与词嵌入(Natural Language Processing and Word Embeddings)

Last updated 6 years ago

Was this helpful?

We have defined the layers objects you need as global variables. Please run the next cell to create them. Please check the Keras documentation to make sure you understand what these layers are: , , .

A. Select the "t"th time-step vector from X. The shape of this selection should be (78,). To do so, create a custom layer in Keras by using this line of code:

Step 2.D: Sample x to the be "out"'s one-hot version (the prediction) so that you can pass it to the next LSTM's step. We have already provided this line of code, which uses a function.

Exercise: Implement predict_and_sample(). This function takes many arguments including the inputs [x_initializer, a_initializer, c_initializer]. In order to predict the output corresponding to this input, you will need to carry-out 3 steps: 1. Use your inference model to predict an output given your set of inputs. The output pred should be a list of length TyT_yTy​ where each element is a numpy-array of shape (1, n_values). 2. Convert pred into a numpy array of TyT_yTy​ indices. Each index corresponds is computed by taking the argmax of an element of the pred list. . 3. Convert the indices into their one-hot vector representations. .

Ji-Sung Kim, 2016,

Jon Gillick, Kevin Tang and Robert Keller, 2009.

Robert Keller and David Morrison, 2007,

François Pachet, 1999,

Reshape()
LSTM()
Dense()
Lambda
Lambda
Hint
Hint
deepjazz
Learning Jazz Grammars
A Grammatical Approach to Automatic Improvisation
Surprising Harmonies