自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何使用神經(jīng)網(wǎng)絡(luò)彈奏出帶情感的音樂?

開發(fā) 開發(fā)工具
神經(jīng)網(wǎng)絡(luò)在音樂方面的應(yīng)用已經(jīng)不是一個(gè)新鮮的話題了。在音頻檢索領(lǐng)域中,人們一直在嘗試著用神經(jīng)網(wǎng)絡(luò)對(duì)一系列音樂元素進(jìn)行建模。

神經(jīng)網(wǎng)絡(luò)在音樂方面的應(yīng)用已經(jīng)不是一個(gè)新鮮的話題了。在音頻檢索領(lǐng)域中,人們一直在嘗試著用神經(jīng)網(wǎng)絡(luò)對(duì)一系列音樂元素進(jìn)行建模 [1],例如和弦、音高等等。正如作者所提及的,人們?cè)?1943 年開始用神經(jīng)網(wǎng)絡(luò)解決語音識(shí)別的問題。但是在那個(gè)年代,沒有足夠的計(jì)算能力來得到較好的結(jié)果,所以神經(jīng)網(wǎng)絡(luò)的方法在那個(gè)時(shí)候并不流行。而現(xiàn)在,由于 GPU 計(jì)算資源和可獲得的大數(shù)據(jù),結(jié)果可以變得相當(dāng)好,于是作者就希望使用像圖 1 中的神經(jīng)網(wǎng)絡(luò)來進(jìn)行一個(gè)音樂實(shí)驗(yàn),來實(shí)現(xiàn)音樂風(fēng)格的神經(jīng)轉(zhuǎn)換。在這篇文章中,作者給出了非常詳細(xì)的分析和什么會(huì)這樣思考,本文也表明使用作者提出的方法,我們可以得到良好的結(jié)果。

深度神經(jīng)網(wǎng)絡(luò)

圖 1. 深度神經(jīng)網(wǎng)絡(luò)

音樂和神經(jīng)網(wǎng)絡(luò)

谷歌的一個(gè)名為 Google Magenta[2] 的項(xiàng)目正在使用 AI 作曲家來產(chǎn)生開創(chuàng)性的結(jié)果,它使用神經(jīng)網(wǎng)絡(luò)來生成旋律。這證明了神經(jīng)網(wǎng)絡(luò)是成功的應(yīng)用。其驚人的性能讓作者認(rèn)為神經(jīng)網(wǎng)絡(luò)還可以做一些有趣的音樂預(yù)測。

隨后作者分析了音樂中的兩個(gè)重要元素,音樂構(gòu)成和音樂表現(xiàn)。音樂構(gòu)成關(guān)注的是音樂本身,它的指的是能夠定義一首歌曲的音符。如作者所說,你可以將它看作是圖 2 中的樂譜。

一段樂譜圖

圖 2. 一段樂譜圖

然而這對(duì)音樂家而言只是***步。這些樂譜如何被演奏家演奏,這才是音樂工作的靈魂。因?yàn)檠葑嗾哐葑嗾哐葑嗟酶鞑幌嗤晕覀冇靡魳凤L(fēng)格來描述個(gè)人化的音樂演奏。

什么是音樂風(fēng)格

音樂風(fēng)格很難定義,因?yàn)椴荒馨岩魳凤L(fēng)格像音高一樣被參數(shù)化。如果你曾聽過很多經(jīng)典的鋼琴曲,那么你會(huì)發(fā)現(xiàn)一個(gè)新手和一個(gè)資深的鋼琴家會(huì)奏出大不相同的強(qiáng)弱力度(dynamics),這里指的是音樂響度的變化。一個(gè)音符的響度可以通過控制敲擊琴鍵的輕重程度來實(shí)現(xiàn)。在音樂符號(hào)中這些不同級(jí)別的強(qiáng)弱力度一般用意大利字母表示。這些字母被稱為情感符。不同的人會(huì)有不同的感覺,所以這里的特定的強(qiáng)弱集合都有著各自的情感表現(xiàn)。因此情感表現(xiàn)就意味著一組***的強(qiáng)弱力度,而強(qiáng)弱力度也就成了風(fēng)格的重要特征。

樂譜中的強(qiáng)弱力度范圍

