中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

東湖網(wǎng)站建設啥是網(wǎng)絡推廣

東湖網(wǎng)站建設,啥是網(wǎng)絡推廣,用網(wǎng)站做的人工智能,網(wǎng)站論壇怎么做 csdn前言 本文介紹循環(huán)神經(jīng)網(wǎng)絡的進階案例,通過搭建和訓練一個模型,來對鋼琴的音符進行預測,通過重復調(diào)用模型來進而生成一段音樂; 使用到Maestro的鋼琴MIDI文件 ,每個文件由不同音符組成,音符用三個量來表示…

前言

本文介紹循環(huán)神經(jīng)網(wǎng)絡的進階案例,通過搭建和訓練一個模型,來對鋼琴的音符進行預測,通過重復調(diào)用模型來進而生成一段音樂;

使用到Maestro的鋼琴MIDI文件 ,每個文件由不同音符組成,音符用三個量來表示:音高pitch、步長step、持續(xù)時間duration。通過搭建和訓練循環(huán)神經(jīng)網(wǎng)絡模型,輸入一系列音符能預測下一個音符。

下圖是一個鋼琴MIDI文件,由不同音符組成:

思路流程

  1. 導入數(shù)據(jù)集
  2. 探索集數(shù)據(jù),并進行數(shù)據(jù)預處理
  3. 構(gòu)建模型(搭建神經(jīng)網(wǎng)絡結(jié)構(gòu)、編譯模型)
  4. 訓練模型(把數(shù)據(jù)輸入模型、評估準確性、作出預測、驗證預測) ?
  5. 使用訓練好的模型
  6. 優(yōu)化模型、重新構(gòu)建模型、訓練模型、使用模型

一、導入數(shù)據(jù)集

?使用到Maestro的鋼琴MIDI文件 ,每個文件中由不同音軌組成,音軌中包含了一些音符;我們可以通過遍歷每個音軌中的音符,獲取音符的開始時間、結(jié)束時間、音高、音量等信息,進行音樂分析和處理。

我們到Maestro下載maestro-v2.0.0-midi.zip文件,它包含1282個鋼琴MIDI文件,大約58M左右;解壓后能看到如下的文件。

2004

2006

2008

2009

2011

2013

2014

2015

2017

2018

LICENSE

maestro-v2.0.0.csv

maestro-v2.0.0.json

README

我們可以使用電腦播放器打開文件夾中鋼琴MIDI文件,比如:maestro-v2.0.0/2004/MIDI-Unprocessed_SMF_02_R1_2004_01-05_ORIG_MID--AUDIO_02_R1_2004_05_Track05_wav.midi文件,能聽到一段鋼琴音樂。

二、探索集數(shù)據(jù),并進行數(shù)據(jù)預處理

2.1 解析MIDI文件

我們使用?pretty_midi?庫創(chuàng)建和解析MIDI文件,首先安裝一下它,執(zhí)行如下的命令:

!pip install pretty_midi

在notebook jupytre中播放MIDI音頻文件,需要安裝pyfluidsynth庫,執(zhí)行如下的命令:

!sudo apt install -y fluidsynth

寫一個程序解析MIDI文件,

import glob
import pretty_midi# 加載maestro-v2.0.0目錄下的每個midi文件
filenames = glob.glob(str('./maestro-v2.0.0/*/*.mid*'))
print('Number of files:', len(filenames))# 使用pretty_midi庫解析單個MIDI文件,并檢查音符的格式
sample_file = filenames[1]
print(sample_file)
pm = pretty_midi.PrettyMIDI(sample_file)# 對MIDI文件進行檢查
print('Number of instruments:', len(pm.instruments))
instrument = pm.instruments[0]
instrument_name = pretty_midi.program_to_instrument_name(instrument.program)
print('Instrument name:', instrument_name)

2.2 提取音符

在訓練模型時,將使用三個變量來表示音符:pitch、step 和 duration。

  • pitch是音符的音高,以MIDI音高值表示,范圍是0到127,0表示最低音高,127表示最高音高。
  • step是是從上一個音符或曲目的開始經(jīng)過的時間。
  • duration是音符的持續(xù)時間,以“ticks”為單位表示,一個tick表示MIDI時間分辨率中的最小時間單位,具體的時間取決于MIDI文件的時間分辨率參數(shù)。

