久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

快過年了,搞個AI作曲,用TensorFlow訓練midi文件

 TF男孩 2022-12-24 發(fā)布于山東

一,、老張需求:AI作曲營造新年氛圍

我有一個搞嵌入式的朋友老張,全名叫張三,。是真的,,他的身份證上就叫張三。據(jù)說,,出生時,,他父母準備了一堆名字。但是兩人各執(zhí)一派,,大打出手,。吵鬧聲引來隔壁李大爺:實在不行叫張三,我叫李四,,也活得挺好,。于是,互不相讓的一對年輕夫妻,,給孩子上了戶口,,起名叫:張三。

老張長大后,,一直不和李大爺說話,。李大爺告訴小張三:當時,如果,,不是我沖進去,,急中生智給你定下名字,你可能就沒命了,。聽到這里,,小張三才稍微得以釋懷,并且給李大爺磕了個頭,,以示感謝,。李大爺說:客氣了,我起名字時,,我父母也一樣,,最后還是你爺爺給起的李四,咱兩家是世交,。

我打斷了老張:快說,,找我么事?

老張說,,其實我一直覺得,,我不是普通的凡人。

“嗯,,你特別的煩人”,。

老張說,是平凡的“凡”,。我今年40歲了,,哎,你知道嗎,?我前天剛過完40歲生日,,買了一個大蛋……

“說事情!”

老張說,,兄弟,,幫幫忙吧,我想搞一個發(fā)明,,需要你人工智能方向的幫助,。

我說,啊,,你又搞發(fā)明,?這次什么想法。

老張說,,現(xiàn)在快過年了,,我想搞一個仿老式留聲機的盒子,安裝到餐廳里面,。

機器采用自助模式,,只要顧客付錢,,盒子就會自動播放一段,由AI生成的原創(chuàng)新年音樂,,給他們送去祝福,,掃碼還可以下載保存。

我問老張,,你有銷售渠道嗎,?

老張說,放心吧,,餐廳我都談好了,。他們提供場地和網(wǎng)絡(luò),我們只承擔電費就行,。

我沉思了一會,,問老張:老張啊,你認識一個“耿”姓做手工的人嗎,?

老張說,,相信我,我絕對不認識他,,他的那些發(fā)明,,不是沒用,是真沒用,。

我點了點頭:那就好,,我支持你!

二,、midi格式:便攜式音樂描述文件

想讓AI學會作曲,,首先要找到一批音樂樣本,讓它學,。

AI作曲,,遵循“種瓜得瓜,種豆得豆”的原則:你給它訓練什么風格的樣本,,它最終就會生成什么風格的音樂,。

因此,我們需要找一些輕松活潑的音樂,,這適合新年播放,。

音樂文件的格式,我們選擇MIDI格式,。MIDI的全稱是:Musical Instrument Digital Interface,,翻譯成中文就是:樂器數(shù)字接口。

這是一種什么格式?為什么會有這種格式呢,?

話說,,隨著計算機的普及,電子樂器也出現(xiàn)了,。電子樂器的出現(xiàn),,極大地節(jié)省了成本,,帶來了便利,。

基本上有一個電子樂器,世間的樂器就都有了,。

這個按鈕是架子鼓,,那個按鈕是薩克斯。而在此之前,,你想要發(fā)出這類聲音,,真的得敲架子鼓或者吹薩克斯管。

而且還有更為放肆的事情,。你想用架子鼓一秒敲五下,,得有專業(yè)的技能。但是用電子樂器,,一秒敲五十下也毫不費力,,因為程序就給搞定了。

這些新生事物的出現(xiàn),,常常讓老藝術(shù)家們口吐鮮血,。

電子樂器既然可以演奏音樂,那么就有樂譜,。這樂譜還得有標準,,因為它得在所有電子樂器中都起作用。這個“計算機能理解的樂譜”,,就是MIDI格式,。

下面我們就來解析一下MIDI文件??纯此慕Y(jié)構(gòu)是怎么樣的,。

我找到一個機器貓(哆啦A夢)的主題曲,采用python做一下解析:

import pretty_midi
# 加載樣本文件
pm = pretty_midi.PrettyMIDI("jqm.midi")
# 循環(huán)樂器列表
for i, instrument in enumerate(pm.instruments):
instrument_name = pretty_midi.program_to_instrument_name(instrument.program)
print(i, instrument_name) # 輸出樂器名稱

