基于LSTM的爵士乐自动化创作

标签: 爵士乐  LSTM  吴恩达

本文是基于吴恩达老师《深度学习》第五课第一周练习题所做。

0.背景简介

使用LSTM模型对爵士乐进行学习训练,最终编制出一段具有爵士风格的乐曲。

导入所需的第三方库,其中所用辅助程序可点击此处下载。

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

注:达叔的程序中有 from __future__ import print_function 语句,该语句的作用是规定在使用print函数时要像python3.x一样使用print函数,即加()。

1.问题阐述

1.1数据集

音乐数据的特性不是本文的重点,只需知道我们最终会将其抽象成具有78个特征值输入RNN网络。

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)

1.2模型概览

模型的整体结构如下图所示,属于典型的LSTM网络。

2.构建模型

 本节将构建并训练用以学习音乐特性的模型,输入X的shape为(m, T_x, 78),输入Y的shape为(T_y, m, 78),LSTM的隐层状态维度为64

n_a = 64

使用keras中的layer组件构建必要的层对象:

reshapor = Reshape((1, 78))
LSTM_cell = LSTM(n_a, return_state = True)
densor = Dense(n_values, activation = 'softmax')

模型函数如下:

def djmodel(Tx, n_a, n_values):

    X = Input(shape=(Tx, n_values))

    a0 = Input(shape=(n_a,), name='a0')
    c0 = Input(shape=(n_a,), name='c0')
    a = a0
    c = c0

    outputs = []

    for t in range(Tx):

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

        x = reshapor(x)

        a, _, c = LSTM_cell(x, initial_state=[a,c])

        out = densor(a)

        outputs.append(out)

    model = Model(inputs = [X, a0, c0], outputs=outputs)

    return model

 定义model、优化方法opt,并编译。

model = djmodel(Tx = 30, n_a = 64, n_values = 78)
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'])

定义输入个数、初始化a0和c0

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

迭代100次得到loss的返回值

model.fit([X, a0, c0], list(Y), epochs=100)
Epoch 1/100
60/60 [==============================] - 7s - loss: 125.8611 - dense_1_loss_1: 4.3548 - dense_1_loss_2: 4.3569 - dense_1_loss_3: 4.3485 - dense_1_loss_4: 4.3469 - dense_1_loss_5: 4.3461 - dense_1_loss_6: 4.3449 - dense_1_loss_7: 4.3488 - dense_1_loss_8: 4.3302 - dense_1_loss_9: 4.3440 - dense_1_loss_10: 4.3383 - dense_1_loss_11: 4.3373 - dense_1_loss_12: 4.3388 - dense_1_loss_13: 4.3367 - dense_1_loss_14: 4.3348 - dense_1_loss_15: 4.3427 - dense_1_loss_16: 4.3351 - dense_1_loss_17: 4.3400 - dense_1_loss_18: 4.3313 - dense_1_loss_19: 4.3298 - dense_1_loss_20: 4.3462 - dense_1_loss_21: 4.3411 - dense_1_loss_22: 4.3325 - dense_1_loss_23: 4.3345 - dense_1_loss_24: 4.3291 - dense_1_loss_25: 4.3432 - dense_1_loss_26: 4.3320 - dense_1_loss_27: 4.3383 - dense_1_loss_28: 4.3449 - dense_1_loss_29: 4.3333 - dense_1_loss_30: 0.0000e+00 - dense_1_acc_1: 0.0000e+00 - dense_1_acc_2: 0.0500 - dense_1_acc_3: 0.0500 - dense_1_acc_4: 0.0833 - dense_1_acc_5: 0.0333 - dense_1_acc_6: 0.0500 - dense_1_acc_7: 0.0333 - dense_1_acc_8: 0.1500 - dense_1_acc_9: 0.0500 - dense_1_acc_10: 0.0833 - dense_1_acc_11: 0.1000 - dense_1_acc_12: 0.0667 - dense_1_acc_13: 0.1000 - dense_1_acc_14: 0.1333 - dense_1_acc_15: 0.0667 - dense_1_acc_16: 0.0500 - dense_1_acc_17: 0.0500 - dense_1_acc_18: 0.0667 - dense_1_acc_19: 0.0333 - dense_1_acc_20: 0.0500 - dense_1_acc_21: 0.0167 - dense_1_acc_22: 0.1167 - dense_1_acc_23: 0.0500 - dense_1_acc_24: 0.0500 - dense_1_acc_25: 0.1000 - dense_1_acc_26: 0.0500 - dense_1_acc_27: 0.0500 - dense_1_acc_28: 0.0167 - dense_1_acc_29: 0.0833 - dense_1_acc_30: 0.0000e+00                                                                     
Epoch 2/100
60/60 [==============================] - 0s - loss: 121.9889 - dense_1_loss_1: 4.3332 - dense_1_loss_2: 4.3157 - dense_1_loss_3: 4.2876 - dense_1_loss_4: 4.2830 - dense_1_loss_5: 4.2551 - dense_1_loss_6: 4.2606 - dense_1_loss_7: 4.2598 - dense_1_loss_8: 4.2126 - dense_1_loss_9: 4.2354 - dense_1_loss_10: 4.2240 - dense_1_loss_11: 4.1925 - dense_1_loss_12: 4.2316 - dense_1_loss_13: 4.1935 - dense_1_loss_14: 4.1858 - dense_1_loss_15: 4.1724 - dense_1_loss_16: 4.1725 - dense_1_loss_17: 4.1944 - dense_1_loss_18: 4.1905 - dense_1_loss_19: 4.1251 - dense_1_loss_20: 4.2314 - dense_1_loss_21: 4.1897 - dense_1_loss_22: 4.1183 - dense_1_loss_23: 4.1488 - dense_1_loss_24: 4.1708 - dense_1_loss_25: 4.2241 - dense_1_loss_26: 4.0790 - dense_1_loss_27: 4.1207 - dense_1_loss_28: 4.1732 - dense_1_loss_29: 4.2077 - dense_1_loss_30: 0.0000e+00 - dense_1_acc_1: 0.0333 - dense_1_acc_2: 0.1000 - dense_1_acc_3: 0.1167 - dense_1_acc_4: 0.2167 - dense_1_acc_5: 0.2167 - dense_1_acc_6: 0.0667 - dense_1_acc_7: 0.0833 - dense_1_acc_8: 0.2000 - dense_1_acc_9: 0.1167 - dense_1_acc_10: 0.1500 - dense_1_acc_11: 0.1333 - dense_1_acc_12: 0.0833 - dense_1_acc_13: 0.1667 - dense_1_acc_14: 0.1333 - dense_1_acc_15: 0.1167 - dense_1_acc_16: 0.0833 - dense_1_acc_17: 0.0500 - dense_1_acc_18: 0.1167 - dense_1_acc_19: 0.1000 - dense_1_acc_20: 0.0333 - dense_1_acc_21: 0.0667 - dense_1_acc_22: 0.1333 - dense_1_acc_23: 0.1167 - dense_1_acc_24: 0.0667 - dense_1_acc_25: 0.0500 - dense_1_acc_26: 0.1000 - dense_1_acc_27: 0.1000 - dense_1_acc_28: 0.1000 - dense_1_acc_29: 0.0333 - dense_1_acc_30: 0.0000e+00             
Epoch 3/100
---