圖 3:樂譜中的強(qiáng)弱力度范圍

此外,人們還用一些流派來標(biāo)記音樂,例如經(jīng)典音樂、爵士音樂等等。由此我們可以發(fā)現(xiàn),在一些特定的音樂風(fēng)格中是存在一些規(guī)則的,因此人們可以通過強(qiáng)弱力度來識(shí)別音樂風(fēng)格。這也意味著人么可以用流派來歸類音樂風(fēng)格。

我們可以拿強(qiáng)弱力度來干什么?

在參考文獻(xiàn) [3,4,5] 中,他們?cè)趪L試著生成音樂構(gòu)成的那一部分,但是并沒有音樂表現(xiàn)的那一部分。所以作者在這篇文章中通過添加強(qiáng)弱信息使用樂器數(shù)字接口(MIDI)來像人一樣演奏音樂。

是人還是機(jī)器人在演奏呢?

作者設(shè)計(jì)并訓(xùn)練模型來為活頁樂譜合成強(qiáng)弱力度(dynamics)。作者展示了一種樂譜的兩個(gè)不同的演奏,其中一個(gè)來自于人,另一個(gè)來自于機(jī)器。并進(jìn)行了盲測,即看一看你能不能區(qū)分出哪一個(gè)是人演奏的,哪一個(gè)是機(jī)器演奏的。如作者提到的那樣。只有不到一半的受試者能夠正確地區(qū)分出來。我也聽過這兩種音樂,不幸的是,我能夠很輕易地區(qū)分出來哪一個(gè)是人演奏的。因?yàn)橛蓹C(jī)器演奏的那一段中仍然存在很奇怪的強(qiáng)弱力度,并且我能夠確保人類不會(huì)做出那樣的演奏。即便如此,這個(gè)結(jié)果還是足以令人印象深刻了。

背景知識(shí)

1. 神經(jīng)元

圖 4 所示是神經(jīng)網(wǎng)絡(luò)中最基本的計(jì)算單元--神經(jīng)元。

人工神經(jīng)元

圖 4. 人工神經(jīng)元

輸入與對(duì)應(yīng)權(quán)重 w 的乘積和,然后再加上偏置單元 b。凈輸入可以通過方程 1 計(jì)算得到:

神經(jīng)元的輸出通過使用方程 2 所示的激活函數(shù) g() 來計(jì)算:

Sigmoid 函數(shù)是最常用的激活函數(shù)。這個(gè)函數(shù)將任意實(shí)數(shù)作為輸入,并將它們壓縮在 0 到 1 之間。我們可以在圖 5 中看到,一個(gè)很小的數(shù)字可以被替代成接近于 0 的結(jié)果,一個(gè)很大的數(shù)字可以被替代為接近于 1 的結(jié)果。其他常見的激活函數(shù)還有 Tanh 和 Relu。

sigmoid 激活函數(shù)

圖 5. sigmoid 激活函數(shù)

2. 前饋神經(jīng)網(wǎng)絡(luò)

前饋神經(jīng)網(wǎng)絡(luò)(FNN)是最常用的結(jié)構(gòu)。神經(jīng)元逐層相連。***層是輸入層,***一層是輸出層。輸入層和輸出層之間是隱藏層。圖 6 所示是一個(gè)只有一層隱藏層的前饋神經(jīng)網(wǎng)絡(luò)。在前饋神經(jīng)網(wǎng)絡(luò)中有一個(gè)假設(shè):即每一個(gè)輸入都是和其余輸入相互獨(dú)立。

前饋神經(jīng)網(wǎng)絡(luò)

前饋神經(jīng)網(wǎng)絡(luò)

3. 循環(huán)神經(jīng)網(wǎng)絡(luò)