這個音樂,,相信大家都很熟悉,,就是:哦、哦,、哦,,哆啦A夢和我一起,讓夢想發(fā)光……

通過pretty_midi庫加載MIDI文件,獲取它的樂器列表pm.instruments,,打印如下:

Acoustic Grand Piano(原聲大鋼琴),、Glockenspiel(鋼片琴)、String Ensemble(弦樂合奏) ,、Muted Trumpet(悶音小號),、Trombone(長號)、Electric Bass(電貝斯),、Acoustic Guitar(原聲吉他),、Flute(長笛)、Acoustic Grand Piano(原聲大鋼琴),、Harmonica(口琴),、Vibraphone(電顫琴)、Bagpipe(蘇格蘭風笛),、Marimba(馬林巴琴)……

我們看到,,短短一個片頭曲,就動用了近20種樂器,。如果不是專門分析它,,我們還真的聽不出來吶。

那么,,每種樂器的音符可以獲取到嗎,?我們來試試:

# 承接上個代碼片段,假設(shè)選定了樂器instrument
for j, note in enumerate(instrument.notes):
# 音高轉(zhuǎn)音符名稱
note_name = pretty_midi.note_number_to_name(note.pitch)
info = ("%s:%.2f->%.2f")%(note_name, note.start, note.end)

打印如下:

Acoustic Grand Piano

F#3:1.99->2.04 F#2:1.98->2.06 E2:1.99->2.07 C2:1.98->2.08 F#3:2.48->2.53 F#2:2.48->2.56 F#3:2.98->3.03 F#2:2.98->3.06 ……

通過獲取instrumentnotes,,可以讀到此樂器的演奏信息,。包含:pitch音高,start開始時間,,end結(jié)束時間,,velocity演奏力度。

名稱pitchstartendvelocity
示例241.982.0382
解釋音高(C1,、C2)開始時間結(jié)束時間力度
范圍128個音高單位為秒單位為秒最高100

上面的例子中,,F#3:1.99->2.04表示:音符F#3,演奏時機是從1.99秒到2.04秒,。

如果把這些數(shù)據(jù)全都展開,,其實挺壯觀的,應該是如下這樣:

其實,,MIDI文件對于一首樂曲來說,,就像是一個程序的源代碼,也像是一副藥的配方,。MIDI文件里,,描述了樂器的構(gòu)成,,以及該樂器的演奏數(shù)據(jù)。

這類文件要比WAV,、MP3這些波形文件小得多,。一段30分鐘鋼琴曲的MIDI文件,大小一般不超過100KB,。

因此,,讓人工智能去學習MIDI文件,并且實現(xiàn)自動作曲,,這是一個很好的選擇,。

三、實戰(zhàn):TensorFlow實現(xiàn)AI作曲

我在datasets目錄下,,放了一批節(jié)奏歡快的MIDI文件,。

這批文件,,除了節(jié)奏歡快適合在新年播放,,還有一個特點:全部是鋼琴曲。也就是說,,如果打印他的樂器的話,,只有一個,那就是:Acoustic Grand Piano(原聲大鋼琴),。

這么做降低了樣本的復雜性,,僅需要對一種樂器進行訓練和預測。同時,,當它有朝一日練成了AI作曲神功,,你也別妄想它會鑼鼓齊鳴,它仍然只會彈鋼琴,。

多樂器的復雜訓練當然可行,。但是目前在業(yè)內(nèi),還沒有足夠的數(shù)據(jù)集來支撐這件事情,。

開搞之前,,我們必須得先通盤考慮一下。不然,,我們都不知道該把數(shù)據(jù)搞成么個形式,。

AI作曲,聽起來很高端,。其實跟文本生成,、詩歌生成,沒有什么區(qū)別,。我之前講過很多相關(guān)的例子《NLP實戰(zhàn):基于LSTM自動生成原創(chuàng)宋詞》《NLP實戰(zhàn):基于GRU的自動對春聯(lián)》《NLP實戰(zhàn):基于RNN的自動藏頭詩》,。如果感興趣,,大家可以先預習一下。不看也不要緊,,后面我也會簡單描述,,但深度肯定不如上面的專項介紹。

利用RNN,,生成莎士比亞文集,,是NLP領(lǐng)域的HelloWorld入門程序。那么,,AI作曲,,只不過是引入了音樂的概念。另外,,在出入?yún)?shù)上,,維度也豐富了一些。但是,,從本質(zhì)上講,,它還是那一套思路。