所以我們需要對每個MIDI文件進行提取音符。

上面打開的xxxMIDI文件,查看它的5個音符

# 查看xxxMIDI文件的10個音符
for i, note in enumerate(instrument.notes[:5]):note_name = pretty_midi.note_number_to_name(note.pitch)duration = note.end - note.startprint(f'{i}: pitch={note.pitch}, note_name={note_name},'f' duration={duration:.4f}')

能看到如下的信息

0: pitch=78, note_name=F#5, duration=0.0292

1: pitch=66, note_name=F#4, duration=0.0333

2: pitch=71, note_name=B4, duration=0.0292

3: pitch=83, note_name=B5, duration=0.0365

4: pitch=73, note_name=C#5, duration=0.0333

寫一個函數(shù)來從MIDI文件中提取音符

import pandas as pd
import collections
import numpy as np# 從MIDI文件中提取音符
def midi_to_notes(midi_file: str) -> pd.DataFrame:pm = pretty_midi.PrettyMIDI(midi_file)instrument = pm.instruments[0]notes = collections.defaultdict(list)# 按開始時間對筆記排序sorted_notes = sorted(instrument.notes, key=lambda note: note.start)prev_start = sorted_notes[0].startfor note in sorted_notes:start = note.startend = note.endnotes['pitch'].append(note.pitch)notes['start'].append(start)notes['end'].append(end)notes['step'].append(start - prev_start)notes['duration'].append(end - start)prev_start = startreturn pd.DataFrame({name: np.array(value) for name, value in notes.items()})

通過midi_to_notes函數(shù),提取一個MIDI文件中提取音符

raw_notes = midi_to_notes('./xxx.midi')
raw_notes.head()

?比如,MIDI文件名稱為:maestro-v2.0.0/2004/MIDI-Unprocessed_XP_14_R1_2004_01-03_ORIG_MID--AUDIO_14_R1_2004_03_Track03_wav.midi

pitch是音高。duration 是音符將播放多長時間(以秒為單位),是音符結(jié)束時間(end)和音符開始時間(start)之間的差值。step 是從前一個音符開始所經(jīng)過的時間。

pitchstartendstepduration
0781.0666671.0958330.0000000.029167
1661.0718751.1052080.0052080.033333
2831.2177081.2541670.1458330.036458
3711.2208331.2500000.0031250.029167
4851.3562501.4072920.1354170.051042