一個(gè)簡單的前饋神經(jīng)網(wǎng)絡(luò)的主要局限性是缺乏記憶。這是因?yàn)榍梆伾窠?jīng)網(wǎng)絡(luò)假設(shè)輸入之間是彼此獨(dú)立的。但是在音樂中,樂譜是在全局結(jié)構(gòu)下寫成的,因?yàn)橐魳芳沂腔谒胍磉_(dá)的某種情感來譜曲的,所以音符序列不能簡單地認(rèn)為音符序列是獨(dú)立的。循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)可以解決這類問題。循環(huán)神經(jīng)網(wǎng)絡(luò)有狀態(tài)(states),以及一個(gè)被稱作循環(huán)權(quán)重的反饋回路。這個(gè)結(jié)構(gòu)在計(jì)算當(dāng)前輸出的時(shí)候還利用了前一時(shí)刻的狀態(tài)。這意味著循環(huán)神經(jīng)網(wǎng)絡(luò)有一個(gè)短期記憶機(jī)制來記住過去的計(jì)算結(jié)果,并將它用來計(jì)算當(dāng)前的結(jié)果。圖 7 展示了這個(gè)機(jī)制。

按時(shí)間展開的循環(huán)神經(jīng)網(wǎng)絡(luò)

圖 7. 按時(shí)間展開的循環(huán)神經(jīng)網(wǎng)絡(luò)

4. 雙向循環(huán)神經(jīng)網(wǎng)絡(luò)

音樂家有能力預(yù)測樂譜中的走向,這有助于對(duì)即將到來的情感符號(hào)做好準(zhǔn)備。但是對(duì)于簡單的循環(huán)神經(jīng)網(wǎng)絡(luò)而言,它是按順序讀取輸入的。所以需要有一個(gè)能夠訪問即將到來時(shí)間步驟的神經(jīng)網(wǎng)絡(luò)。有一種叫做雙向循環(huán)神經(jīng)網(wǎng)絡(luò)(Bi-Directional RNN)的結(jié)構(gòu)。如圖 8 所示,這個(gè)結(jié)構(gòu)結(jié)合了兩個(gè)循環(huán)神經(jīng)網(wǎng)絡(luò)層。

 雙向循環(huán)神經(jīng)網(wǎng)絡(luò)

圖 8. 雙向循環(huán)神經(jīng)網(wǎng)絡(luò)

***層被稱為前向?qū)?,它以原始的順序讀取輸入。第二層叫做反向?qū)樱苑聪蝽樞蜃x取輸入。對(duì)于作者提出的目標(biāo)而言,這個(gè)結(jié)構(gòu)貌似是一個(gè)不錯(cuò)的選擇。

5. 長短期記憶網(wǎng)絡(luò)

根據(jù)參考文獻(xiàn) [7,8],循環(huán)神經(jīng)網(wǎng)絡(luò)***的問題就是它無法記住長期依賴的關(guān)系。為了解決這個(gè)問題,文獻(xiàn) [9] 中提出了長短期記憶網(wǎng)絡(luò)(LSTM),為了控制類似于該記住多少,該遺忘多少的問題,LSTM 中提供了門控機(jī)制。

一個(gè) LSTM 單元

圖 9. 一個(gè) LSTM 單元

架構(gòu)設(shè)計(jì)

***我們開始設(shè)計(jì)整個(gè)系統(tǒng)的架構(gòu)。作者在這篇文章中使用了雙向-長短期記憶網(wǎng)絡(luò)(Bi-Directional LSTM)。分別用兩個(gè)網(wǎng)絡(luò)實(shí)現(xiàn)對(duì)音樂流派和風(fēng)格的分析,分別叫做 GenreNet 和 StyleNet。

1. GenreNet

流派具有可定義的音樂風(fēng)格,所以作者使用這個(gè)特點(diǎn)來設(shè)計(jì)學(xué)習(xí)一首樂曲演奏強(qiáng)弱力度的基本模型。如圖 10 所示,這個(gè)模型中有兩個(gè)主要的層:雙向 LSTM(Bi-Directional LSTM)和線性層。

GenreNet

圖10. GenreNet

雙向 LSTM 層結(jié)合了 LSTM 網(wǎng)絡(luò)的優(yōu)點(diǎn),它對(duì)學(xué)習(xí)相關(guān)的依賴提供了記憶,雙向結(jié)構(gòu)還使得模型在學(xué)習(xí)的時(shí)候同時(shí)考慮了未來的信息。這使得模型的輸出可以作為另一層網(wǎng)絡(luò)的輸入。線性層就是被用來把雙向 LSTM 的輸出值的范圍從 [-1,1] 變得更大。