所有AI自動生成的模式,,基本上都是給定一批輸入值+輸出值,。然后,讓機器去學習,,自己找規(guī)律,。最后,學成之后,,再給輸入,,讓它自己預測出下一個值。

舉個例子,,莎士比亞文集的生成,,樣本如下:

First Citizen:
Before we proceed any further, hear me speak.

All:
Speak, speak.

它是如何讓AI訓練和學習呢?其實,,就是從目前的數(shù)據(jù)不斷觀察,,觀察出現(xiàn)下一個字符的概率。

當前下一個經(jīng)驗值
Fi
Fir
Firs
First☆☆
………………

F后面大概率會出現(xiàn)i,。如果現(xiàn)在是Fi,,那么它的后面該出現(xiàn)r了。這些,,AI作為經(jīng)驗記了下了,。

這種記錄概率的經(jīng)驗,在少量樣本的情況下,,是無意義的,。

但是,,當這個樣本變成人類語言庫的時候,那么這個概率就是語法規(guī)范,,就是上帝視角,。

舉個例子,當我說:冬天了,,窗外飄起了__,!

你猜,飄起了什么,?是的,,窗外飄起了雪。

AI分析過人類歷史上,,出現(xiàn)過的所有語言之后,。當它進行數(shù)據(jù)分析的時候,最終它會計算出:在人類的語言庫里,,冬天出現(xiàn)飄雪花的情況,,要遠遠高于冬天飄落葉的情況。所以,,它肯定也會告訴你那個空該填:雪花,。

這就是AI自動作詞、作曲,、作畫的本質(zhì)。它的技術(shù)支撐是帶有鏈式的循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN),,數(shù)據(jù)支撐就是大量成型的作品,。

3.1 準備:構(gòu)建數(shù)據(jù)集

首先,讀取這些數(shù)據(jù),,然后把它們加工成輸入input和輸出output,。

展開一個MIDI文件,我們再來看一下原始數(shù)據(jù):

Note(start=1.988633, end=2.035121, pitch=54, velocity=82),
Note(start=1.983468, end=2.060947, pitch=42, velocity=78),
Note(start=2.479335, end=2.525823, pitch=54, velocity=82)……

我們可以把前幾組,,比如前24組音符數(shù)據(jù)作為輸入,,然后第25個作為預測值。后面依次遞推,。把這些數(shù)據(jù)交給AI,,讓它研究去。

訓練完成之后,,我們隨便給24個音符數(shù)據(jù),,讓它預測第25個。然后,,再拿著2~25,,讓它預測第26個,,以此循環(huán)往后,連綿不絕,。

這樣可以嗎,?

可以(能訓練)。但存在問題(結(jié)果非所愿),。

在使用循環(huán)神經(jīng)網(wǎng)絡(luò)的時候,,前后之間要帶有通用規(guī)律的聯(lián)系。比如:前面有“冬天”做鋪墊,,后面遇到“飄”時,,可以更準確地推測出來是“飄雪”。

我們看上面的數(shù)據(jù),,假設(shè)我們忽略velocity(力度)這個很專業(yè)的參數(shù),。僅僅看pitch音高和startend起始時間,。其中,,音高是128個音符。它是普遍有規(guī)律的,,值是1~128,,不會出圈兒。但是這個起始時間卻很隨機,,這里可以是啊1秒開始,,再往后可能就是100秒開始。

如果,,我們只預測2個音符,,結(jié)果200秒的時間出現(xiàn)的概率高。那么,,第二個音符豈不是到等到3分鐘后再演奏,。另外,很顯然演奏是有先后順序的,,因此要起止時間遵從隨機的概率分布,,是不靠譜的。

我覺得,,一個音符會演奏多久,,以及前后音符的時間間距,這兩項相對來說是比較穩(wěn)定的,。他們更適合作為訓練參數(shù),。

因此,我們決定把音符預處理成如下格式:

Note(duration=0.16, step=0.00, pitch=54),
Note(duration=0.56, step=0.31, pitch=53),
Note(duration=0.26, step=0.22, pitch=24),
……

duration表示演奏時長,,這個音符會響多久,,它等于end-start,。

step表示步長,本音符距離上一個出現(xiàn)的時間間隔,,它等于start2-start1,。