解釋音符名稱可能比解釋音高更容易,可以使用下面的函數(shù)將數(shù)字音高值轉(zhuǎn)換為音符名稱。音符名稱顯示了音符類型、變音記號和八度數(shù)(例如 C#4)。

get_note_names = np.vectorize(pretty_midi.note_number_to_name)
sample_note_names = get_note_names(raw_notes['pitch'])
sample_note_names[:10]

輸出信息

array(['F#5', 'F#4', 'B5', 'B4', 'C#6', 'C#5', 'D#6', 'B0', 'D#5', 'B1'], dtype='<U3')

2.3 繪制音軌

從MIDI文件中提取音符后,寫一個函數(shù)來繪制pitch音高、duration持續(xù)時間

from matplotlib import pyplot as plt
from typing import Dict, List, Optional, Sequence, Tuple
import seaborn as sns# 繪制pitch音高、duration持續(xù)時間
def plot_piano_roll(notes: pd.DataFrame, count: Optional[int] = None):if count:title = f'First {count} notes'else:title = f'Whole track'count = len(notes['pitch'])plt.figure(figsize=(20, 4))plot_pitch = np.stack([notes['pitch'], notes['pitch']], axis=0)plot_start_stop = np.stack([notes['start'], notes['end']], axis=0)plt.plot(plot_start_stop[:, :count], plot_pitch[:, :count], color="b", marker=".")plt.xlabel('Time [s]')plt.ylabel('Pitch')_ = plt.title(title)# 查看MIDI文件30個音符的分布情況
plot_piano_roll(raw_notes, count=30)# 繪制整個音軌的音符
plot_piano_roll(raw_notes)

查看MIDI文件50個音高和持續(xù)時間的情況

繪制整個音軌的音符

?

2.4?檢查音符分布

檢查每個音符變量的分布,通過如下函數(shù)實現(xiàn)

def plot_distributions(notes: pd.DataFrame, drop_percentile=2.5):plt.figure(figsize=[15, 5])plt.subplot(1, 3, 1)sns.histplot(notes, x="pitch", bins=20)plt.subplot(1, 3, 2)max_step = np.percentile(notes['step'], 100 - drop_percentile)sns.histplot(notes, x="step", bins=np.linspace(0, max_step, 21))plt.subplot(1, 3, 3)max_duration = np.percentile(notes['duration'], 100 - drop_percentile)sns.histplot(notes, x="duration", bins=np.linspace(0, max_duration, 21))# 查看音符的分布
plot_distributions(raw_notes)

能看到如下的音符分布:

?

2.5?創(chuàng)建訓練數(shù)據(jù)集

通過從MIDI文件中提取音符來創(chuàng)建訓練數(shù)據(jù)集,音符用三個變量來表示:pitch(音高)、step(音符名)和 duration(持續(xù)時間)。

對于成批的音符序列訓練模型;每個樣本將包含一系列音符作為輸入特征,下一個音符作為標簽。通過這種方式,模型將被訓練來預測序列中的下一個音符。

以下代碼是創(chuàng)建訓練數(shù)據(jù)集的:

key_order = ['pitch', 'step', 'duration']
train_notes = np.stack([all_notes[key] for key in key_order], axis=1)
notes_ds = tf.data.Dataset.from_tensor_slices(train_notes)# 每個示例將由一系列音符組成作為輸入特征,并將下一個音符作為標簽。
# 通過這種方式,模型將被訓練以預測序列中的下一個音符。
def create_sequences(dataset: tf.data.Dataset, seq_length: int,vocab_size = 128,
) -> tf.data.Dataset:seq_length = seq_length+1windows = dataset.window(seq_length, shift=1, stride=1,drop_remainder=True)flatten = lambda x: x.batch(seq_length, drop_remainder=True)sequences = windows.flat_map(flatten)def scale_pitch(x):x = x/[vocab_size,1.0,1.0]return xdef split_labels(sequences):inputs = sequences[:-1]labels_dense = sequences[-1]labels = {key:labels_dense[i] for i,key in enumerate(key_order)}return scale_pitch(inputs), labelsreturn sequences.map(split_labels, num_parallel_calls=tf.data.AUTOTUNE)

設置每個示例的序列長度。嘗試使用不同的長度(例如,50、100、150),以確定哪種長度最適合數(shù)據(jù),或使用超參數(shù)調(diào)整。詞匯表的大小(Vocab_Size)設置為128,表示Pretty_MIDI支持的所有音調(diào)。

seq_length = 25
vocab_size = 128
seq_ds = create_sequences(notes_ds, seq_length, vocab_size)
seq_ds.element_specbatch_size = 64
buffer_size = n_notes - seq_length  
train_ds = (seq_ds.shuffle(buffer_size).batch(batch_size, drop_remainder=True).cache().prefetch(tf.data.experimental.AUTOTUNE))

三、構(gòu)建模型

模型輸入是序列的音符,輸出是一個音符;即:通過輸入一段連續(xù)的音符,預測下一個音符。

輸入:輸入的維度是nx3,n是指音符的個數(shù)長度,3是指音符使用pitch(音高)、step(音符名)和 duration(持續(xù)時間)三個變量來表示;

輸出:預測一個音符,設置模型輸出的維度是3,表示音符的3個變量。

模型主體:LSTM結(jié)構(gòu)。

損失函數(shù):對于pitch和duration,使用基于均方誤差的自定義損失函數(shù)。

def mse_with_positive_pressure(y_true: tf.Tensor, y_pred: tf.Tensor):mse = (y_true - y_pred) ** 2positive_pressure = 10 * tf.maximum(-y_pred, 0.0)return tf.reduce_mean(mse + positive_pressure)

下面是搭建網(wǎng)絡的代碼:

# 設置輸入
input_shape = (seq_length, 3)
learning_rate = 0.005# 模型輸入層
inputs = tf.keras.Input(input_shape)# 使用循環(huán)神經(jīng)網(wǎng)絡的變體LSTM層
x = tf.keras.layers.LSTM(128)(inputs)# 輸出層
outputs = {'pitch': tf.keras.layers.Dense(128, name='pitch')(x),'step': tf.keras.layers.Dense(1, name='step')(x),'duration': tf.keras.layers.Dense(1, name='duration')(x),
}# 構(gòu)建模型
model = tf.keras.Model(inputs, outputs)# 定義損失函數(shù)
loss = {'pitch': tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),'step': mse_with_positive_pressure,'duration': mse_with_positive_pressure,
}# 模型訓練的優(yōu)化器
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)# 編譯模型
model.compile(loss=loss,loss_weights={'pitch': 0.05,'step': 1.0,'duration':1.0,},optimizer=optimizer,
)# 設置訓練模型時的回調(diào)函數(shù)
callbacks = [tf.keras.callbacks.ModelCheckpoint(filepath='./training_checkpoints/ckpt_{epoch}',save_weights_only=True),tf.keras.callbacks.EarlyStopping(monitor='loss',patience=5,verbose=1,restore_best_weights=True),
]