2. StyleNet

這個(gè)網(wǎng)絡(luò)被用來學(xué)習(xí)一些在 Genre 網(wǎng)絡(luò)上無法訓(xùn)練得到的更加復(fù)雜的風(fēng)格信息。StyleNet 中有 GenreNet 的子網(wǎng)絡(luò),它們被用在 StyleNet 中來學(xué)習(xí)特定流派的風(fēng)格。在 StyleNet 中,有一個(gè)解釋層,它可以被 GenreNet 子網(wǎng)絡(luò)共享。這大大減少了網(wǎng)絡(luò)需要學(xué)習(xí)的參數(shù)。并且 StyleNet 就像是一個(gè)能夠?qū)⒁魳忿D(zhuǎn)換為不同風(fēng)格的轉(zhuǎn)換工具。如圖 11 所示,這是一個(gè)多任務(wù)學(xué)習(xí)模型。

 StyleNet

圖 11. StyleNet

3. 數(shù)據(jù)

作者在這篇文章中使用了 MIDI 格式的音樂文件,因?yàn)檫@種格式的文件包含了音樂屬性。有一個(gè)叫做速率(velocity)的參數(shù)來存儲(chǔ)強(qiáng)弱力度。它類似于音量,但是取值范圍在 0~127 之間。作者在本文中用速率來檢測強(qiáng)弱力度。

在本文中,作者創(chuàng)建了一個(gè)鋼琴數(shù)據(jù)集。MIDI 文件的流派被限定在經(jīng)典和爵士這兩種里面。作者采用的 MIDI 文件全部來自于雅馬哈鋼琴電子競賽。如圖 12 所示,通常情況人類表演至少擁有 45 中不同的速率。作者將不同速率的數(shù)量的最小閾值設(shè)置為 20。

 左:下載到的 MIDI 文件中的速率的數(shù)量。右:表演 MIDI 文件中速率的數(shù)量

圖 12. 左:下載到的 MIDI 文件中的速率的數(shù)量。右:表演 MIDI 文件中速率的數(shù)量

 

***,我們我們?cè)谶@篇文章中選擇了 4/4 拍,因?yàn)樗亲畛R姷囊环N節(jié)拍,所以作者可以擁有比其他節(jié)拍更多的數(shù)據(jù)。

我們所用的數(shù)據(jù)集總共包含 349 個(gè)經(jīng)典曲鋼琴曲和爵士鋼琴曲。

MIDI 編碼方案

在得到了鋼琴數(shù)據(jù)集之后,接下來的一部就是設(shè)計(jì)輸入輸出矩陣。

1. 量化

首先,數(shù)據(jù)集應(yīng)該被量化,這使得作者能夠拿矩陣來表征樂譜。但是但是這樣做會(huì)導(dǎo)致一個(gè)結(jié)果,那就是我們會(huì)丟失樂譜相關(guān)的定時(shí)信息。文章中作者將樂譜的時(shí)間戳近似到了最接近的第 1/16 個(gè)音符。然后我們呢就可以捕獲樂譜。圖 13 展示了量化之前和量化之后的樂譜表征的不同。

量化

圖 13. 量化

2. 輸入矩陣表征

輸入將會(huì)攜帶有關(guān)樂譜音高、開始時(shí)間以及結(jié)束時(shí)間等相關(guān)信息。樂譜總共有三個(gè)狀態(tài),所以作者使用二進(jìn)制向量來表示這三個(gè)狀態(tài)?!竜n」被編碼為 [1,1],「sustained」被編碼為 [0,1],「off」被編碼為 [0,0]。

樂譜音高也需要被編碼,我們會(huì)創(chuàng)建一個(gè)矩陣,其中***維是關(guān)于 MIDI 音高數(shù)量的值,第二維是關(guān)于 1/16 音符量化為時(shí)間步驟的值。這些在圖 14 中可以看到。

輸入輸出表征

圖 14. 輸入輸出表征

3. 輸出矩陣的表征

輸出矩陣攜帶著輸入的速率。如圖 14 所示,矩陣的列也表示音高,行表示時(shí)間步驟。音高維度只有 88 個(gè)音符,因?yàn)槲覀冞@次只需要表示速率。然后我們以***的速率 127 把數(shù)據(jù)進(jìn)行分割,***輸出速率被解碼為一個(gè) MIDI 文件。