原始數(shù)據(jù)格式[start,end],同預處理后的數(shù)據(jù)格式[duration,step],,兩者是可以做到相互轉(zhuǎn)化的,。

我們把所有的訓練集文件整理一下:

import pretty_midi
import tensorflow as tf

midi_inputs = [] # 存放所有的音符
filenames = tf.io.gfile.glob("datasets/*.midi")
# 循環(huán)所有midi文件
for f in filenames:
pm = pretty_midi.PrettyMIDI(f) # 加載一個文件
instruments = pm.instruments # 獲取樂器
instrument = instruments[0] # 取第一個樂器,此處是原聲大鋼琴
notes = instrument.notes # 獲取樂器的演奏數(shù)據(jù)
# 以開始時間start做個排序,。因為默認是依照end排序
sorted_notes = sorted(notes, key=lambda note: note.start)
prev_start = sorted_notes[0].start
# 循環(huán)各項指標,,取出前后關(guān)聯(lián)項
for note in sorted_notes:
step = note.start - prev_start # 此音符與上一個距離
duration = note.end - note.start # 此音符的演奏時長
prev_start = note.start # 此音符開始時間作為最新
# 指標項:[音高(音符),同前者的間隔,,自身演奏的間隔]
midi_inputs.append([note.pitch, step, duration])

上面的操作,,是把所有的MIDI文件,依照預處理的規(guī)則,,全部處理成[pitch, step, duration]格式,,然后存放到midi_inputs數(shù)組中。

這只是第一步操作,。后面我們要把這個樸素的格式,,拆分成輸入和輸出的結(jié)對。然后,,轉(zhuǎn)化為TensorFlow框架需要的數(shù)據(jù)集格式,。

seq_length = 24 # 輸入序列長度
vocab_size = 128 # 分類數(shù)量

# 將序列拆分為輸入和輸出標簽對
def split_labels(sequences):
inputs = sequences[:-1] # 去掉最后一項最為輸入
# 將音高除以128,便于
inputs_x = inputs/[vocab_size,1.0,1.0]
y = sequences[-1] # 截取最后一項作為輸出
labels = {"pitch":y[0], "step":y[1],"duration":y[2]}
return inputs_x, labels

# 搞成tensor,,便于流操作,,比如notes_ds.window
notes_ds = tf.data.Dataset.from_tensor_slices(midi_inputs)
cut_seq_length = seq_length+1 # 截取的長度,因為要拆分為輸入+輸出,,因此+1
# 每次滑動一個數(shù)據(jù),每次截取cut_seq_length個長度
windows = notes_ds.window(cut_seq_length, shift=1, stride=1,drop_remainder=True)
flatten = lambda x: x.batch(cut_seq_length, drop_remainder=True)
sequences = windows.flat_map(flatten)
# 將25,,拆分為24+1,。24是輸入,1是預測,。進行訓練
seq_ds = sequences.map(split_labels, num_parallel_calls=tf.data.AUTOTUNE)
buffer_size = len(midi_inputs) - seq_length
# 拆分批次,,緩存等優(yōu)化
train_ds = (seq_ds.shuffle(buffer_size)
.batch(64, drop_remainder=True)
.cache().prefetch(tf.data.experimental.AUTOTUNE))

我們先分析split_labels這個方法。它接收一段序列數(shù)組,。然后將其分為兩段,,最后1項作為后段,其余部分作為前段,。

我們把seq_length定義為24,,從總數(shù)據(jù)midi_inputs中,,利用notes_ds.window實現(xiàn)每次取25個數(shù)據(jù),取完了向后移動1格,,再繼續(xù)取數(shù)據(jù),。直到湊不齊25個數(shù)據(jù)(drop_remainder=True意思是不足25棄掉)停止。

至此,,我們就有了一大批以25為單位的數(shù)據(jù)組,。其實,他們是:1~25,、2~26,、3~27……

然后,我們再調(diào)用split_labels,,將其全部搞成24+1的輸入輸出對,。此時數(shù)據(jù)就變成了:(1~24,25)(2~25,26)……,。接著,,再調(diào)用batch方法,把他們搞成每64組為一個批次,。這一步是框架的要求,。

至此,我們就把準備工作做好了,。后面,,就該交給神經(jīng)網(wǎng)絡(luò)訓練去了。

3.2 訓練:構(gòu)建神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)