3.生成音乐

3.1预测及采样

在本人上一篇文章中对采样的过程有详细的介绍,在此不再赘述。

模型前向传播的函数如下

def music_inference_model(LSTM_cell, densor, n_values = 78, n_a = 64, Ty = 100):

    x0 = Input(shape=(1, n_values))

    a0 = Input(shape=(n_a,), name='a0')
    c0 = Input(shape=(n_a,), name='c0')
    a = a0
    c = c0
    x = x0

    outputs = []

    for t in range(Ty):

        a, _, c = LSTM_cell(x, initial_state=[a, c])
        out = densor(a)
        outputs.append(out)
        x = Lambda(one_hot)(out)

    inference_model = Model(inputs=[x0, a0, c0], outputs=outputs)

    return inference_model

运行模型并初始化x,a,c

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

x_initializer = np.zeros((1,1,78))
a_initializer = np.zeros((1, n_a))
c_initializer = np.zeros((1, n_a))

 预测及采样函数为

def predict_and_sample(inference_model, x_initializer = x_initializer,
                       a_initializer = a_initializer, c_initializer = c_initializer):

    pred = inference_model.predict([x_initializer, a_initializer, c_initializer])
    indices = np.argmax(pred, axis=-1)
    results = to_categorical(indices, num_classes=x_initializer.shape[-1])

    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]) = 62
np.argmax(results[17]) = 63
list(indices[12:18]) = [array([62], dtype=int64), array([63], dtype=int64), array([0], dtype=int64), array([50], dtype=int64), array([62], dtype=int64), array([63], dtype=int64)]

3.3生成爵士乐

运行上述的模型,并将生成的爵士乐片段保持在out_stream中

out_stream = generate_music(inference_model) 
Predicting new values for different set of chords.
Generated 51 sounds using the predicted values for the set of chords ("1") and after pruning
Generated 51 sounds using the predicted values for the set of chords ("2") and after pruning
Generated 51 sounds using the predicted values for the set of chords ("3") and after pruning
Generated 51 sounds using the predicted values for the set of chords ("4") and after pruning
Generated 51 sounds using the predicted values for the set of chords ("5") and after pruning
Your generated music is saved in output/my_music.midi

