偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

新聞 人工智能
柏林工業(yè)大學(xué)深度學(xué)習(xí)方向博士生 Tilman Krokotsch 在多項(xiàng)任務(wù)中對(duì)比了 8 種自編碼器的性能。

 柏林工業(yè)大學(xué)深度學(xué)習(xí)方向博士生 Tilman Krokotsch 在多項(xiàng)任務(wù)中對(duì)比了 8 種自編碼器的性能。

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

深度學(xué)習(xí)中的自編碼器。圖源:https://debuggercafe.com/autoencoders-in-deep-learning/

目前,很多研究者仍在使用堆疊自編碼器進(jìn)行無監(jiān)督預(yù)訓(xùn)練。柏林工業(yè)大學(xué)深度學(xué)習(xí)方向博士生 Tilman Krokotsch 對(duì)此感到疑惑:堆疊自編碼器難道不是算力低下時(shí)代訓(xùn)練深度模型的變通方案嗎?現(xiàn)在算力相對(duì)充足了,為什么還要用?

于是,他決定在多項(xiàng)不同任務(wù)中對(duì)比原版深度自編碼器(AE)和堆疊自編碼器。

項(xiàng)目地址:https://github.com/tilman151/ae_bakeoff

Krokotsch 對(duì)比了原版深度自編碼器所有改變潛在空間行為方式或有可能提升下游任務(wù)性能的變體,不包括應(yīng)用特定的損失(如圖像領(lǐng)域的 VGG19 損失)和編碼器與解碼器類型(如 LSTM vs. CNN)。最終,Krokotsch 選擇了以下八種自編碼器進(jìn)行對(duì)比:

  • 淺層自編碼器
  • 深度自編碼器(原版 AE)
  • 堆疊自編碼器
  • 稀疏自編碼器
  • 去噪自編碼器
  • 變分自編碼器(VAE)
  • Beta 變分自編碼器(beta-VAE)
  • 向量量化變分自編碼器(vq-VAE)

Krokotsch 不僅介紹了這些自編碼器的獨(dú)特性,還在以下方面進(jìn)行了對(duì)比:

  • 重建質(zhì)量
  • 對(duì)來自潛在空間的樣本的解碼質(zhì)量
  • 潛在空間插值質(zhì)量
  • 利用 UMAP 可視化得到的潛在空間結(jié)構(gòu)
  • 利用重建誤差的異常檢測 ROC 曲線
  • 擬合自編碼器特征的線性層的分類準(zhǔn)確率

所有自編碼器均使用相同的簡單架構(gòu),該架構(gòu)使用全連接編解碼器、批歸一化和 ReLU 激活函數(shù),輸出層使用 sigmoid 激活函數(shù)。除了淺層自編碼器以外,所有自編碼器均具備三個(gè)編碼器和解碼器層。

潛在空間的維度和網(wǎng)絡(luò)參數(shù)量基本恒定。這意味著變分自編碼器比原版有更多參數(shù),因?yàn)榫幋a器為維度為 n 的潛在空間生成 2n 個(gè)輸出。在測試過程中,每個(gè)自編碼器執(zhí)行兩次訓(xùn)練運(yùn)行:一次潛在空間的維度為 20,一次維度為 2。第二次訓(xùn)練的模型用于異常檢測,第一次的模型用于其他任務(wù)。

對(duì)比測試使用的數(shù)據(jù)集為 MNIST。Krokotsch 從訓(xùn)練數(shù)據(jù)集中隨機(jī)采樣 5000 個(gè)樣本作為驗(yàn)證集,將默認(rèn)訓(xùn)練 / 測試分割進(jìn)一步劃分為訓(xùn)練 / 驗(yàn)證 / 測試分割。

接下來我們來看這些自編碼器變體及其對(duì)比情況。

「參賽選手」:8 個(gè)自編碼器

Krokotsch 介紹了這些自編碼器的工作原理及獨(dú)特性,并嘗試對(duì)其性能做出一些假設(shè)。

淺層自編碼器

淺層自編碼器算不上真的競爭對(duì)手,因?yàn)樗哪芰h(yuǎn)遠(yuǎn)落后于其他變體。在這里,它作為基線存在。

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

上式為淺層自編碼器的重建公式,從中可以看出自編碼器如何以半數(shù)學(xué)的方式重建樣本 x。

