python进行谱曲_使用LSTM-GAN为歌词谱曲
在本文中,我將首先介紹基于AI的音樂生成的最新發(fā)展,然后介紹我創(chuàng)建的系統(tǒng)并討論其組成,包括Yi Yu等人的“Lyrics-to-Melody” AI模型等。 。 [6]和Google的Music Transformer模型[7]。 然后,我將演示一個示例,該示例從(Robert Frost)的詩歌中生成歌曲,并介紹其他生成的歌曲的集合。
背景
在過去的五個月中,我一直在研究如何將人工智能(AI)和機器學(xué)習(xí)(ML)用于創(chuàng)新活動。
盡管最先進的人工智能模型可以生成優(yōu)秀的圖片和文字,但到目前為止,人工智能模型在作曲方面還沒有那么好。有些音樂生成模型還不錯,比如谷歌[3]的various Magenta models,OpenAI[4]的MuseNet模型,以及AIVA[5]的商業(yè)產(chǎn)品。但大多數(shù)產(chǎn)生AI模型的音樂輸出往往是雜亂無章和不連貫的。似乎缺少的是歌曲的整體結(jié)構(gòu)。讓我們看看我們是否可以通過注入抒情詩歌來彌補這一點。
系統(tǒng)總覽
我使用的是由Yi Yu和她的同事設(shè)計和訓(xùn)練的Lyrics-to-Melody AI模型。他們稱之為有條件的LSTM-GAN,用于從歌詞中生成旋律[6]。
系統(tǒng)接受了約12K帶有歌詞的MIDI歌曲進行訓(xùn)練。 它使用單詞及其音節(jié)作為輸入,并經(jīng)過訓(xùn)練以預(yù)測音樂的音符,持續(xù)時間和靜息持續(xù)時間作為輸出。 這是對“I’ve Been Working on the Railroad”的五個條形的分析,以黃色顯示輸入,以藍色顯示預(yù)期輸出。 請注意,“ day”一詞之后的其余部分如何與下一個音節(jié)“ I've”相關(guān)聯(lián)。
我使用的第二個主要系統(tǒng)是Music Transformer [7],它是谷歌的Magenta模型套件的一部分。該模型自動為給定的旋律生成音樂伴奏。它訓(xùn)練了作為雅馬哈年度電子鋼琴比賽[8]的一部分數(shù)據(jù),大約400個由約翰·塞巴斯蒂安·巴赫的合唱團和1100個由專家鋼琴家捕捉的表演。
下面是一個組件圖,它顯示了整個系統(tǒng)的流程,左邊是作為文本的一首詩歌,右邊是作為MIDI文件生成一首新歌。
每一行選定的詩被輸入系統(tǒng),一次一行。它使用一個名為Pyphen的模塊,使用Hunspell連字符字典[9]將行中的每個單詞分解成音節(jié)。將結(jié)果輸入到歌詞到旋律模型中。 該模型是GAN和長短期記憶(LSTM)模型之間的混合體,用來進行MIDI格式的音符生成。
使用MIT的Music21庫[10]分析所得的樂句,確定其所處的音調(diào)。然后將該樂句轉(zhuǎn)換為C大調(diào)(或A Minor),并使用Music21量化為十六分音符。 生成所有音樂行之后,將生成的MIDI文件輸入到Music Transformer模型中,該模型添加一個伴隨的音樂聲部,并以具有表現(xiàn)力的鍵盤速度和定時來營造人性化的感覺。
最后,使用谷歌的Magenta 庫[11]對最終的MIDI文件進行一些后處理,比如分配樂器聲音。
在下一節(jié)中,我將詳細介紹這些步驟,并顯示為自定義處理編寫的Python代碼。
系統(tǒng)演練
在演練中,我們將使用Robert Frost的一首簡短而完整的詩歌,稱為“Plowmen” [12]。 我將展示用于將這首詩轉(zhuǎn)換為歌曲的Python代碼的主要摘要。
準備詩歌
處理的第一步涉及將每個單詞分解為音節(jié),并創(chuàng)建要嵌入到LSTM-GAN中的單詞嵌入。
這是示例詩。
Plowmen
A plow, they say, to plow the snow.
They cannot mean to plant it, no–
Unless in bitterness to mock
At having cultivated rock.
- Robert Frost
這是將每個單詞分解為音節(jié)并將其輸入LSTM-GAN的代碼段。 您可以看到它使用Word2Vec [13]為單詞和音節(jié)創(chuàng)建并輸出了嵌入內(nèi)容。 Google表示:“事實證明,通過Word2Vec學(xué)習(xí)到的嵌入在各種下游自然語言處理任務(wù)上都是成功的。”
from gensim.models import Word2Vec
syllModel = Word2Vec.load(syll_model_path)
wordModel = Word2Vec.load(word_model_path)
import pyphen
dic = pyphen.Pyphen(lang='en_US')
poem = '''A plow, they say, to plow the snow.
They cannot mean to plant it, no–
Unless in bitterness to mock
At having cultivated rock.'''
lines = poem.split('\n')
for line in lines:
line = re.sub(r'[^a-zA-Z ]+', '', line.strip())
line = re.sub(' +', ' ', line)
words = line.split(' ')
lyrics = []
for word in words:
syllables = dic.inserted(word).split('-')
if len(syllables) > 0:
for syllable in syllables:
if len(syllable) is 0:
continue
lyric_syllables.append(syllable)
if syllable in syllModel.wv.vocab and word in wordModel.wv.vocab:
lyrics.append([syllable, word])
else:
lyrics.append(["la", "la"])
else:
lyric_syllables.append(word)
if len(syllable) is 0:
continue
if word in wordModel.wv.vocab and syllable in syllModel.wv.vocab:
lyrics.append([word, word])
else:
lyrics.append(["la", "la"])
您還可以看到我是如何處理不在字典中的單詞的嵌入。如果一個單詞沒有在字典里,我只需要用“l(fā)a”來代替正確的音節(jié)數(shù)。這是詞曲作者的一個傳統(tǒng),當(dāng)他們還沒有寫完所有的歌詞。
這是這首詩詩句的音節(jié)。
A plow, they say, to plow the snow.
['A', 'plow', 'they', 'say', 'to', 'plow', 'the', 'snow']
They cannot mean to plant it, no–
['They', 'can', 'not', 'mean', 'to', 'plant', 'it', 'no']
Unless in bitterness to mock
['Un', 'less', 'in', 'bit', 'ter', 'ness', 'to', 'la']
At having cultivated rock.
['At', 'hav', 'ing', 'la', 'la', 'la', 'la', 'rock']
你可以看到單詞mock和cultivated變成了la。
生成旋律
一旦單詞和音節(jié)的嵌入設(shè)置好了,就很容易產(chǎn)生旋律。這里的代碼。
length_song = len(lyrics)
cond = []
for i in range(20):
if i < length_song:
syll2Vec = syllModel.wv[lyrics[i][0]]
word2Vec = wordModel.wv[lyrics[i][1]]
cond.append(np.concatenate((syll2Vec, word2Vec)))
else:
cond.append(np.concatenate((syll2Vec, word2Vec)))
flattened_cond = []
for x in cond:
for y in x:
flattened_cond.append(y)
pattern = generate_melody(flattened_cond, length_song)
length_song變量設(shè)置為文本行傳遞的音節(jié)數(shù)。 該模型經(jīng)過硬編碼,可以容納20個音節(jié),因此代碼將限制輸入,并在必要時通過重復(fù)最后一個音節(jié)來填充輸入。 注意,該填充將被模型忽略,并且我們將得到一個音符向量,該音符等于行中音節(jié)的數(shù)量。 這是旋律。
處理旋律
LSTM-GAN的輸出非常好,但存在一些問題:音樂沒有量化,而且每一行的鍵都在變化。LSTM-GAN系統(tǒng)的原始代碼具有將旋律“離散化”并將其轉(zhuǎn)置為統(tǒng)一鍵的功能。但是我選擇使用Music21庫來執(zhí)行這些功能。
下面的代碼顯示了如何將每個音符量化為十六分音符(第12和13行),以及如何將最后一個音符擴展到小節(jié)的末尾(第22行)。
import music21
def transpose_notes(notes, new_key):
midi_stream = music21.stream.Stream(notes)
key = midi_stream.analyze('key')
interval = music21.interval.Interval(key.tonic, new_key.tonic)
new_stream = midi_stream.transpose(interval)
return new_stream.notes
# quantize the start times and note durations
for c, n in enumerate(pattern):
n.offset = int(float(n.offset)*4+0.5) / 4
n.quarterLength = int(float(n.quarterLength)*4+0.5) / 4
n.offset += song_length
new_notes.append(n)
pattern_length += n.quarterLength
# stretch the last note out to hold the time
pattern_length_adjusted = float(pattern_length-0.125)
new_length = 4 * (1 + pattern_length_adjusted//4)
diff = new_length - float(pattern_length)
new_notes[-1].quarterLength += diff
the_key = music21.key.Key("C") # C Major
# transpose
new_notes = transpose_notes(new_notes, the_key)
您還可以看到如何使用Music21(第27行在第3行調(diào)用該函數(shù))將每行換位到C大調(diào)中。 這是生成的旋律。
下一步是將旋律傳遞到Music Transformer以創(chuàng)建一個伴隨的軌道,并使旋律更人性化。這里的代碼。
model_name = 'transformer'
hparams_set = 'transformer_tpu'
ckpt_path = 'gs://magentadata/models/music_transformer/checkpoints/melody_conditioned_model_16.ckpt'
class MelodyToPianoPerformanceProblem(score2perf.AbsoluteMelody2PerfProblem):
@property
def add_eos_symbol(self):
return True
problem = MelodyToPianoPerformanceProblem()
melody_conditioned_encoders = problem.get_feature_encoders()
inputs = melody_conditioned_encoders['inputs'].encode_note_sequence(melody_ns)
# Generate sample events.
decode_length = 4096
sample_ids = next(melody_conditioned_samples)['outputs']
# Decode to NoteSequence.
midi_filename = decode(
sample_ids,
encoder=melody_conditioned_encoders['targets'])
accompaniment_ns = note_seq.midi_file_to_note_sequence(midi_filename)
前11行代碼將設(shè)置transformer。代碼的其余部分采用名為melody_ns的音符序列,并生成與原旋律合并為伴奏的音軌。
處理的最后步驟是分配樂器并通過保留最后的音符作為額外的措施來創(chuàng)建結(jié)尾。 這是最后步驟的代碼。
def find_closest_note(n, notes):
closest = None
smallest_diff = float("inf")
for x in notes:
if n.pitch == x.pitch:
diff = abs(n.start_time - x.start_time)
if (diff < smallest_diff):
closest = x
smallest_diff = diff
return closest
for n in accompaniment_ns.notes:
n.instrument = 1
n.program = 2 # piano
closest_notes = []
for n in melody_ns.notes:
closest_note = find_closest_note(n, accompaniment_ns.notes)
closest_note.instrument = 0
closest_note.program = 26 # guitar
closest_notes.append(closest_note)
lyric_times.append(closest_note.start_time)
lyric_pitches.append(closest_note.pitch)
# map to the closest notes in the original melody
for c in range(len(closest_notes)-1):
if (closest_notes[c].end_time > closest_notes[c+1].start_time and
closest_notes[c+1].start_time > closest_notes[c].start_time):
closest_notes[c].end_time = closest_notes[c+1].start_time
# hold the last 5 notes to create an ending
pitches = []
for i in range(1,6):
n = accompaniment_ns.notes[-i]
if n.pitch not in pitches:
n.end_time += 4
由于原始旋律的時序在轉(zhuǎn)換器中發(fā)生了變化,因此我不得不編寫一個小函數(shù)來映射兩個音序之間最接近的音符。 然后,我使用該功能查找更改的音符,以將樂器設(shè)置為吉他。 最后一個代碼塊保留了最后五個注釋,這是一個額外的措施。 這是一個提示歌曲結(jié)束的小技巧。
Music Transformer的伴奏確實為樂曲增添了深度和色彩。 通過改變MIDI音符的開始時間和速度,該模型還給樂曲帶來更人性化的感覺。
結(jié)果
通常,這種音樂生成方法會產(chǎn)生不錯的效果。
經(jīng)過調(diào)轉(zhuǎn)和調(diào)整旋律線的時間,LSTM-GAN似乎為詩歌產(chǎn)生了良好的旋律。詩歌具有成為好音樂的品質(zhì),如韻律、結(jié)構(gòu)和抒情流。LSTM-GAN既獲取儀表的音節(jié),又獲取含義的單詞作為輸入。 來自兩種輸入的質(zhì)量導(dǎo)致良好的旋律。 請注意,此模型非常一致,因為在給定相同輸入文本的情況下,它將生成幾乎相同的旋律。
然而,對于Music Transformer同一輸入旋律的輸出變化很大,有的伴奏效果很差。
引用
[1] S. Hendrix, “Robert Frost wrote this masterpiece in about 20 minutes. It belongs to all of us now.”, The Washington Post, 2019,
[2] R. Frost, “New Hampshire”, 1923, http://en.wikisource.org/wiki/NewHampshire(Frost)
[4] C. M. Payne, “MuseNet”, OpenAI, 2019, http://openai.com/blog/musenet
[5] AIVA, “The Artificial Intelligence composing emotional soundtrack music”, 2016
[6] Y. Yu, A. Srivastava, and S. Canales, “Lyrics-Conditioned Neural Melody Generation”, 2019, http://arxiv.org/pdf/1908.05551.pdf
[7] C.A. Huang, A. Vaswani, J. Uszkoreit, N. Shazeer, I. Simon, C. Hawthorne, A.M. Dai, M.D. Hoffman, M.Dinculescu, and D. Eck, “Music Transformer: Generating Music with Long-Term Structure”, 2018, http://arxiv.org/pdf/1809.04281.pdf
[8] Yamaha, e-Piano Competition, 2002–2011
[9] Pyphen, Python Hyphenator, 2014
[10] MIT, Music21, 1995
[11] Google, Magenta, 2016
[12] R. Frost, “Plowmen”, A Miscellany of American Poetry, 1920,
[13] T. Mikolov, K. Chen, G. Corrado, and J. Dean, “Efficient Estimation of Word Representations in Vector Space”, 2013,
作者:Robert A. Gonsalves
deephub翻譯組
總結(jié)
以上是生活随笔為你收集整理的python进行谱曲_使用LSTM-GAN为歌词谱曲的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux云计算-02_CentOS L
- 下一篇: 不联网安装 SQL server 201