GraphPPL.jl: A Probabilistic Programming Language forGraphical Models
GraphPPL.jl:一種用于圖形模型的概率編程語言
https://biaslab.github.io/pdf/entropy/entropy-26-00890-v2.pdf
摘要:
本文介紹了GraphPPL.jl,這是一種專為圖形模型設計的新型概率編程語言。GraphPPL.jl獨特地將概率模型表示為因子圖。其顯著特點是模型嵌套能力,這便于創建模塊化的圖形模型,并顯著簡化了大型(層次化)圖形模型的開發。此外,GraphPPL.jl提供了一個插件系統,可以將特定于推理的信息納入圖中,從而允許與各種知名推理引擎集成。為了展示這一點,GraphPPL.jl包含了一個靈活的插件,用于定義約束貝葉斯自由能最小化過程,也稱為變分推理。特別是,GraphPPL.jl定義的約束貝葉斯自由能可以作為許多知名推理后端的潛在推理框架,使其成為多樣化應用的多功能工具。本文詳細介紹了GraphPPL.jl的設計與實現,強調了其強大功能、表達能力和用戶友好性。它還強調了模型定義與推理之間的清晰分離,同時為開發人員提供了可擴展性和定制選項。這使得GraphPPL.jl成為一種高級用戶界面語言,允許用戶創建復雜的圖形模型而不必被推理的復雜性所困擾,同時讓后端開發人員可以輕松地將GraphPPL.jl作為他們的前端語言。
關鍵詞:貝葉斯推理;因子圖;嵌套模型;概率編程
1. 引言
概率編程語言(PPLs)旨在簡化概率推理的復雜性。它們提供了一種高級建模語言和一個自動執行各種推理算法(包括貝葉斯方法)的推理引擎。盡管PPLs通常便于貝葉斯推理,但它們也可以支持更廣泛的概率模型和推理算法。有效使用這些PPLs通常需要對底層原理有深入的了解,但最近的PPL進展,如NumPyro [1]和Turing.jl [2],旨在減輕用戶的負擔。這些語言顯著推動了概率推理領域的發展,使得它們能夠在毒理學 [3]、地球物理學 [4] 和認知科學 [5] 等多樣化領域得到應用。它們為用戶提供了強大的推理結果,而無需定制推理軟件,使得沒有深入概率信息處理知識的研究人員能夠輕松分析觀測數據。借助PPLs,用戶只需要與高級接口交互并定義控制數據生成的生成模型。
一旦定義了模型,額外的困難在于在有限的計算資源內實現可行的推理。已經提出了許多方法來自動化推理過程,例如基于采樣的方法 [2,6,7] 或基于變分優化的方法 [8–10]。然而,大多數自動推理解決方案與其模型規范組件緊密交織在一起。這使得使用相同的概率模型進行不同的推理方法變得困難,并且需要為每種特定的推理方法重新定義模型。
本文通過介紹GraphPPL.jl解決了這一問題,GraphPPL.jl是一種PPL,允許用戶定義概率模型而不對特定的推理過程做出假設。前端可以將模型生成為一個圖,并提供一個插件系統,如果需要,可以添加特定于推理的信息。為了說明這一能力,GraphPPL.jl包含了一個變分推理插件,該插件將額外信息注入到標準模型結構中,并支持變分推理方法,例如RxInfer [10]中的約束貝葉斯自由能(CBFE)優化過程。
選擇CBFE最小化來展示GraphPPL.jl的能力是經過深思熟慮的。已經證明,許多傳統的推理近似方法可以表示為CBFE泛函的最小化。然而,GraphPPL.jl并不對推理過程做出任何特定假設,并且可以作為各種其他推理技術的前端,包括HMC [11]、NUTS [12]等。GraphPPL.jl輸出一個表示生成模型的數據結構,而不依賴任何推理后端。據我們所知,目前沒有其他PPL提供這一功能。
此外,GraphPPL.jl便于定義嵌套模型,允許從較小、較簡單的模型構建大型復雜模型。這一點至關重要,因為計算能力的指數增長使得曾經極其昂貴的貝葉斯推理在標準計算機芯片上變得可行。這一進步擴大了生成模型的范圍,最近的技術已經擴展到數千個變量 [2,13],使得對這些大型模型的規范變得更加具有挑戰性。在處理復雜系統時,將它們劃分為獨立的模塊(例如編程語言中的函數或類)是一種常見的做法。然而,概率編程中類似模塊化的概念仍然不夠發達,GraphPPL.jl旨在填補這一空白。
本文的結構如下:
? 第2節回顧因子圖、變分貝葉斯推理和CBFE最小化。此外,我們討論了為什么在因子圖上進行CBFE最小化被認為是一種通用且可定制的推理方法。
? 第3節討論相關工作。
? 第4.2節深入探討GraphPPL.jl的核心設計理念,并解釋了為什么將CBFE最小化插件作為GraphPPL.jl的默認實現。
? 第4.3節介紹@model
宏和語法,這是創建任何GraphPPL.jl模型的主要入口點。
? 第4.4節展示了如何將使用@model
宏定義的模型在更大的模型中重用,從而為語言增加模塊化。
? 第4.7節介紹@constraints
宏,它為推理引擎指定變分后驗的分解和函數形式約束。我們定義了一種清晰直觀的約束語言。@model
和@constraints
都展示了在GraphPPL.jl中指定的模型與特定推理后端的集成。
? 第5節通過一個推理示例展示了GraphPPL.jl在RxInfer.jl推理生態系統中的集成。
2. 背景
本節旨在概述貝葉斯推理、變分推理、因子圖和約束貝葉斯自由能(CBFE)最小化。我們認為理解這些概念對于欣賞GraphPPL.jl的語言設計至關重要。然而,這并不是對這些主題的全面綜述。相反,我們建議感興趣的讀者參考文獻[14],其中對這些概念進行了更詳細的討論。
2.1 貝葉斯推理
在概率建模的背景下,第一個分解將模型表述為似然和先驗的乘積。貝葉斯推理的目標是推導出第二個分解,即后驗和證據的乘積。貝葉斯后驗和模型證據都是非常有趣的量,因為后驗描述了在觀測到數據x之后隱變量z的分布,而模型證據量化了模型在解釋觀測數據方面的表現。不幸的是,方程(1)中對隱變量的積分很快變得難以處理,因為積分的計算復雜度隨著z的維度呈指數增長。因此,人們投入了大量努力來尋找一種在計算模型證據時既可管理又準確的貝葉斯推理近似方法,因為使用現有資源進行計算是不可行的。其中一種解決方案涉及進一步分解似然和先驗分布,我們將在接下來探討這一概念。
2.2 因子圖
在本節中,我們探討因子圖及其在表達生成模型中的應用。為了簡化,我們將生成模型寫作p(s),而不顯式地將變量s分解為z和x。假設我們可以進一步分解我們的模型如下:
在分解的分布中計算貝葉斯后驗和邊緣分布,比方程(1)中的積分問題在計算上要簡單得多。這是因為我們可以利用方程(4)中的分解來降低積分的維度,如下所示:
2.3 變分推理
2.4 約束貝葉斯自由能
貝葉斯自由能(BFE)為因子圖(FFG)中的每個節點計算一個局部變分自由能(VFE)項,這使得我們可以在每個節點單獨最小化VFE。然而,由于BFE將全局優化問題分解為多個局部優化問題,因此有必要對變分后驗分布q(s)施加約束,以確保在優化BFE之后,結果仍然是一個有效的概率分布。所需的約束是歸一化約束和邊緣化約束。
在貝葉斯推理中,貝葉斯自由能(BFE)用于通過局部優化的方式近似全局優化問題。然而,為了確保優化后的結果仍然是有效的概率分布,需要對變分后驗分布施加歸一化和邊緣化約束。 在這些約束下對BFE進行最小化的過程被稱為約束貝葉斯自由能(Constrained Bethe Free Energy, CBFE)最小化。CBFE最小化的固定點對應于信念傳播算法的局部最小值。通過引入額外的約束,許多流行的推理算法可以被視作CBFE最小化的特例。例如,通過進一步約束節點信念為完全分解的形式,可以得到均場(Mean-Field)算法。 因此,允許用戶指定生成模型的CBFE的概率編程語言(PPL)為用戶提供了強大的工具,既能定義生成模型,又能影響推理結果。
3. 相關工作
概率編程語言(PPLs)旨在為用戶提供一種直觀的方式來創建用于推理的概率模型。一般來說,現有的PPLs都是圍繞那些可以高效執行推理的模型設計的。盡管這種設計限制了建模語言的表達能力,但它也催生了一些成功的語言,例如BUGS [6,22]、STAN [7,23] 和 CHURCH [24]。在某些語言中,例如IBAL [25],推理細節是模型規范的一部分,進一步將模型定義與推理實現交織在一起。隨著時間的推移,眾多概率編程庫不斷涌現,每個庫都為該領域貢獻了獨特的視角 [24–28]。近年來,Python的流行及其豐富的深度學習社區為基于Python的PPLs鋪平了道路,這些PPLs使用深度學習引擎作為后端,例如Pyro [27] 和 TensorFlow Probability [29]。對于更全面的概率編程語言綜述,我們建議讀者參考文獻 [30]。
為了構建一個不依賴于推理細節的通用PPL,Turing.jl [2] 應運而生。這是一種基于Julia [31] 的PPL,旨在通過采樣提供通用推理。通過實現DynamicPPL.jl語言,開發者投入了大量精力以確保建模語言與推理過程之間的分離。Turing.jl的日益流行表明,需要一種不受推理細節限制的通用建模語言。Turing.jl也在努力實現模塊化;通過@submodel宏,現有的Turing.jl模型可以在更大的模型中被調用。然而,子模型只能以正向生成方向嵌入,因此這不是一個通用的模塊化概率編程解決方案。
傳統編程語言中函數的實用性已得到廣泛認可,主要原因是它們能夠促進代碼重用、減少程序定義中的錯誤,并最小化代碼行數。這一概念與PPLs中的嵌套概率模型領域相呼應。嵌套PPLs的必要性源于其潛在能力,包括減少代碼行數、降低模型定義中的錯誤以及增強可重用性,這與傳統編程語言中函數所提供的優勢相呼應。編程中的模塊化和可重用性概念不僅僅是方便或良好的軟件工程實踐;它還與我們對智能系統(無論是生物的還是人工的)的理解相呼應。
4. GraphPPL.jl引擎
在本節中,我們將詳細闡述GraphPPL.jl(GitHub - ReactiveBayes/GraphPPL.jl[2024年9月18日訪問],文檔可在https://reactivebayes.github.io/GraphPPL.jl/stable/[2024年9月18日訪問] 查看)軟件包的哲學和細節,解釋其設計選擇并突出其獨特功能。我們還將解釋為什么特別關注將約束貝葉斯自由能(CBFE)用于推理后端集成的合理性。
我們使用Julia [31] 編程語言實現了GraphPPL.jl。選擇Julia作為編程語言的主要原因是兩個關鍵因素。首先,Julia為科學計算提供了高性能。鑒于貝葉斯推理的計算需求,使用以性能為中心的語言是至關重要的。盡管PPL本身可能不會受到這種計算負擔的太大影響,但將用戶語言和推理后端都放在同一種語言中會帶來相當大的好處。其次,Julia的元編程能力使我們能夠創建一種自定義語法,將其轉換為標準Julia代碼。這使我們能夠為Julia語言增強特定于概率編程的功能和操作符。
4.1 表示圖形模型
GraphPPL.jl提供了一個用于定義概率模型的前端,具有足夠的靈活性以適配各種推理后端。這些概率模型以圖的形式表示,允許在不承諾使用特定推理方法的情況下對它們的屬性進行可視化和檢查。模型可以存儲在內存中,也可以通過互聯網傳輸到獨立設備上供以后使用。基于圖的表示方式使得模型可以被拆分為更小的組件,即子模型,這些子模型可以在更復雜的層次化概率模型中被重用。選擇因子圖表示法可以對生成模型進行分析,推理后端可以將子圖與已知模型進行匹配,以采用更快且更易處理的推理過程。
然而,GraphPPL.jl認識到主要目標是對指定的模型進行推理。為了促進推理方法的集成,GraphPPL.jl采用了一個插件系統,允許向圖中添加特定推理后端所需的額外信息。例如,這些信息可能包括采樣方法(如HMC)所需的特定超參數,或變分推理方法的約束條件。作為這種無縫集成的一個例子,GraphPPL.jl與一種名為約束貝葉斯自由能(CBFE)框架的特定推理方法進行了集成。在第4.7節中,我們將展示GraphPPL.jl中變分約束的集成,允許定義CBFE。
4.2 語言哲學
在設計GraphPPL.jl時,我們采用了以用戶為中心的方法,主要關注提供高級模型規范能力,這些能力可以與各種推理操作集成,而不依賴于特定的推理后端。通過這種以用戶為中心的方法,我們旨在平衡表達能力、易用性和可學性,確保新手和經驗豐富的用戶能夠在初次接觸時不受陡峭學習曲線的負擔,有效地利用該語言。
GraphPPL.jl的哲學基于以下幾點要求:
使用GraphPPL.jl創建概率模型應該類似于起草生成模型的數學描述。類似于Turing.jl和BUGS,GraphPPL.jl模型的核心語言應該與生成模型的數學表示緊密匹配。
GraphPPL.jl模型應該像Julia程序一樣易于閱讀。借鑒PyTorch將“深度學習模型視為Python程序”的方法,我們希望GraphPPL.jl模型具有與Julia程序相同的可讀性和感覺。因此,任何GraphPPL.jl模型都應該可以作為更大GraphPPL.jl模型中的一個組件使用。
實例化的GraphPPL.jl模型應該與各種推理后端兼容,例如CBFE最小化。模型應該可以擴展,以注入任何推理后端執行貝葉斯推理所需的所有信息。
4.3 模型規范語言
為了以盡可能接近模型數學表示的方式規范一個模型,我們利用Julia [31] 強大的元編程功能來創建我們自己的語法。通過使用@model
宏創建我們自己的語法,我們將構建GraphPPL.jl模型所需的所有邏輯封裝起來。使用Julia的宏功能的一個結果是,我們擴展了Julia的語法,這意味著我們的語言接受任何常規的Julia代碼,同時擴展Julia語法以允許概率建模。我們首先構建一個描述一系列硬幣投擲的模型來介紹模型語法。
n次硬幣投擲的模型定義如下:
@model
語法接受一個Julia函數。函數的參數是模型外部的所有數據結構,例如數據,但我們也可以包括先驗或超參數。這些參數被稱為接口,因為它們連接了模型的外部和內部。由于我們的模型接收數據y,我們通過創建一個函數開始模型定義:@model function coin_toss(y)
。@model宏暴露了一個特定于GraphPPL.jl的操作符:~
。這個操作符在因子圖中創建一個新的因子節點和一個變量。例如,語句θ ~ Beta(1, 1)
創建了一個Beta因子節點和一個θ變量,以及兩個表示常數1的變量。它將這些連接到Beta節點。由該語句創建的子圖可以在圖3中看到。
4.4 模型的模塊化定義與使用
定義了gcv
和gcv_lm
模型后,我們現在可以簡化圖5中展示的HGF模型,使其使用這些子模型。創建HGF模型的GraphPPL.jl代碼可以在代碼塊5中看到。對于
y中的每個數據點,我們使用gcv
和gcv_lm
子模型計算狀態轉移,以完整規范似然模型。請注意,到目前為止我們編寫的GraphPPL.jl代碼行數仍然少于20行。在這個hgf
的定義中,我們可以將常量或分布作為參數ξ、ω和κ傳遞,這些參數將作為這些參數的參數或先驗。請注意,在代碼塊5中,我們使用了新的語法,如果變量不存在,它會在隨機變量向量中創建一個新變量。通過這種語法,我們可以在同一行中通過狀態轉移指定觀測值,并創建這兩個變量。
使用我們定義的子模型的HGF模型的因子圖(FFG)可以在圖7中查看。在這個圖中,我們獲得了計算流程的更清晰視圖,并且可以更好地向讀者傳達模型的意圖以及所做的建模決策。更重要的是,如果我們想使用一個與代碼塊4中指定的高斯似然不同的似然模型,我們只需要更改這個子模型,hgf
模型中每個gcv_lm
的實例都會相應改變。這與廣泛使用的PPLs形成對比,在廣泛使用的PPLs中,每個時間步的似然模型必須分別更改。
GraphPPL.jl中的嵌套模型規范使研究人員能夠輕松構建復雜的模型,促進了復雜概率模型的探索和創建,而不會犧牲可讀性或可維護性。這種層次化的模型定義和組合作為其顯著特征,代表了在可用性和模型組織方面的重大進步,并與既定的編程設計原則(如單一職責原則 [36])相一致。
4.5 示例:貝葉斯神經網絡
現在,我們可以定義一個由共享相同輸入并產生單個輸出元素的神經元組成的全連接層(代碼塊8)。有了這個定義,我們可以創建一個多層感知器或全連接神經網絡。創建一個四層貝葉斯神經網絡的代碼可以在代碼塊9中看到。這個例子再次突出了GraphPPL.jl如何通過組合更小、更簡單的模型來構建復雜的概率模型。
4.6 可擴展性
GraphPPL.jl并不僅僅依賴于一組預定義的因子節點運行。相反,它采用了一種可擴展的架構,該架構依賴于Julia的多重分派功能來決定何時為一個函數實例化一個因子節點,以及何時根據提供的參數確定性地評估一個函數。通過指定一個函數是確定性的還是隨機的,推理后端的開發者可以引入新的節點以融入概率建模中。
當考慮到在代碼塊2中使用的正態分布時,這種設計的強大之處便顯而易見。正態分布并非GraphPPL.jl的原生組成部分,而是屬于一個擴展,該擴展在加載Distributions.jl包時變得可用。這個擴展定義了為Distributions.jl中的每個分布創建節點所需的基本功能,擴展了可用于概率建模的分布范圍,而無需明確依賴Distributions.jl開箱即用。
4.7 約束規范
在第2節中,我們探討了約束貝葉斯自由能(CBFE)最小化作為一種有效的貝葉斯推理方法的效用。使用CBFE框架需要用戶為變分后驗提供一系列約束。這些約束可以被視為嵌入在模型圖結構中的額外信息。GraphPPL.jl中的變分約束插件專門設計用于處理此類場景,為ReactiveMP.jl后端提供支持。
通過這種語法,我們提供了一種簡潔的約束語言,同時仍然為考慮的變分后驗分布族提供了顯著的靈活性和控制能力。
5. 使用ReactiveMP.jl后端的推理示例
用于生成這些圖像的代碼可以在GitHub上找到,鏈接為 https://github.com/wouterwln/GraphPPL-demo (2024年9月18日訪問)。可以參考附錄A中的代碼塊或RxInfer的示例代碼來獲取更多信息。
6. 討論
在本文中,我們的目標是設計并實現一種具有以下期望目標/設計原則的概率編程語言(PPL):
應該可以將任何GraphPPL.jl模型作為子模型用于任何后續模型。
實例化的GraphPPL.jl模型應包含執行貝葉斯推理所需的所有信息。該模型應可由后端開發者擴展,以包含額外信息。
GraphPPL.jl模型應盡可能接近生成模型的數學表示,盡可能少地暴露實現細節。
在第4.4節中,我們介紹了模塊化,展示了如何將任何現有的GraphPPL.jl模型作為子模型用于更大的模型中。這種圖形模型構建中的模塊化功能強大,允許構建豐富的模型類別。正如在第5節中所見,我們可以用可讀且可解釋的代碼創建復雜的圖形模型。貝葉斯大腦假說 [40] 提出,智能生物體是貝葉斯推理機器,通過處理感官觀測不斷減少對環境的不確定性。這一假說進一步得到了自由能原理 [41] 的支持,該原理認為智能體在其大腦中擁有一個關于環境的生成模型。此外,有研究表明,生物智能行為的主要先決條件是將智能體的生成模型層次化地分解為更小的子模型,每個子模型獨立地最小化貝葉斯意外 [42,43]。這種層次化結構允許在認知過程中實現模塊化和可擴展性,從而更高效、更靈活地適應新信息和環境。通過引入GraphPPL.jl,我們引入了一種語言,其核心設計理念是概率模型的嵌套,使得基于自由能原理設計智能體成為可能。
通過變分約束插件,GraphPPL.jl可以被啟用以完全指定一個約束貝葉斯自由能(CBFE)。我們已經看到許多流行的推理算法可以被表示為CBFE最小的化 [14]。在GraphPPL.jl中,我們通過為生成模型提供一組推理約束(分解約束和函數形式約束)來實現這一點,這些約束共同完全定義了一個需要最小化的CBFE。然而,盡管分解約束和函數形式約束提供了一種富有表現力的約束語言,這些并不是可以應用于變分后驗的唯一約束。GraphPPL.jl未涵蓋的約束示例包括機會約束 [44] 或聯合函數形式約束(約束某些變量的聯合后驗分布的函數形式,而不是約束單個隨機變量的函數形式的函數形式約束)。盡管支持更廣泛的約束類別可以帶來優勢,但我們尚未發現支持這些約束的推理后端,因此沒有努力在GraphPPL.jl中暴露這些約束。
人們可能對GraphPPL.jl的性能問題和分析感興趣,以及諸如貝葉斯因子進行模型比較等模型統計信息的可用性。我們指出,GraphPPL.jl是一種用于指定帶有推理約束的模型的語言,但并不執行推理過程。在與RxInfer.jl推理引擎的現有集成中,我們可以分析推理過程的性能,由于RxInfer.jl近似變分自由能,我們也得到了模型證據的近似值,這可以用于模型比較。
對這項工作的未來改進可能會擴展GraphPPL.jl引擎的功能,例如提供更廣泛的約束類別,或者提供一個全面的可視化工具,用戶可以通過該工具檢查他們的圖形模型。
7. 結論
在本文中,我們介紹了GraphPPL.jl,這是一種用于圖形模型的概率編程語言。GraphPPL.jl將概率模型表示為因子圖,并使用自定義語法從高級用戶代碼高效生成因子圖。通過插件系統,GraphPPL.jl變得高度可擴展。我們通過實現變分約束插件展示了GraphPPL.jl的可擴展性,該插件允許用戶定義約束貝葉斯自由能,而不僅僅是定義生成模型。借助這一插件,我們將GraphPPL.jl集成到ReactiveMP.jl推理后端的前端,后者通過消息傳遞最小化約束貝葉斯自由能。這展示了GraphPPL.jl的多功能性以及一個與后端無關、可擴展的概率編程語言的重要性。
GraphPPL.jl引入了一種模型嵌套機制,允許模塊化的圖形模型,從而大幅降低了用戶在創建大型圖形模型時所承受的認知復雜性。簡而言之,GraphPPL.jl是一種直觀、強大且富有表現力的概率編程語言,它確保了模型定義與推理之間的分離,同時為開發者提供了可擴展性和定制性。
附錄A. 額外示例
在本附錄中,我們展示了一些GraphPPL.jl建模語言的有趣額外示例。
附錄A.1 遞歸生成模型
在本示例中,我們展示了一個類似四叉樹(Quadtree)的結構。四叉樹是一種數據結構,它遞歸地將二維空間劃分為四個象限。在這里,我們編寫了一個受四叉樹啟發的GraphPPL.jl模型,以展示GraphPPL.jl的遞歸能力。在我們的模型中,我們遞歸地使用一個聚合函數,該函數結合了四個象限的中間變量,其中基本情況是葉節點。
在這里,模型的深度由輸入的大小決定;一個8×8的輸入會導致深度為4的模型,而一個128×128的輸入會導致深度為8的模型。在每一層,我們都有中間表示(i1、i2、i3和i4),以及該模型中包含的所有變量,這些變量包含了輸出的粗粒化表示。從這個意義上說,這樣的模型可以被視為受尺度空間(Scale-Space)[45]方法的啟發,其中每一層代表輸入的更粗糙、更高層次的版本。
附錄A.2 變分自編碼器
GraphPPL.jl的一個顯著優勢是,子模型沒有固定的生成方向。這使得GraphPPL.jl的模塊化與Turing.jl的模塊化有顯著不同。在這個示例中,我們展示了如何使用第4.5節中定義的神經網絡架構,通過復制我們的編碼器-解碼器子模型兩次,輕松創建一個變分自編碼器 [46]。
將這個模型實例化兩次,一次在正向生成方向,一次在鏡像方向,就可以得到一個變分自編碼器。利用GraphPPL.jl的模塊化特性,我們可以保證這個網絡的編碼器和解碼器具有相同的架構,并且如果我們對這個模型進行任何更改,我們知道這些更改將反映在兩個地方。
原文鏈接:https://biaslab.github.io/pdf/entropy/entropy-26-00890-v2.pdf
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.