淺層自編碼器的特點(diǎn)是編碼器和解碼器中只有一個(gè)層。它與 PCA 的區(qū)別是在編碼器中使用 ReLU 激活函數(shù),在解碼器中使用 sigmoid 函數(shù),因此它是非線性的。

一般情況下,自編碼器的默認(rèn)重建損失是均方誤差。而 Krokotsch 使用的是二值交叉熵 (binary cross-entropy, BCE),因?yàn)樗茉诔醪綄?shí)驗(yàn)中獲得更美觀的圖像。所有自編碼器均使用以下 BCE 版本:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

其中 x^(i)_j 是第 i 個(gè)輸入圖像的第 j 個(gè)像素,x̂^(i)_j 是對(duì)應(yīng)的重建。損失即匯總每張圖像再基于 batch 求平均。這一決策對(duì)于變分自編碼器非常重要。

深度自編碼器

深度自編碼器(原版自編碼器)是淺層自編碼器的擴(kuò)大版。它們基本相同,只不過深度自編碼器擁有更多層。它們的重建公式是一樣的。

深度自編碼器的潛在空間沒有約束,因此應(yīng)當(dāng)能夠編碼最多信息。

堆疊自編碼器

堆疊自編碼器即通過僅訓(xùn)練淺層自編碼器來得到深度自編碼器。只不過訓(xùn)練方式不是端到端,而是逐層貪婪訓(xùn)練:首先,以第一個(gè)編碼器和最后一個(gè)解碼器形成一個(gè)淺層自編碼器;訓(xùn)練完這些層之后,使用編碼層編碼整個(gè)數(shù)據(jù)集;然后基于第二個(gè)編碼器和倒數(shù)第二個(gè)解碼器層形成另一個(gè)淺層自編碼器,使用編碼得到的數(shù)據(jù)集訓(xùn)練第二個(gè)淺層自編碼器;重復(fù)這一過程,直到到達(dá)最內(nèi)層。最終得到的深度自編碼器由許多個(gè)淺層自編碼器堆疊而成。

堆疊自編碼器與深度自編碼器只在訓(xùn)練過程上存在區(qū)別,因此它們也具備相同的重建函數(shù)。堆疊自編碼器的潛在空間沒有約束,但是由于貪婪訓(xùn)練,其編碼能力略差。

稀疏自編碼器

稀疏自編碼器在潛碼方面存在稀疏約束,潛碼中每個(gè)元素的活躍概率為 p。為此在訓(xùn)練過程中需要為其添加輔助損失:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

其中 z¯(i) 是潛碼中第 i 個(gè)元素基于 batch 的平均激活值。這一損失函數(shù)對(duì)應(yīng)于 p 和 z¯(i) 二項(xiàng)式分布之間的 KL 散度 |z| 的總和??赡艽嬖谄渌麑?shí)現(xiàn),可以滿足該稀疏約束。

為了使該稀疏損失成為可能,我們需要將潛碼的范圍縮放至 [0,1],以便將其理解為概率。這通過 sigmoid 激活函數(shù)完成,重建公式如下:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

稀疏自編碼器的完整損失結(jié)合了重建損失和稀疏損失:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

在所有實(shí)驗(yàn)中,p 值設(shè)置為 0.25,β 值設(shè)置為 1。

去噪自編碼器

去噪自編碼器的潛在空間沒有約束,它旨在通過對(duì)輸入數(shù)據(jù)應(yīng)用噪聲來學(xué)習(xí)更高效的編碼。去噪自編碼器并未將輸入數(shù)據(jù)直接饋入網(wǎng)絡(luò),而是添加了高斯噪聲:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

其中 clip 表示將輸入裁剪為 [0,1],標(biāo)量 β 表示噪聲的方差。因此,去噪自編碼器的訓(xùn)練方式是基于噪聲輸入數(shù)據(jù)重建干凈樣本,重建公式如下:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

不過,噪聲輸入僅在訓(xùn)練過程中使用。在評(píng)估該自編碼器時(shí),使用的是原始輸入數(shù)據(jù)。去噪自編碼器使用的損失函數(shù)與之前的自編碼器相同。在所有實(shí)驗(yàn)中, β 值被設(shè)置為 0.5。

變分自編碼器

理論上,變分自編碼器 (VAE) 與原版 AE 關(guān)聯(lián)不大。但在實(shí)踐中,其實(shí)現(xiàn)和訓(xùn)練均很類似。VAE 將重建解釋為隨機(jī)過程,使之具備不確定性。編碼器不輸出潛碼,而是輸出表示潛碼概率分布的參數(shù);然后,解碼器從這一分布中接收樣本。默認(rèn)的分布族選擇是高斯 N(μ;diag⁡(Σ))。其重建公式如下:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