訓(xùn)練

作者給出了訓(xùn)練網(wǎng)絡(luò)的每一個(gè)細(xì)節(jié)過程。這里我僅僅向你們展示一些關(guān)鍵步驟。輸入應(yīng)該是 176 個(gè)節(jié)點(diǎn)的寬度和一層的深度。用 tensorflow 建立具有兩個(gè) GenreNet 單元的模型(經(jīng)典和爵士)。每一個(gè) GenreNet 有 3 層。使用 Mini-batch,大小為 4。將學(xué)習(xí)率設(shè)置為 0.001. 使用 Adam 優(yōu)化器來進(jìn)行隨機(jī)優(yōu)化。作者使用數(shù)據(jù)集中的 95% 來訓(xùn)練,剩下的 5% 來做驗(yàn)證。另外,在如圖 15 所示的實(shí)驗(yàn)中,dropout rate 設(shè)置為 0.8。這樣的 dropout rate 使模型能夠?qū)W到潛在的模式。模型被訓(xùn)練了 160 個(gè) epoch,最終的損失值和驗(yàn)證損失值分別為 0.0007 和 0.001。

訓(xùn)練誤差和驗(yàn)證誤差

在圖 16 中,作者展示了訓(xùn)練誤差和驗(yàn)證誤差。

訓(xùn)練誤差率和驗(yàn)證誤差率

圖 16. 訓(xùn)練誤差率和驗(yàn)證誤差率

作者還展示了很多訓(xùn)練過程的快照,所以我們可以在快照中發(fā)現(xiàn)經(jīng)典音樂和爵士音樂的不同。圖 17 是快照之一。

 訓(xùn)練過程的一次快照

圖 17. 訓(xùn)練過程的一次快照

結(jié)果

測試結(jié)果的關(guān)鍵就是看看 StyleNet 是否能夠生成像人一樣的表演。作者在這里使用了圖靈測試來測試結(jié)果 [11]。作者組織了一個(gè)叫做「鑒別人類演奏」的調(diào)查。這兩部分總共有 9 個(gè)問題,如圖 18 所示,參與者需要在 10 秒內(nèi)聽完一個(gè)音樂片段。

 [鑒別人類演奏] 測試

圖 18. [鑒別人類演奏] 測試

在測試中參與者需要鑒別出人類的演奏。如圖 19 所示,大約平均 53% 的參與者能夠聽出人類的演奏。

[鑒別人類的演奏] 測試結(jié)果

圖 19. [鑒別人類的演奏] 測試結(jié)果

為了讓這個(gè)調(diào)查更加完整,作者還添加了一項(xiàng)名為「不能確定」的選項(xiàng)來確保參與者不是在瞎蒙。如圖 20 所示,這一次作者發(fā)現(xiàn)只有 46% 的人能夠鑒別出人類的演奏。這意味著 StyleNet 模型能夠通過圖靈測試,它可以生成與人類并無區(qū)別的演奏。

最終鑒別測試結(jié)果

圖 20. 最終鑒別測試結(jié)果

我學(xué)會(huì)演奏小提琴已經(jīng)有 19 年了,所以我特別贊同作者關(guān)于音樂的兩大元素的觀點(diǎn),也就是說,音樂構(gòu)成和音樂表現(xiàn)。有時(shí)候表演會(huì)更加困難一些。在聽完生成的演奏之后,我覺得 StyleNet 的表演的確是令人印象深刻的。我認(rèn)為如果音符量化能夠做的更小,例如 1/32 甚至 1/64,那么它有可能得到更好的結(jié)果。此外,我覺得其中的一項(xiàng)挑戰(zhàn)就是你并不能確保 StyleNet 從人類的表演中學(xué)到了正確的風(fēng)格。在作者提供的測試中,我能夠正確地分辨出人類的演奏的原因就是仍然有一部分音符的細(xì)節(jié)并沒被網(wǎng)絡(luò)學(xué)習(xí)到,而這些細(xì)節(jié)正是我用來判斷一段音樂是不是人類演奏的關(guān)鍵。我的建議是讓音樂家去聽 StyleNet 生成的音頻,我相信他們能夠給出一些專業(yè)的建議,然后這些專業(yè)的建議會(huì)幫助網(wǎng)絡(luò)學(xué)習(xí)得更好。

