项目笔记(五)——从原始midi文件到seq2seq的训练集

零、写在前面

这几天做了两件事情,一件是完善上篇文章的用于分段的自相似矩阵算法,生成了分段后的1000+的midi文件(来自贝多芬九首交响曲),作为encoder input,另一件事是根据之前这篇文章的思路,训练神经网络提取旋律乐器的midi文件,作为decoder target。

已经准备好训练集了,下一步就是搭建seq2seq模型了,在这之前,把拼接好的两个模块记录下来,以备后患。

一、segement.py

import numpy as np
import pretty_midi
import matplotlib.pyplot as plt
import scipy.signal
from scipy.ndimage import filters
import cv2
import os

midi_cnt = 0
p = print

rootdir = 'C:/Users/Lenovo/Desktop/Computer Science/sourse/midi/beethoven symphony' # 存放原始midi文件的目录 
list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
for i in range(0,len(list)): #遍历所有文件,注意,下面的所有代码都包括在这层循环内
    p (i)
    file_name = os.path.join(rootdir,list[i])
    p(file_name)
    pm = pretty_midi.PrettyMIDI(file_name) #使用pretty_midi加载
    for inst_num in range (len(pm.instruments)): # 打印所有乐器的信息
        p(inst_num)
        p(pm.instruments[inst_num])

    # 设置超参数    
    filter_size = 256 # 高斯核尺寸
    standard_deviation = 200 # 高斯核标准差
    N_filter_size=50 # 滤波卷积核尺寸
    saved = False  # 用于调试
    print_S = False #绘制自相似矩阵
    print_gaussian = False #绘制高斯核
    print_scores = False # 打印滤波前后的得分
    segement = True #是否进行分割
    bias = 2.1 #对卷积操作进行除偏

对于最后一行,在进行卷及操作时,所得函数会相对原函数有滞后偏差,这里直接设置该偏差为2.1秒

#自相似矩阵
    if not saved:
        # 加载文件
        piano_roll = pm.get_piano_roll(10) #参数fs=10表示每秒扫描十次,即一个时间步为0.1秒
        p('已加载piano_roll,midi文件名:'+file_name)
        Tx = len(piano_roll[0])
        p('Tx='+str(Tx))
        x = np.zeros(shape=(128,Tx))
        x[:,:]=piano_roll
        x=np.transpose(x)

        #计算相似度矩阵
        S=np.zeros((Tx,Tx))
        p('正在计算相似度矩阵...')
        for i in range(Tx):
            S[i]=(np.sum(np.sqrt(np.square(x-x[i])),axis=1))
        p(S)
        #np.save('S of '+ file_name + '.npy',S)
        p('已储存相似度矩阵。')


    else:
        S=np.load('S of '+ file_name + '.npy')
        p('已加载相似度矩阵。')
        Tx = np.shape(S[0])[0] #Tx为总时间步数
        p(Tx)

    if print_S:
        plt.figure()
        plt.imshow(S,cmap = plt.cm.gray)
        plt.title('Similarity matrix')
        plt.show()
#高斯卷积、滤波、消除邻近的分割点
    # 高斯核卷积
    def gaussian_kernel_2d_opencv(filter_size,standard_deviation):
        kx = cv2.getGaussianKernel(filter_size,standard_deviation)
        ky = cv2.getGaussianKernel(filter_size,standard_deviation)
        return np.multiply(kx,np.transpose(ky))
    filter =gaussian_kernel_2d_opencv(filter_size,standard_deviation)
    ones = np.ones((filter_size,filter_size))
    for i in range (filter_size):
        if i < filter_size/2:
            ones[i,:int(filter_size/2)]= -1
        else:
            ones[i,int(filter_size/2):]=-1
    filter=np.multiply(filter,ones)
    if print_gaussian:
        plt.figure()
        plt.imshow(filter,cmap = plt.cm.gray)
        plt.show()


    # 新奇度函数
    N = np.zeros(Tx)
    p('卷积核大小:'+str(filter_size)+', 标准差:' + str(standard_deviation))
    p('正在卷积计算新奇度函数...')
    for i in range (Tx):
        if i>filter_size/2 and (Tx-i)>filter_size/2:
            slice_x = S[:, i-int(filter_size/2) : int(i+filter_size/2)]
            slice_xy = slice_x[i-int(filter_size/2) : int(i+filter_size/2)]
            N[i]=np.sum(np.multiply(slice_xy,filter))
    p(N)
    p('正在对新奇度函数进行卷积滤波...')

    #filter_1d = cv2.getGaussianKernel(N_filter_size,standard_deviation) #使用高斯核
    filter_1d = np.ones(N_filter_size)
    H = scipy.signal.convolve(N,np.reshape(filter_1d,(N_filter_size)))

    # 寻找极大值点
    maxs = [2]
    for h in range(len(H)-1):
        if H[h-1]<H[h] and H[h+1]<H[h] and h>1 and len
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值