其中 enc_μ(x) 和 enc_Σ(x) 將 x 編碼為μ 和 Σ,兩個(gè)編碼器共享大部分參數(shù)。在實(shí)踐中,單個(gè)編碼器獲得兩個(gè)輸出層而不是一個(gè)。問題在于,從分布中采樣必須要具備梯度和從解碼器到編碼器的反向傳播。解決方法叫做「重參數(shù)化」,將來自標(biāo)準(zhǔn)高斯分布的樣本轉(zhuǎn)換為來自被 μ 和 Σ 參數(shù)化的高斯分布的樣本:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

該公式的梯度與 μ 和 Σ 有關(guān),也可以實(shí)現(xiàn)反向傳播。

變分自編碼器要求高斯分布類似于標(biāo)準(zhǔn)高斯,從而進(jìn)一步約束其潛在空間。其分布參數(shù)接受 KL 散度的懲罰:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

KL 散度基于 batch 求平均值。重建損失按照上文方式求平均,以保留重建損失和散度損失之間正確的比率。完整訓(xùn)練損失如下:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

我們盡量使編碼器輸出標(biāo)準(zhǔn)高斯,這樣就可以直接解碼來自標(biāo)準(zhǔn)高斯分布的樣本。這種無條件采樣是 VAE 的一種獨(dú)特屬性,使其成為類似 GAN 的生成模型。無條件采樣的公式如下:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

Beta 變分自編碼器(beta-VAE)

beta-VAE 是 VAE 的泛化,只改變了重建損失和散度損失之間的比率。散度損失的影響因子用標(biāo)量 β 來表示,因此損失函數(shù)如下所示:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

β<1 放松了對(duì)潛在空間的約束,而 β>1 則加劇了這一約束。前者會(huì)得到更好的重建結(jié)果,后者則得到更好的無條件采樣。Krokotsc 在嚴(yán)格版本中使用了 β=2,在寬松版本中使用了 β=0.5。

向量量化變分自編碼器(vq-VAE)

vq-VAE 使用均勻的類別分布來生成潛碼。編碼器輸出中的每個(gè)元素都被該分布中的類別值取代,后者是其最近鄰。這是一種量化,意味著潛在空間不再是連續(xù)的,而是離散的。

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

類別本身可以通過將誤差平方和最小化為編碼器輸出來學(xué)得:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

其中 z 表示編碼器的輸出,ẑ 表示對(duì)應(yīng)的量化后潛碼,sg 表示停止梯度算子(stop gradient operator)。另外,編碼器輸出的編碼結(jié)果類似于通過誤差平方和得到的類別:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

這叫做 commitment 損失。KL 散度損失并非必要,因?yàn)?KL 散度是均勻類別分布的的常量。將這種損失與重建損失結(jié)合起來,得到:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

實(shí)驗(yàn)中將 β 的值設(shè)置為 1。

由于 vq-VAE 是生成模型,我們也可以執(zhí)行無條件采樣。

自編碼器「大亂斗」

重建質(zhì)量

首先,我們來看每種自編碼器對(duì)輸入的重建質(zhì)量。以下是不同自編碼器在 MNIST 測試集中 16 張圖像上的結(jié)果:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器
無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

淺層自編碼器無法準(zhǔn)確重建一些測試樣本。4 和 9 勉強(qiáng)可以辨認(rèn),一些數(shù)字則完全看不出來。其他自編碼器的效果要好一些,但也并不完美:去噪自編碼器會(huì)使一些細(xì)線消失;稀疏和堆疊自編碼器則在重建筆畫異常的數(shù)字(如 5 和第一個(gè) 9)。整體的重建結(jié)果都有一點(diǎn)模糊,這對(duì)于自編碼器而言是正常的。vq-VAE 的重建結(jié)果沒有那么模糊,其作者認(rèn)為這是離散潛在空間的緣故。

不同自編碼器的重建質(zhì)量區(qū)別不大。下表列舉了基于樣本集合的二值交叉熵平均值:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