我還想將作者提出的工作與計(jì)算機(jī)視覺中的風(fēng)格變換 [12,13] 做一個(gè)對(duì)比。他們的基本方法是相似的:它們都是用了兩個(gè)與風(fēng)格對(duì)應(yīng)的網(wǎng)絡(luò),其他的都用于內(nèi)容。但是對(duì)于圖像的風(fēng)格轉(zhuǎn)換,這兩個(gè)網(wǎng)絡(luò)的不同點(diǎn)是很大的(一個(gè)用于內(nèi)容重建,另一個(gè)用于風(fēng)格重建)。對(duì)于內(nèi)容重建,它會(huì)通過計(jì)算不同子集的卷積神經(jīng)網(wǎng)絡(luò)捕捉不同尺寸的空間特征而生成,例如:conv1_1,[conv1_1, conv2_1],[conv1_1, conv2_1, conv3_1],[conv1_1, conv2_1, conv3_1,conv4_1],[conv1_1, conv2_1, conv3_1, conv4_1, conv5_1]。而在音樂的例子中,我認(rèn)為使用 LSTM 生成音樂的主要思想就是捕捉音樂風(fēng)格和音樂表現(xiàn)中的特征??偨Y(jié)一下:卷積神經(jīng)網(wǎng)絡(luò)是典型的空間深度神經(jīng)網(wǎng)絡(luò),循環(huán)神經(jīng)網(wǎng)絡(luò)是典型的時(shí)間深度神經(jīng)網(wǎng)絡(luò)。在使用卷積神經(jīng)網(wǎng)絡(luò)的時(shí)候,我們應(yīng)該關(guān)注空間映射,圖像特別適合這個(gè)場景。然而對(duì)于音樂,我們需要對(duì)時(shí)間序列做分析,所以我們使用了循環(huán)神經(jīng)網(wǎng)絡(luò)。

【本文是51CTO專欄機(jī)構(gòu)“機(jī)器之心”的原創(chuàng)文章,微信公眾號(hào)“機(jī)器之心( id: almosthuman2014)”】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2020-08-06 10:11:13

神經(jīng)網(wǎng)絡(luò)機(jī)器學(xué)習(xí)算法

2018-07-03 16:10:04

神經(jīng)網(wǎng)絡(luò)生物神經(jīng)網(wǎng)絡(luò)人工神經(jīng)網(wǎng)絡(luò)

2017-03-27 16:18:30

神經(jīng)網(wǎng)絡(luò)TensorFlow人工智能

2025-02-25 14:13:31

2017-08-29 13:50:03

TensorFlow深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)

2023-10-29 18:08:33

GPU神經(jīng)網(wǎng)絡(luò)CPU

2017-09-28 16:15:12

神經(jīng)網(wǎng)絡(luò)訓(xùn)練多層

2017-04-26 08:31:10

神經(jīng)網(wǎng)絡(luò)自然語言PyTorch

2023-05-12 14:58:50

Java神經(jīng)網(wǎng)絡(luò)深度學(xué)習(xí)

2018-08-13 09:00:00

人工智能機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)

2025-02-24 08:00:00

機(jī)器學(xué)習(xí)ML架構(gòu)

2017-08-28 21:31:37

TensorFlow深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)

2017-04-26 09:30:53

卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

2017-09-10 07:07:32

神經(jīng)網(wǎng)絡(luò)數(shù)據(jù)集可視化

2023-06-18 23:00:39

神經(jīng)網(wǎng)絡(luò)損失函數(shù)隨機(jī)變量

2019-06-06 09:00:02

卷積神經(jīng)網(wǎng)絡(luò)CNNAI

2017-03-21 08:52:20

神經(jīng)網(wǎng)絡(luò)聲譽(yù)

2023-11-14 16:29:14

深度學(xué)習(xí)

2017-11-30 18:05:18

2021-01-18 14:38:53

神經(jīng)網(wǎng)絡(luò)人工智能神經(jīng)元
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)