這一步,,我們將構(gòu)建一個神經(jīng)網(wǎng)絡(luò)模型,。它將不斷地由24個音符觀察下一個出現(xiàn)的音符。它記錄,,它思考,,它嘗試推斷,它默寫并對照答案,。一旦見得多了,,量變就會引起質(zhì)變,它將從整個音樂庫的角度,,給出作曲的最優(yōu)解,。

好了,上代碼:

input_shape = (seq_length, 3) # 輸入形狀
inputs = tf.keras.Input(input_shape)
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),
}
model = tf.keras.Model(inputs, outputs)

上面代碼我們定義了輸入和輸出的格式,,然后中間加了個LSTM層,。

先說輸入。因為我們給的格式是[音高,間隔,,時長]3個關(guān)鍵指標,。而且每24個音,預測下一個音,。所以input_shape = (24, 3),。

再說輸出。我們最終期望AI可以自動預測音符,,當然要包含音符的要素,,那也就是outputs = {'pitch','step','duration'}。其中,,stepduration是一個數(shù)就行,,也就是Dense(1)。但是,,pitch卻不同,,它需要是128個音符中的一個。因此,,它是Dense(128),。

最后說中間層。我們期望有人能將輸入轉(zhuǎn)為輸出,,而且最好還有記憶,。前后之間要能綜合起來,要根據(jù)前面的鋪墊,,后面給出帶有相關(guān)性的預測,。那么,這個長短期記憶網(wǎng)絡(luò)LSTM(Long Short-Term Memory)就是最佳的選擇了,。

最終,,model.summary()打印結(jié)構(gòu)如下所示:

Layer (type)Output ShapeParamConnected to
input (InputLayer)[(None, 24, 3)]0[]
lstm (LSTM)(None, 128)67584['input[0][0]']
duration (Dense)(None, 1)129['lstm[0][0]']
pitch (Dense)(None, 128)16512['lstm[0][0]']
step (Dense)(None, 1)129['lstm[0][0]']
Total params: 84,354


后面,配置訓練參數(shù),,開始訓練:

checkpoint_path = 'model/model.ckpt'  # 模型存放路徑
model.compile( # 配置參數(shù)
loss=loss,
loss_weights={'pitch': 0.05,'step': 1.0,'duration':1.0},
optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
)
# 模型保存參數(shù)
cp_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_path
,save_weights_only=True, save_best_only=True)
# 啟動訓練,,訓練50個周期
model.fit(train_ds, validation_data=train_ds
, epochs=50,callbacks=[cp_callback])

訓練完成之后,會將模型保存在'model/model.ckpt'目錄下,。而且,,我們設(shè)置了只保存最優(yōu)的一個模型save_best_only=True

上面有個需要特別說明的地方,,那就是在model.compile中,給損失函數(shù)加了一個權(quán)重loss_weights的配置,。這是因為,,在輸出的三個參數(shù)中,pitch音高的128分類跨度較大,,一旦預測有偏差,,就會導致?lián)p失函數(shù)的值很大,。而stepduration本身數(shù)值就很小,都是0.0x秒,,損失函數(shù)的值變化較小,。這種不匹配,會導致后兩個參數(shù)的變化被忽略,,只關(guān)心pitch的訓練,。因此需要降低pitch的權(quán)重平衡一下。至于具體的數(shù)值,,是調(diào)試出來的,。

出于講解的需要,上面的代碼僅僅是關(guān)鍵代碼片段,。文末我會把完整的項目地址公布出來,,那個是可以運行的。

好了,,訓練上50輪,,保存完結(jié)果模型。下面,,就該去做預測了,。

3.3 預測和播放:實現(xiàn)AI作曲

現(xiàn)在這個模型,已經(jīng)可以根據(jù)24個音符去推測出下一個音符了,。我們來試一下,。

# 加載模型
if os.path.exists(checkpoint_path + '.index'):
model.load_weights(checkpoint_path)
# 從音符庫中隨機拿出24個音符,當然你也可以自己編
sample_notes = random.sample(midi_inputs, 24)
num_predictions = 600 # 預測后面600個
# 循環(huán)600次,,每次取最新的24個
for i in range(num_predictions):
# 拿出最后24個
n_notes = sample_notes[-seq_length:]
# 主要給音高做一個128分類歸一化
notes = []
for input in n_notes:
notes.append([input[0]/vocab_size,input[1],input[2]])
# 將24個音符交給模型預測
predictions = model.predict([notes])
# 取出預測結(jié)果
pitch_logits = predictions['pitch']
pitch = tf.random.categorical(pitch_logits, num_samples=1)[0]
step = predictions['step'][0]
duration = predictions['duration'][0]
pitch, step, duration = int(pitch), float(step), float(duration)
# 將預測值添加到音符數(shù)組中,,進行下一次循環(huán)
sample_notes.append([pitch, step, duration])