不出所料,表現(xiàn)最差的是淺層自編碼器,它缺乏捕捉 MNIST 結(jié)構(gòu)的能力。原版自編碼器表現(xiàn)不錯(cuò),與稀疏自編碼器和 vq-VAE 名列前茅。但稀疏自編碼器和 vq-VAE 似乎并未經(jīng)歷潛在空間約束,而 VAE 和 beta-VAE 由于潛在空間約束獲得了更高的誤差。此外,VAE 中的采樣過程引入了損害重建誤差的噪聲。

采樣

該試驗(yàn)僅包括四個(gè)可執(zhí)行無條件采樣的自編碼器:VAE、寬松和嚴(yán)格版本的 beta-VAE、vq-VAE。對(duì)每個(gè)自編碼器,采樣 16 個(gè)潛碼并解碼。對(duì)于 VAE 和 beta-VAE,從標(biāo)準(zhǔn)高斯分布中采樣。而 vq-VAE 的潛碼則從其學(xué)得類別中均勻采樣得到。

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

上圖中最有意義的生成樣本來自嚴(yán)格版 beta-VAE。這是因?yàn)槠溆?xùn)練重點(diǎn)放在了高斯先驗(yàn)上,編碼器輸出最接近來自標(biāo)準(zhǔn)高斯的樣本,從而使得解碼器成功解碼采樣自真正標(biāo)準(zhǔn)高斯的潛碼。另外,其生成圖像的變化較小,例如右側(cè)數(shù)字既像 5 又像 6。

寬松版 beta-VAE 生成圖像則更多樣化,盡管可識(shí)別的圖像較少。標(biāo)準(zhǔn) VAE 的表現(xiàn)在二者之間。令人略感失望的是 vq-VAE,它采樣的圖像完全不像 MNIST 數(shù)字。

插值

插值任務(wù)展示了潛在空間區(qū)域的密集程度。Krokotsch 從測試集中編碼了兩個(gè)圖像 2 和 7,并執(zhí)行線性插值。然后將插值解碼以接收新圖像。如果來自插值潛碼的圖像能夠顯示有意義的數(shù)字,則類別區(qū)域之間的潛碼可被自編碼器高效利用。

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

對(duì)于所有 VAE 類型,Krokotsch 在瓶頸操作之前即執(zhí)行插值。這意味著對(duì)于 VAE 和 beta-VAE,先插值高斯參數(shù),再進(jìn)行采樣;對(duì)于 vq-VAE,則先插值再量化。

從上圖中可以看到 VAE 和 beta-VAE 可以生成相對(duì)有意義的插值。其他自編碼器則完全不行。

潛在空間結(jié)構(gòu)

Krokotsch 利用 UMAP 算法可視化潛在空間結(jié)構(gòu),該算法可以將潛在空間縮減至二維,并保留潛碼的近鄰。下圖展示了自編碼器每個(gè)自編碼器潛在空間的散點(diǎn)圖,每個(gè)點(diǎn)表示測試集中一個(gè)圖像的潛碼,顏色表示圖像中的數(shù)字。

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

這些圖之間存在一些明顯的相似性。首先,原版、堆疊、稀疏、去噪自編碼器和 vq-VAE 很相似。0(藍(lán)色)、1(橙色)、2(綠色)和 6(粉色)的簇總能得到很好地分割,因此它們與其他數(shù)字看起來區(qū)別較大。還有 4-7-9 和 3-5-8 的簇,這表明這些數(shù)字之間存在連接,如在 3 上添加兩個(gè)直線可以得到 8。這些自編碼器可以編碼數(shù)字之間的結(jié)構(gòu)相似性。

但淺層自編碼器很難將數(shù)字分類為簇。VAE 和 beta-VAE 與其他不同,我們可以從中看到散度損失的影響。

分類

潛在空間圖表明很多自編碼器擅長將 MNIST 數(shù)字分簇,盡管它們并未接收到任何標(biāo)簽。那么如何利用這一點(diǎn)來執(zhí)行 MNIST 數(shù)字分類呢?

Krokotsch 使用 20 維潛碼擬合稠密分類層,該層僅在來自訓(xùn)練集的 550 個(gè)標(biāo)注樣本訓(xùn)練。也就是說,使用這些自編碼器做半監(jiān)督學(xué)習(xí)。從頭訓(xùn)練原版編碼器和分類層獲得的準(zhǔn)確率是 0.4364。下表展示了這些自編碼器的改進(jìn)效果:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

幾乎所有自編碼器都基于基線有所改進(jìn),除了稀疏自編碼器。去噪自編碼器獲得最優(yōu)結(jié)果,其次是原版自編碼器和 vq-VAE。去噪自編碼器添加的輸入噪聲似乎產(chǎn)生了最適合分類任務(wù)的特征。