查看一下網(wǎng)絡模型:tf.keras.utils.plot_model(model)

或者用這樣方式看看:model.summary()

?

四、訓練模型

這里我們輸入準備好的訓練集數(shù)據(jù),指定訓練模型時的回調(diào)函數(shù)(保存模型權(quán)重、自動早停),模型一共訓練50輪。

# 模型訓練50輪
epochs = 50# 開始訓練模型
history = model.fit(train_ds,epochs=epochs,callbacks=callbacks,
)

下圖是訓練過程的截圖,能看到模型訓練到42輪時停止了,因為使用EarlyStopping()函數(shù),模型的損失足夠小了,就不再訓練了。

通常loss越小越好,訓練完模型后,畫一下?lián)p失值的變化過程:

?

五、使用模型

使用 model.predict( )? 函數(shù),進行預測音符。但要使用模型生成音符,首先需要提供音符的起始序列。

下面的函數(shù),從一系列音符中生成一個音符

def predict_next_note(notes: np.ndarray, keras_model: tf.keras.Model, temperature: float = 1.0) -> int:"""使用經(jīng)過訓練的序列模型生成標簽ID"""assert temperature > 0# 添加批次維度inputs = tf.expand_dims(notes, 0)predictions = model.predict(inputs)pitch_logits = predictions['pitch']step = predictions['step']duration = predictions['duration']pitch_logits /= temperaturepitch = tf.random.categorical(pitch_logits, num_samples=1)pitch = tf.squeeze(pitch, axis=-1)duration = tf.squeeze(duration, axis=-1)step = tf.squeeze(step, axis=-1)# `step` 和 `duration` 值應該是非負數(shù)step = tf.maximum(0, step)duration = tf.maximum(0, duration)return int(pitch), float(step), float(duration)

舉一個例子,生成一些音符

temperature = 2.0
num_predictions = 120sample_notes = np.stack([raw_notes[key] for key in key_order], axis=1)# 音符的初始序列; 音高被歸一化,類似于訓練序列
input_notes = (sample_notes[:seq_length] / np.array([vocab_size, 1, 1]))generated_notes = []
prev_start = 0
for _ in range(num_predictions):pitch, step, duration = predict_next_note(input_notes, model, temperature)start = prev_start + stepend = start + durationinput_note = (pitch, step, duration)generated_notes.append((*input_note, start, end))input_notes = np.delete(input_notes, 0, axis=0)input_notes = np.append(input_notes, np.expand_dims(input_note, 0), axis=0)prev_start = startgenerated_notes = pd.DataFrame(generated_notes, columns=(*key_order, 'start', 'end'))

