项目笔记(三)实验——尝试用循环卷积神经网络实现midi交响乐乐句分割
零、写在前面
现在来看,这是一次失败的实验,因为突然有新的想法,就先搁置下。但在开始新实验前,暂且先把失败的这个记录下来。
为了使用seq2seq模型进行“交响乐翻译”, 需要以乐句为单位的输入。人为标注效率太低,所以要做一个自动实现乐句分割的功能。
一、原理
这一神经网络的灵感来自trigger word detection,它将音频的频谱图输入至循环神经网络作为x,而y是1或者0:在触发词结束瞬间之后的n=50个时间步内y为1,其余为0。
神经网络的结构是这样的:最底层是对频谱图的1维卷积(可视为卷积核的高等于总高的卷积,即没有卷积核的换行),卷积后的结果输入至两层GRU循环神经网络。最后的输出因为目标y为0或1,所以使用sigmoid函数作为激活函数。
在本实验中,神经网络的架构基本不变,只是输出替换为交响乐midi文件的piano_roll(取消了乐器的标注,合并所有乐器在一个piano_roll矩阵中)。piano_roll是一个二位矩阵,两个维度分别为时间和音高。时间的单位为0.01,音高在0-128之间。矩阵每个位置上的数值代表了该音符的力度。
输出与之前的触发词检测类似,是手工标注的一维01数列,这里n=20。作为初步实验,只是用一首midi文件(贝多芬第七交响曲第四乐章)作为训练集。
另外,为了方便处理midi文件,我用了python的pretty_midi库。
二、代码
引入库文件:
import numpy as np
import pretty_midi
import matplotlib.pyplot as plt
import keras
处理输入与输出
file_name = 'Symphonie7_Opus92_Mvt4.mid'
pm = pretty_midi.PrettyMIDI(file_name)
piano_roll = pm.get_piano_roll()Tx = 52103 #输入的时间维度最大长度
n_pitch = 128 #输入的音高维度最高音高
Ty = 13023 #输出的时间步维度长度(因为卷积操作,所以Tx不等于Ty)x = np.zeros(shape=(128,52103)) #52103:取决于midi文件的长度
x[:,:]=piano_roll
x=np.transpose(x)
X=np.zeros((1,52103,128))
X[0,:,:] = xy = np.zeros((1,Ty ))
ends_s = [1,2,9,15,17,19,22,25,29,32,35,37,42,46,48,53,55,64,67,74,77,83,86,89,93,98,107,114,117,120,123,126,129,133,136,138,143,147,150,153,156,165,168,178,183,187,190,194,199,208,215,217,221,226,234,240,247,254,258,270,291,310,313,319,337,342,349,353,355,360,370,374,379,382,389,398,438,421,424,427,431,434,438,471,480,495,505,509] # 手工标注的分割点,以秒为单位for end_s in ends_s:end_ms= 100*end_sy = insert_ones(y,end_ms)y=np.transpose(y)
Y = np.zeros((1,Ty,1))
Y[0]=y
插入在0中插入1:
def insert_ones(y, segment_end_ms):segment_end_y = int((segment_end_ms-15)/4) # 卷积核大小=15, 步长=4for i in range(segment_end_y+1, segment_end_y+21):if i < Ty:y[0, i] = 1.0return y
用Keras搭建神经网络,model函数如下:
def model(input_shape):X_input = keras.Input(shape = input_shape)# CONV layerX = keras.layers.convolutional.Conv1D(196, 15, strides=4)(X_input) X = keras.layers.normalization.BatchNormalization()(X) X = keras.layers.Activation('relu')(X) X = keras.layers.Dropout(0.8)(X) # First GRU Layer X = keras.layers.GRU(units = 128, return_sequences = True)(X) X = keras.layers.Dropout(0.8)(X) X = keras.layers.BatchNormalization()(X) # Second GRU LayerX = keras.layers.GRU(units = 128, return_sequences = True)(X) X = keras.layers.Dropout(0.8)(X) X = keras.layers.BatchNormalization()(X) X = keras.layers.Dropout(0.8)(X) # Time-distributed dense layerX = keras.layers.wrappers.TimeDistributed(keras.layers.core.Dense(1, activation = "sigmoid"))(X)model = keras.Model(inputs = X_input, outputs = X)return model
编译、创建、训练神经网络:
model = model(input_shape=(Tx, n_pitch))
opt = keras.optimizers.Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, decay=0.01)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=["accuracy"])model.fit(X, Y, batch_size = 1, epochs=1000) #为了验证可行性,循环数设为1000,会导致很强的过拟合model.save('my_model_1000.h5')
plt.plot( predictions[0, :, 0] )
plt.ylabel( 'probability' )
plt.show()
三、结果
循环数为1时,训练集准确率在0.5左右。循环1000次后,训练集准确率稳定在0.56。
循环数为1时,神经网络对训练样本的预测:
循环数为1000时,神经网络的预测:
循环数为2时,神经网络的预测,同时也画上了目标y,前2000个时间步:
四、分析
我们看到,一部分的分割点还是被预测出来了,但是其余的效果并不好。
分析可能的原因有:
- 在标注y时,以整秒为单位,并且标注之前并没有进行曲式分析,导致分割标准不一致。
- 训练样本太少。
- 没有进行移调训练,泛化能力太弱。
- 没有乐器的区分,把所有乐器混合到一个piano_roll中了。
项目笔记(三)实验——尝试用循环卷积神经网络实现midi交响乐乐句分割相关推荐
- cocos2dx打飞机项目笔记三:HeroLayer类和坐标系
HeroLayer类主要是处理hero的一些相关东西,以及调用bulletLayer的一些方法,因为子弹是附属于hero的~~ HeroLayer 类的成员如下: 1 class HeroLayer ...
- 树莓派魔镜项目——笔记三 第三方库
介绍几个第三方模块 由于部分module使用了api,则可能涉及以下情况: 1:直接可用的 2:需要科学上网的 3:需要申请api key的 主要修改mouts/config/config.js文件, ...
- ASP.Net MVC OA项目笔记三
1.1.1 业务层和数据层之间加一个数据会话层,封装所有数据操作类实例的创建(工厂类) 工厂类是负责对象的创建 作用:将BLL和DAL解耦了,提供一个数据访问的统一访问点 数据会话层DBSession ...
- 项目笔记(一):实验——用神经网络实现midi音乐旋律音轨的确定
零.写在前面 计划要用seq2seq模型做一个交响乐编曲程序,encoder network的输入是一个乐句旋律,decoder network的目标target是这个乐句完整的管弦配乐版本.本文记录 ...
- 深度学习入门教程UFLDL学习实验笔记三:主成分分析PCA与白化whitening
深度学习入门教程UFLDL学习实验笔记三:主成分分析PCA与白化whitening 主成分分析与白化是在做深度学习训练时最常见的两种预处理的方法,主成分分析是一种我们用的很多的降维的一种手段,通 ...
- 自动驾驶系统进阶与项目实战(三)基于全卷积神经网络的点云三维目标检测和ROS实战
自动驾驶系统进阶与项目实战(三)基于全卷积神经网络的点云三维目标检测和ROS实战 前面入门系列的文章中我介绍了几种点云三维分割/目标检测模型,在做点云预处理上,有通过球面投射(SqueezeNet)得 ...
- C51 项目笔记 |Mifare RFID-RC522模组实验
项目框架 射频识别(Radiofrequency identification ,RFID),又称电子标签(E-Tag),是一种利用射频信号自动识别目标对象并获取相关信息的技术.RFID或射频识别系统 ...
- 机器学习笔记三—卷积神经网络与循环神经网络
系列文章目录 机器学习笔记一-机器学习基本知识 机器学习笔记二-梯度下降和反向传播 机器学习笔记三-卷积神经网络与循环神经网络 机器学习笔记四-机器学习可解释性 机器学习笔记五-机器学习攻击与防御 机 ...
- 用dsp的c54x汇编语言编写4位数的按位输出和计算,DSP实验三实验四(精).doc
DSP实验三实验四(精).doc 实验三.文件和Gel文件的编写 一.实验目的 1. 掌握Gel文件的编写, 2. 熟悉Code Composer Studio的使用 二.实验设备 1. 集成开发环境 ...
最新文章
- mysql 数据目录更改
- 计算机网络知识点总结(一)-物理层
- c语言是结构化 模块化,c语言是完全模块化和结构化的语言,怎么理解,什么是模块化和结构化...
- mxnet基础到提高(6)--梯度,反馈与标准化(归一化)
- Comparable与Comparator浅析
- 纽约大学计算机工程专业课程,纽约大学计算机工程硕士专业介绍及课程要求
- [***]HZOI20190714 T2熟练剖分
- oracle出现The Network Adapter could not establish the connection的问题
- win10 html css,Win10创造者更新:Edge支持CSS自定义属性
- Netty工作笔记0020---Selectionkey在NIO体系
- 1. 少了一个PermMissingElem Find the missing element in a given permutation.
- 蓝宝石rx470d原版bios_AMD RX470/570强刷RX580完整图文教程(附文件下载及查BIOS攻略)...
- float函数python作用_Python内置函数float()
- 如何在edge浏览器上安装flash插件运行需要flash的游戏
- 如何获取Teams Meeting 详情
- 安徽省大数据与人工智能竞赛经验分享-4【从赛题角度看人员分工】
- 渗透测试 | UserInfo信息收集
- ActiveMQ学习(二)——MQ的工作原理
- java NIO BIO和AIO
- Linux终端编程--termios