最有趣的一點(diǎn)是,即使淺層自編碼器也能稍微提升準(zhǔn)確率,即使它只有一層,參數(shù)也更少。這再一次表明,智能數(shù)據(jù)使用往往勝過大模型。

VAE 和 beta-VAE 再一次表明,散度損失對(duì)潛在空間的約束。稀疏自編碼器的結(jié)果比基線還差,似乎是因?yàn)橄∈杼卣魍耆贿m合用于分類 MNIST 數(shù)字。對(duì)于其效果,還需要在其他數(shù)據(jù)集上再進(jìn)行測試。

異常檢測

使用自編碼器執(zhí)行異常檢測任務(wù)相對(duì)直接。使用訓(xùn)練好的模型,為測試樣本計(jì)算重建損失,得到異常分?jǐn)?shù)。如果樣本的重建結(jié)果較好,則它可能類似于訓(xùn)練數(shù)據(jù);如果重建結(jié)果較差,則樣本被認(rèn)為是異常值。自編碼器可以利用訓(xùn)練數(shù)據(jù)之間的關(guān)聯(lián)來學(xué)習(xí)有效的低維表示。只要這些關(guān)聯(lián)出現(xiàn),則測試樣本就可以得到不錯(cuò)地重建。反之,則自編碼器無法進(jìn)行很好地重建。

該任務(wù)的一大挑戰(zhàn)是找出異常分?jǐn)?shù)的最優(yōu)閾值。下圖展示了 ROC 曲線圖和曲線下面積:

無監(jiān)督訓(xùn)練用堆疊自編碼器是否落伍?ML博士對(duì)比了8個(gè)自編碼器

淺層自編碼器以 0.91 的 AUC 將其他自編碼器甩在身后,緊隨其后的是堆疊自編碼器。而且對(duì)于不同數(shù)字和潛在空間維度而言,不同自編碼器的排序是不變的。

為什么這兩個(gè)在其他任務(wù)中拖后腿的自編碼器如此擅長異常檢測呢?原因似乎在于其他任務(wù)依賴潛在空間的泛化能力。而異常檢測無需泛化,至少不需要太好的泛化能力。

結(jié)論

經(jīng)過對(duì)比實(shí)驗(yàn)后,Krokotsch 并未找出自編碼器中的王者,他認(rèn)為選擇哪種自編碼器取決于任務(wù)本身。想要基于噪聲生成人臉?使用變分自編碼器。圖像過于模糊?試試 vq-VAE。分類任務(wù)?選擇去噪自編碼器。如果要做異常檢測任務(wù),或許可以嘗試淺層自編碼器或 PCA。有時(shí),少即是多。

 

 

責(zé)任編輯:張燕妮 來源: 機(jī)器之心
相關(guān)推薦

2021-03-29 11:37:50

人工智能深度學(xué)習(xí)

2021-03-22 10:52:13

人工智能深度學(xué)習(xí)自編碼器

2025-04-10 11:52:55

2017-07-03 07:14:49

深度學(xué)習(xí)無監(jiān)督學(xué)習(xí)稀疏編碼

2017-07-19 13:40:42

卷積自編碼器降噪

2024-06-18 08:52:50

LLM算法深度學(xué)習(xí)

2024-10-21 16:47:56

2020-04-26 11:26:02

人臉合成編碼器數(shù)據(jù)

2017-11-10 12:45:16

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

2022-04-02 21:46:27

深度學(xué)習(xí)編碼器圖像修復(fù)

2017-05-08 22:40:55

深度學(xué)習(xí)自編碼器對(duì)抗網(wǎng)絡(luò)

2018-05-21 08:22:14

自編碼器協(xié)同過濾深度學(xué)習(xí)

2017-12-26 10:48:37

深度學(xué)習(xí)原始數(shù)據(jù)

2022-09-13 15:26:40

機(jī)器學(xué)習(xí)算法數(shù)據(jù)

2021-11-02 20:44:47

數(shù)字化

2018-04-23 14:49:31

表征句子深度學(xué)習(xí)自然語言

2025-04-10 06:30:00

2024-11-13 16:24:33

ViT架構(gòu)PyTorch

2012-04-10 16:55:22

PowerSmart編碼器

2023-08-14 08:30:32

點(diǎn)贊
收藏

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