# 查看成的generated_notes前5個音符
generated_notes.head(5)# 查看成的generated_notes的音軌情況
plot_piano_roll(generated_notes)# 查看生成的generated_notes?音符的分布情況
plot_distributions(generated_notes)

查看生成的前5個音符,

pitchstepdurationstartend
0370.0956330.0920780.0956330.187710
1770.0974170.6094620.1930490.802511
2760.0890490.4556260.2820990.737724
3940.0965750.4439370.3786730.822611
4970.1094040.3766040.4880770.864681

?

查看成的generated_notes的音軌情況

?查看生成的generated_notes?音符的分布情況

?

本文只供大家參考和學習,謝謝~

其它推薦文章:

[1]?【神經(jīng)網(wǎng)絡】綜合篇——人工神經(jīng)網(wǎng)絡、卷積神經(jīng)網(wǎng)絡、循環(huán)神經(jīng)網(wǎng)絡、生成對抗網(wǎng)絡

[2]?手把手搭建一個【卷積神經(jīng)網(wǎng)絡】

[3]?“花朵分類“ 手把手搭建【卷積神經(jīng)網(wǎng)絡】

[4]?一篇文章“簡單”認識《循環(huán)神經(jīng)網(wǎng)絡》

[5]?神經(jīng)網(wǎng)絡學習

http://www.risenshineclean.com/news/8365.html

相關文章:

  • WordPress前端上傳大文件搜索引擎優(yōu)化seo名詞解釋
  • 做設計網(wǎng)站的工作百度快照優(yōu)化培訓班
  • 手機在線做ppt的網(wǎng)站有哪些最新的網(wǎng)絡營銷的案例
  • 做企業(yè)網(wǎng)站選百度云還是阿里云b2b網(wǎng)站推廣優(yōu)化
  • 成都營銷類網(wǎng)站設計如何優(yōu)化關鍵詞排名快速首頁
  • 免費自己生成網(wǎng)站泰安網(wǎng)絡推廣培訓
  • 網(wǎng)站網(wǎng)頁設計模板下載視頻seo優(yōu)化教程
  • 網(wǎng)站鏈接seo云優(yōu)化是什么意思
  • 如何在網(wǎng)上建立自己的網(wǎng)站torrentkitty搜索引擎
  • 備案號網(wǎng)站下邊軟文廣告經(jīng)典案例分析
  • 牡丹江市建設銀行門戶網(wǎng)站百度快照的作用是什么
  • 企業(yè)網(wǎng)站架構(gòu)體驗營銷是什么
  • 做網(wǎng)站的怎么辦理營業(yè)執(zhí)照seo輿情優(yōu)化
  • 池州專業(yè)網(wǎng)站建設怎么樣蘇州seo
  • wordpress ie8優(yōu)化軟件
  • 做h5的網(wǎng)站頁面設計廈門人才網(wǎng)個人會員
  • 丹陽疫情最新消息今天新增百度seo網(wǎng)站優(yōu)化服務
  • 網(wǎng)絡制作軟件seo型網(wǎng)站
  • 做電商網(wǎng)站哪里好優(yōu)化師助理
  • 個人博客網(wǎng)站模板源碼線上宣傳方式有哪些
  • 百度搜索網(wǎng)站在第一次輸入搜索內(nèi)容后點搜索鍵沒有反應智慧軟文發(fā)稿平臺
  • 深圳網(wǎng)站設計公司如何寧波seo網(wǎng)絡推廣定制多少錢
  • 鼠標放到一級導航時才顯示網(wǎng)站二級導航 鼠標離開時不顯示 怎么控制站長統(tǒng)計app軟件
  • 西安做百度網(wǎng)站的seo優(yōu)化多少錢
  • 網(wǎng)站做優(yōu)化每天一定要更新bing搜索 國內(nèi)版
  • 寧波網(wǎng)站建設制作哪家好牛排seo
  • 邢臺做wap網(wǎng)站費用網(wǎng)站接廣告平臺
  • cms建立網(wǎng)站鄭州百度推廣seo
  • 網(wǎng)站開發(fā)要懂英文嗎全國互聯(lián)網(wǎng)營銷大賽官網(wǎng)
  • 微信網(wǎng)站建設seo項目培訓