其實,關(guān)鍵代碼就一句predictions = model.predict([notes]),。根據(jù)24個音符,,預測出來下一個音符的pitchstepduration,。其他的,,都是輔助操作。

我們從素材庫里,,隨機生成了24個音符,。其實,如果你懂聲樂,,你也可以自己編24個音符,。這樣,起碼能給音樂定個基調(diào)。因為,,后面的預測都是根據(jù)前面特征來的,。當然,也可以不是24個,,根據(jù)2個生成1個也行,。那前提是,訓練的時候也得是2+1的模式,。但是,,我感覺還是24個好,感情更深一些,。

24個生成1個后,,變成了25個。然后再取這25個中的最后24個,,繼續(xù)生成下一個,。循環(huán)600次,最后生成了624個音符,。打印一下:

[[48, 0.001302083333371229, 0.010416666666628771], 
[65, 0.11979166666674246, 0.08463541666651508]
……
[72, 0.03634712100028992, 0.023365378379821777],
[41, 0.04531348496675491, 0.011086761951446533]]

但是,,這是預處理后的特征,并非是可以直接演奏的音符,。是否還記得duration = end-start以及step=start2-start1,。我們需要把它們還原成為MIDI體系下的屬性:

# 復原midi數(shù)據(jù)
prev_start = 0
midi_notes = []
for m in sample_notes:
pitch, step, duration = m
start = prev_start + step
end = start + duration
prev_start = start
midi_notes.append([pitch, start, end])

這樣,就把[pitch, step, duration]轉(zhuǎn)化成了[pitch, start, end],。打印midi_notes如下:

[[48, 0.001302083333371229, 0.01171875], 
[65, 0.12109375000011369, 0.20572916666662877],
……
[72, 32.04372873653976, 32.067094114919584],
[41, 32.08904222150652, 32.100128983457964]]

我們從數(shù)據(jù)可以看到,,最后播放到了32秒。也就說我們AI生成的這段600多個音符的樂曲,,可以播放32秒,。

聽一聽效果,那就把它寫入MIDI文件吧,。

# 寫入midi文件
pm = pretty_midi.PrettyMIDI()
instrument = pretty_midi.Instrument(
program=pretty_midi.instrument_name_to_program("Acoustic Grand Piano"))
for n in midi_notes:
note = pretty_midi.Note(velocity=100,pitch=n[0],start=n[1],end=n[2])
instrument.notes.append(note)
pm.instruments.append(instrument)
pm.write("out.midi")

MIDI文件有5個必需的要素,。其中,樂器我們設(shè)置為"Acoustic Grand Piano"原聲大鋼琴,。velocity沒有參與訓練,,但也需要,我們設(shè)為固定值100,。其他的3個參數(shù),,都是AI生成的,依次代入,。最后,,把結(jié)果生成到out.midi文件中,。

使用Window自帶的Media Player就可以直接播放這個文件。你聽不到,,我可以替你聽一聽。

聽完了,,我談下感受吧,。

怎么描述呢?我覺得,,說好聽對不起良心,,反正,不難聽,。

好了,,AI作曲就到此為止了。

源代碼已上傳到GitHub地址是:https://github.com/hlwgy/ai_music,。

做完了,,我還得去找老張談談。

四,、合作:你果然還是這樣的老張

我騎電動車去找老張,,我告訴他,AI作曲哥們搞定了,。

老張問我,,你陽了沒有。

我說,,沒有,。

老張告訴我,他表弟陽了,。

我說,,你不用擔心,畢竟你們離得那么遠,。

老張說,,他陽了后,我們的項目也泡湯了,。

我問為什么,。

老張說:我談好的那家飯店,就是表弟開的,。他陽了之后,,現(xiàn)在不承認了。

我的電腦還停留在開機界面,,我強制關(guān)機,。走了,。

我記得,上一次,,我告訴老張,,三個月不要聯(lián)系我《老張讓我用TensorFlow識別語音命令》。

而這一次,,我什么也沒有說,。就走了。

我是ITF男孩,,帶你從IT視角看世界,。

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多