至此一个完成的自动化创作爵士乐模型便构建完成了,赶快在你的output文件夹下找出该音乐好好欣赏一下吧。

版权声明:本文为u013093426原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013093426/article/details/82390386

智能推荐

Linux搭建LAMP,源码安装

Linux搭建LAMP,源码安装 LAMP是Linux Apache MySQL PHP的简写,即把Apache、MySQL以及PHP安装在Linux系统上,组成一个环境来运行PHP的脚本语言,通常是网站。Apache 是最常用的Web服务软件,而MySQL是比较小型的数据库软件,这两个软件以及PHP都可以安装到Windows的机器上。 我们可以把Apache+PHP安装在一台机器上,再把MySQ...

模拟按键 —— 鼠标

背景 之前写自动化脚本的时候总是遇到一些很尴尬的问题: 跑脚本时模拟鼠标按键时,光标是真实的跑到了那个位置的,也就是说跑脚本的时候会很影响电脑的正常使用,导致不得不开一个虚拟机专门跑。 另外因为光标只有一个所以很难实现多线程去同时操作多个窗口,当线程1 模拟鼠标但还没有结束时,线程2 已经开始执行模拟操作,这就导致了线程1 的模拟操作被终止了,被迫之下只能开多个虚拟机(但实在太占用性能🙄) 解决...

Hibernate学习总结(一)

一、Hibernate简介 一个持久层的ORM框架。ORM:Object Relational Mapping(对象关系映射)。指的是将一个Java中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可以操作数据库中的表。 二、Hibernate入门 1、创建一个项目,引入jar包 hibernate用到的jar包 2、创建表 3、创建实体类 4、创建映射(*****) 映射需要通过XML...

Linux系统NFS

文章目录 1. nfs简介 1.1 nfs特点 1.2 使用nfs的好处 1.3 nfs的体系组成 1.4 nfs的应用场景 2. nfs工作机制 2.1 RPC 2.2 NIS 2.3 nfs工作机制 3. exports文件的格式 4. nfs管理 5. 作业 5.1手动搭建一个nfs服务器 5.1.1开放/nfs/shared目录,供所有用户查阅资料 5.1.2 开放/nfs/upload目...

关于java中String,StringBuffer,StringBuilder的区别以及StringBuffer,StringBuilder的安全性问题

这里的结果就是正确的然后我们来看他的append方法 它在前边加了一个synchronized来修饰,相当于同时只能有一个线程来访问他,这样就不会产生上边的问题但同时他的效率也就比StringBuilder低,...

猜你喜欢

Django连接现有mysql数据库

1、打开cmd后cd到项目位置 2、建立项目 django-admin startproject test2 3、编辑项目中的配置文件, mysite/settings.py ,告诉Django你的数据库连接参数和数据库名。具体的说,要提供 DATABASE_NAME , DATABASE_ENGINE , DATAB...

ShareSDK新浪微博登录时报错error:redirect_uri_mismatch

今天用 ShareSDK 做第三方登录的时候碰到个问题,明明在微博平台的应用审核已经通过了,但是调用登录接口的时候一直报错,错误如下: 出现这个错误是因为在微博开放平台上没有设置回调地址,或者设置的回调地址与本地XML中的地址不一致。 在sharesdk.xml文件当中对于微博的设置: 其中RedirectUrl为设置的回调地址,这里的地址必须要与微博开发平台设置的地址相同,否则就会出现上面的错误...

python解析网络封包方法

2019独角兽企业重金招聘Python工程师标准>>> 在使用Python解析网络数据包时,使用网络字节序解析,参见下表。 C语言的数据类型和Python的数据类型对照表请参见下表。 接下来对封包与解包进行举例说明。 version type id content unsigned short unsigned short unsigned int unsigned int 封包...

python3:时间方法,异常处理,系统文件相关模块(os)

文章目录 时间方法 time模块 时间表示方法: time模块的方法 datetime模块 异常处理 触发异常 创建mydiv.py脚本,要求如下: 创建myerror.py脚本,要求如下: os模块 实现ls -R(os.walk) os.path pickle模块 记账脚本 时间方法 time模块 时间表示方法: 时间戳:自1970-1-1 0:00:00到某一时间点之间的秒数 UTC时间:世...

负载均衡群集——LVS+DR模型

一、实验组成 调度器 192.168.100:41 web1 192.168.100:42 web2 192.168.100.43 NFS共享服务器 192.168.100.44 二、实验拓扑 三、实验配置 3.1在调度器配置:192.168.100.41 配置虚拟IP地址(VIP) 调整/proc响应参数 对于 DR 群集模式来说,由于 LVS 负载调度器和各节点需要共用 VIP 地址,应该关闭...