當前位置:首頁 » 編程軟體 » 編程范型

編程范型

發布時間: 2023-02-09 01:30:59

php oop的作用

oop是面向對象編程(設計) 面向對象程序設計(英語:Object Oriented Programming,縮寫:OOP),指一種程序設計范型,同時也是一種程序開發的方法論。它將對象作為程序的基本單元,將程序和數據封裝其中,以提高軟體的重用性、靈活性和擴展性。基本理論

一項由 Deborah J. Armstrong 進行的長達40年之久的計算機著作調查顯示出了一系列面向對象程序設計的基本理論。它們是:



類(Class)定義了一件事物的抽象特點。通常來說,類定義了事物的屬性和它可以做到的(它的行為)。舉例來說,"狗"這個類會包含狗的一切基礎特徵,例如它的孕育、毛皮顏色和吠叫的能力。類可以為程序提供模版和結構。一個類的方法和屬性被稱為"成員"。 我們來看一段偽代碼:

類狗 開始 私有成員: 孕育 毛皮顏色 公有成員: 吠叫() 結束

在這串代碼中,我們聲明了一個類,這個類具有一些狗的基本特徵。關於公有成員和私有成員,請參見下面的繼承性一節。

對象

對象(Object)是類的實例。例如,"狗"這個類列舉狗的特點,從而使這個類定義了世界上所有的狗。而萊絲這個對象則是一條具體的狗,它的屬性也是具體的。狗有皮毛顏色,而萊絲的皮毛顏色是棕白色的。因此,萊絲就是狗這個類的一個實例。一個具體對象屬性的值被稱作它的"狀態"。

假設我們已經在上面定義了狗這個類,我們就可以用這個類來定義對象:

定義萊絲是狗 萊絲.毛皮顏色:=棕白色 萊絲.吠叫()

我們無法讓狗這個類去吠叫,但是我們可以讓對象"萊絲"去吠叫,正如狗可以吠叫,但沒有具體的狗就無法吠叫。

方法

方法(Method)是一個類能做的事情,但方法並沒有去做這件事。作為一條狗,萊絲是會吠叫的,因此"吠叫()"就是它的一個方法。與此同時,它可能還會有其它方法,例如"坐下()",或者"吃()"。 對一個具體對象的方法進行調用並不影響其它對象,正如所有的狗都會叫,但是你讓一條狗叫不代表所有的狗都叫。 如下例:

定義萊絲是狗 定義泰爾是狗 萊絲.吠叫()

則泰爾是不會吠叫的,因為這里的吠叫只是對對象"萊絲"進行的。

消息傳遞機制

一個對象通過接受消息、處理消息、傳出消息或使用其他類的方法來實現一定功能,這叫做消息傳遞機制(Message Passing)。

繼承性

繼承性(Inheritance)是指,在某種情況下,一個類會有"子類"。子類比原本的類(稱為父類)要更加具體化,例如,"狗"這個類可能會有它的子類"牧羊犬"和"奇瓦瓦犬"。在這種情況下,"萊絲"可能就是牧羊犬的一個實例。子類會繼承父類的屬性和行為,並且也可包含它們自己的。我們假設"狗"這個類有一個方法叫做"吠叫()"和一個屬性叫做"毛皮顏色"。它的子類(前例中的牧羊犬和奇瓦瓦犬)會繼承這些成員。這意味著程序員只需要將相同的代碼寫一次。 在偽代碼中我們可以這樣寫:

類牧羊犬:繼承狗 定義萊絲是牧羊犬 萊絲.吠叫() /* 注意這里調用的是狗這個類的吠叫屬性。 */

回到前面的例子,"牧羊犬"這個類可以繼承"毛皮顏色"這個屬性,並指定其為棕白色。而"奇瓦瓦犬"則可以繼承"吠叫()"這個方法,並指定它的音調高於平常。子類也可以加入新的成員,例如,"奇瓦瓦犬"這個類可以加入一個方法叫做"顫抖()"。設若用"牧羊犬"這個類定義了一個實例"萊絲",那麼萊絲就不會顫抖,因為這個方法是屬於奇瓦瓦犬的,而非牧羊犬。事實上,我們可以把繼承理解為"是"。例如,萊絲"是"牧羊犬,牧羊犬"是"狗。因此,萊絲既繼承了牧羊犬的屬性,又繼承了狗的屬性。 我們來看偽代碼:

類奇瓦瓦犬:繼承狗 開始 公有成員: 顫抖() 結束 類牧羊犬:繼承狗 定義萊絲是牧羊犬 萊絲.顫抖() /* 錯誤:顫抖是奇瓦瓦犬的成員方法。 */

當一個類從多個父類繼承時,我們稱之為"多重繼承"。多重繼承並不總是被支持的,因為它很難理解,又很難被好好使用。

封裝性

具備封裝性(Encapsulation)的面向對象程序設計隱藏了某一方法的具體執行步驟,取而代之的是通過消息傳遞機制傳送消息給它。因此,舉例來說,"狗"這個類有"吠叫()"的方法,這一方法定義了狗具體該通過什麼方法吠叫。但是,萊絲的朋友蒂米並不需要知道它到底如何吠叫。 從實例來看:

/* 一個面向過程的程序會這樣寫: */

定義萊絲 萊絲.設置音調(5) 萊絲.吸氣() 萊絲.吐氣() /* 而當狗的吠叫被封裝到類中,任何人都可以簡單地使用: */ 定義萊絲是狗 萊絲.吠叫()

封裝是通過限制只有特定類的實例可以訪問這一特定類的成員,而它們通常利用介面實現消息的傳入傳出。舉個例子,介面能確保幼犬這一特徵只能被賦予狗這一類。通常來說,成員會依它們的訪問許可權被分為3種:公有成員、私有成員以及保護成員。有些語言更進一步:java可以限制同一包內不同類的訪問;C#和VB.NET保留了為類的成員聚集准備的關鍵字:internal(C#)和Friend(VB.NET);Eiffel語言則可以讓用戶指定哪個類可以訪問所有成員。

多態性

多態性(Polymorphism)指方法在不同的類中調用可以實現的不同結果。因此,2個甚至更多的類可以對同一消息作出不同的反應。舉例來說,狗和雞都有"叫()"這一方法,但是調用狗的"叫()",狗會吠叫;調用雞的"叫()",雞則會啼叫。 我們將它體現在偽代碼上:

類狗 開始 公有成員: 叫() 開始 吠叫() 結束 結束 類雞 開始 公有成員: 叫() 開始 啼叫() 結束 結束 定義萊絲是狗 定義魯斯特是雞 萊絲.叫() 魯斯特.叫()

這樣,同樣是叫,萊絲和魯斯特做出的反應將大不相同。多態性的概念可以用在運算符重載上,本文不再贅述。

抽象性

抽象(Abstraction)是簡化復雜的現實問題的途徑,它可以為具體問題找到最恰當的類定義,並且可以在最恰當的繼承級別解釋問題。舉例說明,萊絲在大多數時候都被當作一條狗,但是如果想要讓它做牧羊犬做的事,你完全可以調用牧羊犬的方法。如果狗這個類還有動物的父類,那麼你完全可以視萊絲為一個動物。

OOP名詞釋意

編程范型 對於OOP的准確定義及其本意存在著不少爭論。

通常,OOP被理解為一種將程序分解為封裝數據及相關操作的模塊而進行的編程方式。有別於其它編程方式,OOP中的與某數據類型相關的一系列操作都被有機地封裝到該數據類型當中,而非散放於其外,因而OOP中的數據類型不僅有著狀態,還有著相關的行為。OOP理論,及與之同名的OOP實踐相結合創造出了新的一個編程架構;OOP思想被廣泛認為是非常有用的,以致一套新的編程范型被創造了出來。(其它的編程范型例如函數式編程或過程序編程專注於程序運行的過程,而邏輯編程專注於引發程序代碼執行的斷言)

對面向模擬系統的語言(如:SIMULA 67)的研究及對高可靠性系統架構(如:高性能操作系統和CPU的架構)的研究最終導致了OOP的誕生。

一些專家認為Object-Orientation中的Object的本意來自於其在語法領域的意義,即應將其理解為"賓語"或"操作對象",而非一般的"對象"或"對象"。我們所見到的軟體的運行請求通常都是Subject-Oriented的,即"面向主語的"或"面向操作者的",然而這樣將使得對操作者對象的設計變得困難而復雜。有鑒於此,部分研究人員開始了對"面向操作對象"的思考。這又一次產生了新的編程范型,這是前邊提到的"面向操作者"的思考模式的一項革新。

依照"面向操作對象"的原則,在程序語句中的動詞應該被劃分到操作對象的類型之中,而與該動詞請求相關的邏輯關系也就因此將在操作對象中處理。以下是採用"面向操作對象"的方式翻譯"面向操作者"的一些例子:

面向操作者:銷售系統保存交易記錄。
面向操作對象:交易記錄在接受到銷售系統的一條請求消息後將自身保存。
面向操作者:銷售系統列印收據。
面向操作對象:收據在接收到銷售系統的一條請求消息後將自身列印。

面向對象的語言

支持部分或絕大部分面向對象特性的語言即可稱為基於對象的或面向對象的語言。早期,完全面向對象的語言主要包括Smalltalk等語言,目前較為流行的語言中有Java、C#、Eiffel等。隨著軟體工業的發展,比較早的面向過程的語言在近些年的發展中也紛紛吸收了許多面向對象的概念,比如C->C++,BASIC->Visual Basic->Visual Basic .NET,Pascal->Object Pascal,Ada->Ada95。

歷史

對象和實例的最早概念出自麻省理工大學的PDP-1系統。這一系統大概是capability based architecture的最早示例。另一個早期的事例是1963年Ivan Sutherland開發的Sketchpad;但是,這並非是一種編程思想,而只是一個程序。

對象最早在20世紀60年代的Simula 67中被引入程序設計中。Simula這一語言是Ole-Johan Dahl和Kristen Nygaard在奧斯陸計算機中心為模擬環境而設計的。(據說,他們是為了模擬船隻而設計的這種語言,並且對不同船隻間屬性的相互影響感興趣。他們將不同的船隻歸納為不同的類,而每一個對象,基於它的類,可以定義它自己的屬性和行為。)這種辦法是分析式程序的最早概念體現。在分析式程序中,我們將真實世界的對象映射到抽象的對象,這叫做"模擬"。Simula不僅引入了"類"的概念,還應用了實例這一思想--這可能是這些概念的最早應用。20世紀70年代施樂PARC研究所發明的Smalltalk語言將面向對象程序設計的概念定義為,在基礎運算中,對對象和消息的廣泛應用。Smalltalk的創建者深受Simula 67的主要思想影響,但Smalltalk中的對象是完全動態的--它們可以被創建、修改並銷毀,這與Simula中的靜態對象有所區別。此外,Smalltalk還引入了繼承性的思想,它因此一舉超越了不可創建實例的程序設計模型和不具備繼承性的Simula。

此外,Simula 67的思想亦被應用在許多不同的語言,如Lisp、Pascal。

面向對象程序設計在80年代成為了一種主導思想,這主要應歸功於C++--c語言的擴充版。在圖形用戶界面(GUI)日漸崛起的情況下,面向對象程序設計很好地適應了潮流。GUI和面向對象程序設計的緊密關聯在Mac OS X中可見一斑。Mac OS X是由面向對象C語言寫成的,這一語言是一個仿Smalltalk的C語言擴充版。面向對象程序設計的思想也使事件處理式的程序設計更加廣泛被應用(雖然這一概念並非僅存在於面向對象程序設計)。一種說法是,GUI的引入極大地推動了面向對象程序設計的發展。

在ETH Zürich(英文),Niklaus Wirth 和他的同事們對抽象數據和模塊化程序設計進行了調查。Mula-2將這些都包括了進去,而Oberon則包括了一種特殊的面向對象方法--不同於Smalltalk與C++。

面向對象的特性也被加入了當時較為流行的語言:Ada、BASIC、Lisp、Fortran、Pascal以及種種。由於這些語言最初並沒有面向對象的設計,故而這種糅合常常會導致兼容性和維護性的問題。與之相反的是,"純正的"面向對象語言卻缺乏一些程序員們賴以生存的特性。在這一大環境下,開發新的語言成為了當務之急。作為先行者,Eiffel成功地解決了這些問題,並成為了當時較受歡迎的語言。在過去的幾年中,Java語言成為了廣為應用的語言,除了它與C和C++語法上的近似性。Java的可移植性是它的成功中不可磨滅的一步,因為這一特性,已吸引了龐大的程序員群的投入。

近日,一些既支持面向對象程序設計,又支持面向過程程序設計的語言悄然浮出水面。它們中的佼佼者有Python、Ruby等等.

正如面向過程程序設計使得結構化程序設計的技術得以提升,現代的面向對象程序設計方法使得對設計模式的用途、契約式設計和建模語言(如UML)技術也得到了一定提升。

腳本中的OOP

近年來,面向過程程序設計越發流行於腳本語言。Python和Ruby是建立在OOP原理的腳本語言,Perl和PHP亦分別在Perl 5和PHP 4時加入面向過程特性。

⑵ 範式編程是什麼意思

編程範式指的是 Multi-paradigm 這個英文單詞。這個詞是由 Bjarne Stroustrup 博士在其著作中提出的,用於表述 C++ 可以以同時使用多種風格來寫程序,比如面向對象和泛型編程。

⑶ 放棄手工標記數據,斯坦福大學開發弱監督編程範式Snorkel

手工標記大量數據始終是開發機器學習的一大瓶頸。斯坦福AI Lab的研究人員探討了一種通過編程方式生成訓練數據的「弱監督」範式,並介紹了他們的開源Snorkel框架。

近年來,機器學習 (ML) 對現實世界的影響越來越大。這在很大程度上是由於深度學習模型的出現,使得從業者可以在基準數據集上獲得 state-of-the-art 的分數,而無需任何手工特徵設計。考慮到諸如 TensorFlow 和 PyTorch 等多種開源 ML 框架的可用性,以及大量可用的最先進的模型,可以說,高質量的 ML 模型現在幾乎成為一種商品化資源了。然而,有一個隱藏的問題:這些模型依賴於大量手工標記的訓練數據。

這些手工標記的訓練集創建起來既昂貴又耗時 —— 通常需要幾個月甚至幾年的時間、花費大量人力來收集、清理和調試 —— 尤其是在需要領域專業知識的情況下。除此之外,任務經常會在現實世界中發生變化和演變。例如,標記指南、粒度或下游用例都經常發生變化,需要重新標記 (例如,不要只將評論分類為正面或負面,還要引入一個中性類別)。

由於這些原因,從業者越來越多地轉向一種較弱的監管形式,例如利用外部知識庫、模式 / 規則或其他分類器啟發式地生成訓練數據。從本質上來講,這些都是以編程方式生成訓練數據的方法,或者更簡潔地說,編程訓練數據 (programming training data)。

在本文中,我們首先回顧了 ML 中由標記訓練數據驅動的一些領域,然後描述了我們對建模和整合各種監督源的研究。我們還討論了為大規模多任務機制構建數據管理系統的設想,這種系統使用數十或數百個弱監督的動態任務,以復雜、多樣的方式交互。

回顧:如何獲得更多有標簽的訓練數據?

ML 中的許多傳統研究方法也同樣受到對標記訓練數據的需求的推動。我們首先將這些方法與弱監督方法 (weak supervision) 區分開來:弱監督是利用來自主題領域專家(subject matter experts,簡稱 SME) 的更高級別和 / 或更嘈雜的輸入。

目前主流方法的一個關鍵問題是,由領域專家直接給大量數據加標簽是很昂貴的:例如,為醫學成像研究構建大型數據集更加困難,因為跟研究生不同,放射科醫生可不會接受一點小恩小惠就願意為你標記數據。因此,在 ML 中,許多經過深入研究的工作線都是由於獲取標記訓練數據的瓶頸所致:

在主動學習 (active learning) 中,目標是讓領域專家為估計對模型最有價值的數據點貼標簽,從而更有效地利用領域專家。在標準的監督學習設置中,這意味著選擇要標記的新數據點。例如,我們可以選擇靠近當前模型決策邊界的乳房 X 線照片,並要求放射科醫生僅給這些照片進行標記。但是,我們也可以只要求對這些數據點進行較弱的監督,在這種情況下,主動學習與弱監督是完美互補的;這方面的例子可以參考 (Druck, settle, and McCallum 2009)。

在半監督學習 (semi-supervised learning ) 設置中,我們的目標是用一個小的標記訓練集和一個更大的未標記數據集。然後使用關於平滑度、低維結構或距離度量的假設來利用未標記數據 (作為生成模型的一部分,或作為一個判別模型的正則項,或學習一個緊湊的數據表示);參考閱讀見 (Chapelle, Scholkopf, and Zien 2009)。從廣義上講,半監督學習的理念不是從 SME 那裡尋求更多輸入,而是利用領域和任務不可知的假設來利用未經標記的數據,而這些數據通常可以以低成本大量獲得。最近的方法使用生成對抗網路 (Salimans et al. 2016)、啟發式轉換模型 (Laine and Aila 2016) 和其他生成方法來有效地幫助規范化決策邊界。

在典型的遷移學習 (transfer learning )設置 中,目標是將一個或多個已經在不同數據集上訓練過的模型應用於我們的數據集和任務;相關的綜述見 (Pan 和 Yang 2010)。例如,我們可能已經有身體其他部位腫瘤的大型訓練集,並在此基礎上訓練了分類器,然後希望將其應用到我們的乳房 X 光檢查任務中。在當今的深度學習社區中,一種常見的遷移學習方法是在一個大數據集上對模型進行 「預訓練」,然後在感興趣的任務上對其進行 「微調」。另一個相關的領域是多任務學習 (multi-task learning),其中幾個任務是共同學習的 (Caruna 1993; Augenstein, Vlachos, and Maynard 2015)。

上述範例可能讓我們得以不用向領域專家合作者尋求額外的訓練標簽。然而,對某些數據進行標記是不可避免的。如果我們要求他們提供各種類型的更高級、或不那麼精確的監督形式,這些形式可以更快、更簡便地獲取,會怎麼樣呢?例如,如果我們的放射科醫生可以花一個下午的時間來標記一組啟發式的資源或其他資源,如果處理得當,這些資源可以有效地替代成千上萬的訓練標簽,那會怎麼樣呢 ?

將領域知識注入 AI

從 歷史 的角度來看,試圖 「編程」 人工智慧 (即注入領域知識) 並不是什麼新鮮想法,但現在提出這個問題的主要新穎之處在於,AI 從未像現在這樣強大,同時在可解釋性和可控制性方面,它還是一個 「黑盒」。

在 20 世紀 70 年代和 80 年代,AI 的重點是專家系統,它將來自領域專家的手工策劃的事實和規則的知識庫結合起來,並使用推理引擎來應用它們。20 世紀 90 年代,ML 開始作為將知識集成到 AI 系統的工具獲得成功,並承諾以強大而靈活的方式從標記的訓練數據自動實現這一點。

經典的 (非表示學習)ML 方法通常有兩個領域專家輸入埠。首先,這些模型通常比現代模型的復雜度要低得多,這意味著可以使用更少的手工標記數據。其次,這些模型依賴於手工設計的特性,這些特性為編碼、修改和與模型的數據基本表示形式交互提供了一種直接的方法。然而,特性工程不管在過去還是現在通常都被認為是 ML 專家的任務,他們通常會花費整個博士生涯來為特定的任務設計特性。

進入深度學習模型:由於它們具有跨許多領域和任務自動學習表示的強大能力,它們在很大程度上避免了特性工程的任務。然而,它們大部分是完整的黑盒子,除了標記大量的訓練集和調整網路架構外,普通開發人員對它們幾乎沒有控制權。在許多意義上,它們代表了舊的專家系統脆弱但易於控制的規則的對立面 —— 它們靈活但難以控制。

這使我們從一個略微不同的角度回到了最初的問題:我們如何利用我們的領域知識或任務專業知識來編寫現代深度學習模型?有沒有辦法將舊的基於規則的專家系統的直接性與這些現代 ML 方法的靈活性和強大功能結合起來?

代碼作為監督:通過編程訓練 ML

Snorkel 是我們為支持和 探索 這種與 ML 的新型交互而構建的一個系統。在 Snorkel中,我們不使用手工標記的訓練數據,而是要求用戶編寫標記函數 (labeling functions, LF),即用於標記未標記數據子集的黑盒代碼片段。

然後,我們可以使用一組這樣的 LF 來為 ML 模型標記訓練數據。因為標記函數只是任意的代碼片段,所以它們可以對任意信號進行編碼:模式、啟發式、外部數據資源、來自群眾工作者的嘈雜標簽、弱分類器等等。而且,作為代碼,我們可以獲得所有其他相關的好處,比如模塊化、可重用性和可調試性。例如,如果我們的建模目標發生了變化,我們可以調整標記函數來快速適應!

一個問題是,標記函數會產生有雜訊的輸出,這些輸出可能會重疊和沖突,從而產生不太理想的訓練標簽。在 Snorkel 中,我們使用數據編程方法對這些標簽進行去噪,該方法包括三個步驟:

1. 我們將標記函數應用於未標記的數據。

2. 我們使用一個生成模型來在沒有任何標記數據的條件下學習標記函數的准確性,並相應地對它們的輸出進行加權。我們甚至可以自動學習它們的關聯結構。

3. 生成模型輸出一組概率訓練標簽,我們可以使用這些標簽來訓練一個強大、靈活的判別模型 (如深度神經網路),它將泛化到標記函數表示的信號之外。

可以認為,這整個 pipeline 為 「編程」ML 模型提供了一種簡單、穩健且與模型無關的方法!

標記函數 (Labeling Functions)

從生物醫學文獻中提取結構化信息是最能激勵我們的應用之一:大量有用的信息被有效地鎖在數百萬篇科學論文的密集非結構化文本中。我們希望用機器學習來提取這些信息,進而使用這些信息來診斷遺傳性疾病。

考慮這樣一個任務:從科學文獻中提取某種化學 - 疾病的關系。我們可能沒有足夠大的標記訓練數據集來完成這項任務。然而,在生物醫學領域,存在著豐富的知識本體、詞典等資源,其中包括各種化學與疾病名稱數據、各種類型的已知化學 - 疾病關系資料庫等,我們可以利用這些資源來為我們的任務提供弱監督。此外,我們還可以與生物學領域的合作者一起提出一系列特定於任務的啟發式、正則表達式模式、經驗法則和負標簽生成策略。

作為一種表示載體的生成模型

在我們的方法中,我們認為標記函數隱含地描述了一個生成模型。讓我們來快速復習一下:給定數據點 x,以及我們想要預測的未知標簽 y,在判別方法中,我們直接對P(y|x) 建模,而在生成方法中,我們對 P(x,y) = P(x|y)P(y) 建模。在我們的例子中,我們建模一個訓練集標記的過程 P(L,y),其中 L 是由對象 x 的標記函數生成的標簽,y 是對應的 (未知的) 真實標簽。通過學習生成模型,並直接估計 P(L|y),我們本質上是在根據它們如何重疊和沖突來學習標記函數的相對准確性 (注意,我們不需要知道 y!)

我們使用這個估計的生成模型在標簽函數上訓練一個雜訊感知版本的最終判別模型。為了做到這一點,生成模型推斷出訓練數據的未知標簽的概率,然後我們最小化關於這些概率的判別模型的預期損失。

估計這些生成模型的參數可能非常棘手,特別是當使用的標記函數之間存在統計依賴性時。在 Data Programming: Creating Large Training Sets, Quickly(https://arxiv.org/abs/1605.07723) 這篇論文中,我們證明了給定足夠的標記函數的條件下,可以得到與監督方法相同的 asymptotic scaling。我們還研究了如何在不使用標記數據的情況下學習標記函數之間的相關性,以及如何顯著提高性能。

Snorkel:一個開源的框架

在我們最近發表的關於 Snorkel 的論文 (https://arxiv.org/abs/1711.10160) 中,我們發現在各種實際應用中,這種與現代 ML 模型交互的新方法非常有效!包括:

1. 在一個關於 Snorkel 的研討會上,我們進行了一項用戶研究,比較了教 SMEs 使用Snorkel 的效率,以及花同樣的時間進行純手工標記數據的效率。我們發現,使用Snorkel 構建模型不僅快了 2.8 倍,而且平均預測性能也提高了 45.5%。

2. 在與斯坦福大學、美國退伍軍人事務部和美國食品和葯物管理局的研究人員合作的兩個真實的文本關系提取任務,以及其他四個基準文本和圖像任務中,我們發現,與baseline 技術相比,Snorkel 平均提高了 132%。

3. 我們 探索 了如何對用戶提供的標記函數建模的新的權衡空間,從而得到了一個基於規則的優化器,用於加速迭代開發周期。

下一步:大規模多任務弱監管

我們實驗室正在進行各種努力,將 Snorkel 設想的弱監督交互模型擴展到其他模式,如格式豐富的數據和圖像、使用自然語言的監督任務和自動生成標簽函數!

在技術方面,我們感興趣的是擴展 Snorkel 的核心數據編程模型,使其更容易指定具有更高級別介面(如自然語言) 的標記函數,以及結合其他類型的弱監督 (如數據增強)。

多任務學習 (MTL) 場景的普及也引發了這樣一個問題:當嘈雜的、可能相關的標簽源現在要標記多個相關任務時會發生什麼?我們是否可以通過對這些任務進行聯合建模來獲益?我們在一個新的多任務感知版本的 Snorkel,即 Snorkel MeTaL 中解決了這些問題,它可以支持多任務弱監管源,為一個或多個相關任務提供雜訊標簽。

我們考慮的一個例子是設置具有不同粒度的標簽源。例如,假設我們打算訓練一個細粒度的命名實體識別 (NER) 模型來標記特定類型的人和位置,並且我們有一些細粒度的嘈雜標簽,例如標記 「律師」 與 「醫生」,或 「銀行」 與 「醫院」;以及有些是粗粒度的,例如標記 「人」 與 「地點」。通過將這些資源表示為標記不同層次相關的任務,我們可以聯合建模它們的准確性,並重新加權和組合它們的多任務標簽,從而創建更清晰、智能聚合的多任務訓練數據,從而提高最終 MTL 模型的性能。

我們相信,為 MTL 構建數據管理系統最激動人心的方面將圍繞大規模多任務機制(massively multi-task regime),在這種機制中,數十到數百個弱監督 (因而高度動態)的任務以復雜、多樣的方式交互。

雖然迄今為止大多數 MTL 工作都考慮最多處理由靜態手工標記訓練集定義的少數幾項任務,但世界正在迅速發展成組織 (無論是大公司、學術實驗室還是在線社區) 都要維護數以百計的弱監督、快速變化且相互依賴的建模任務。此外,由於這些任務是弱監督的,開發人員可以在數小時或數天內 (而不是數月或數年) 添加、刪除或更改任務 (即訓練集),這可能需要重新訓練整個模型。

在最近的一篇論文 The Role of Massively Multi-Task and Weak Supervision in Software 2.0 (http://cidrdb.org/cidr2019/papers/p58-ratner-cidr19.pdf) 中,我們概述了針對上述問題的一些初步想法,設想了一個大規模的多任務設置,其中 MTL 模型有效地用作一個訓練由不同開發人員弱標記的數據的中央存儲庫,然後組合在一個中央「mother」 多任務模型中。

不管確切的形式因素是什麼,很明顯,MTL 技術在未來有許多令人興奮的進展 —— 不僅是新的模型架構,而且還與遷移學習方法、新的弱監督方法、新的軟體開發和系統範例日益統一。

原文:

https://ai.stanford.e/blog/weak-supervision/

Snorkel:

http://snorkel.stanford.e/

歡迎同時關注微信公眾號: IT 科技 森

每天分享IT小技巧、 科技 數碼新聞!

⑷ c#中的泛型究竟是什麼東西了

泛型:通過參數化類型來實現在同一份代碼上操作多種數據類型。利用「參數化類型」將類型抽象化,從而實現靈活的復用。
例子代碼:
class Program
{
static void Main(string[] args)
{
int obj = 2;
Test<int> test = new Test<int>(obj);
Console.WriteLine("int:" + test.obj);
string obj2 = "hello world";
Test<string> test1 = new Test<string>(obj2);
Console.WriteLine("String:" + test1.obj);
Console.Read();
}
}

class Test<T>
{
public T obj;
public Test(T obj)
{
this.obj = obj;
}
}
輸出結果是:
int:2
String:hello world

程序分析:
1、 Test是一個泛型類。T是要實例化的范型類型。如果T被實例化為int型,那麼成員變數obj就是int型的,如果T被實例化為string型,那麼obj就是string類型的。
2、 根據不同的類型,上面的程序顯示出不同的值。

C#泛型機制:
C#泛型能力有CLR在運行時支持:C#泛型代碼在編譯為IL代碼和元數據時,採用特殊的佔位符來表示範型類型,並用專有的IL指令支持泛型操作。而真正的泛型實例化工作以「on-demand」的方式,發生在JIT編譯時。

看看剛才的代碼中Main函數的元數據
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 79 (0x4f)
.maxstack 2
.locals init ([0] int32 obj,
[1] class CSharpStudy1.Test`1<int32> test,
[2] string obj2,
[3] class CSharpStudy1.Test`1<string> test1)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: newobj instance void class CSharpStudy1.Test`1<int32>::.ctor(!0)
IL_0009: stloc.1
IL_000a: ldstr "int:"
IL_000f: ldloc.1
IL_0010: ldfld !0 class CSharpStudy1.Test`1<int32>::obj
IL_0015: box [mscorlib]System.Int32
IL_001a: call string [mscorlib]System.String::Concat(object,
object)
IL_001f: call void [mscorlib]System.Console::WriteLine(string)
IL_0024: nop
IL_0025: ldstr "hello world"
IL_002a: stloc.2
IL_002b: ldloc.2
IL_002c: newobj instance void class CSharpStudy1.Test`1<string>::.ctor(!0)
IL_0031: stloc.3
IL_0032: ldstr "String:"
IL_0037: ldloc.3
IL_0038: ldfld !0 class CSharpStudy1.Test`1<string>::obj
IL_003d: call string [mscorlib]System.String::Concat(string,
string)
IL_0042: call void [mscorlib]System.Console::WriteLine(string)
IL_0047: nop
IL_0048: call int32 [mscorlib]System.Console::Read()
IL_004d: pop
IL_004e: ret
} // end of method Program::Main

再來看看Test類中構造函數的元數據
.method public hidebysig specialname rtspecialname
instance void .ctor(!T obj) cil managed
{
// Code size 17 (0x11)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: stfld !0 class ConsoleCSharpTest1.Test`1<!T>::obj
IL_000f: nop
IL_0010: ret
} // end of method Test`1::.ctor

1、第一輪編譯時,編譯器只為Test<T>類型產生「泛型版」的IL代碼與元數據——並不進行泛型的實例化,T在中間只充當佔位符。例如:Test類型元數據中顯示的<!T>
2、JIT編譯時,當JIT編譯器第一次遇到Test<int>時,將用int替換「范型版」IL代碼與元數據中的T——進行泛型類型的實例化。例如:Main函數中顯示的<int>
3、CLR為所有類型參數為「引用類型」的泛型類型產生同一份代碼;但是如果類型參數為「值類型」,對每一個不同的「值類型」,CLR將為其產生一份獨立的代碼。因為實例化一個引用類型的泛型,它在內存中分配的大小是一樣的,但是當實例化一個值類型的時候,在內存中分配的大小是不一樣的。

C#泛型特點:
1、如果實例化泛型類型的參數相同,那麼JIT編輯器會重復使用該類型,因此C#的動態泛型能力避免了C++靜態模板可能導致的代碼膨脹的問題。
2、C#泛型類型攜帶有豐富的元數據,因此C#的泛型類型可以應用於強大的反射技術。
3、C#的泛型採用「基類、介面、構造器,值類型/引用類型」的約束方式來實現對類型參數的「顯示約束」,提高了類型安全的同時,也喪失了C++模板基於「簽名」的隱式約束所具有的高靈活性

C#泛型繼承:
C#除了可以單獨聲明泛型類型(包括類與結構)外,也可以在基類中包含泛型類型的聲明。但基類如果是泛型類,它的類型要麼以實例化,要麼來源於子類(同樣是泛型類型)聲明的類型參數,看如下類型
class C<U,V>
class D:C<string,int>
class E<U,V>:C<U,V>
class F<U,V>:C<string,int>
class G:C<U,V> //非法
E類型為C類型提供了U、V,也就是上面說的來源於子類
F類型繼承於C<string,int>,個人認為可以看成F繼承一個非泛型的類
G類型為非法的,因為G類型不是泛型,C是泛型,G無法給C提供泛型的實例化

泛型類型的成員:
泛型類型的成員可以使用泛型類型聲明中的類型參數。但類型參數如果沒有任何約束,則只能在該類型上使用從System.Object繼承的公有成員。如下圖:

泛型介面:
泛型介面的類型參數要麼已實例化,要麼來源於實現類聲明的類型參數

泛型委託:
泛型委託支持在委託返回值和參數上應用參數類型,這些參數類型同樣可以附帶合法的約束
delegate bool MyDelegate<T>(T value);
class MyClass
{
static bool F(int i){...}
static bool G(string s){...}
static void Main()
{
MyDelegate<string> p2 = G;
MyDelegate<int> p1 = new MyDelegate<int>(F);
}
}

泛型方法:
1、C#泛型機制只支持「在方法聲明上包含類型參數」——即泛型方法。
2、C#泛型機制不支持在除方法外的其他成員(包括屬性、事件、索引器、構造器、析構器)的聲明上包含類型參數,但這些成員本身可以包含在泛型類型中,並使用泛型類型的類型參數。
3、泛型方法既可以包含在泛型類型中,也可以包含在非泛型類型中。

泛型方法聲明:如下
public static int FunctionName<T>(T value){...}

泛型方法的重載:
public void Function1<T>(T a);
public void Function1<U>(U a);
這樣是不能構成泛型方法的重載。因為編譯器無法確定泛型類型T和U是否不同,也就無法確定這兩個方法是否不同

public void Function1<T>(int x);
public void Function1(int x);
這樣可以構成重載

public void Function1<T>(T t) where T:A;
public void Function1<T>(T t) where T:B;
這樣不能構成泛型方法的重載。因為編譯器無法確定約束條件中的A和B是否不同,也就無法確定這兩個方法是否不同

泛型方法重寫:
在重寫的過程中,抽象類中的抽象方法的約束是被默認繼承的。如下:
abstract class Base
{
public abstract T F<T,U>(T t,U u) where U:T;
public abstract T G<T>(T t) where T:IComparable;
}

class MyClass:Base
{
public override X F<X,Y>(X x,Y y){...}
public override T G<T>(T t) where T:IComparable{}
}
對於MyClass中兩個重寫的方法來說
F方法是合法的,約束被默認繼承
G方法是非法的,指定任何約束都是多餘的

泛型約束:
1、C#泛型要求對「所有泛型類型或泛型方法的類型參數」的任何假定,都要基於「顯式的約束」,以維護C#所要求的類型安全。
2、「顯式約束」由where子句表達,可以指定「基類約束」,「介面約束」,「構造器約束」,「值類型/引用類型約束」共四種約束。
3、「顯式約束」並非必須,如果沒有指定「顯式約束」,范型類型參數將只能訪問System.Object類型中的公有方法。例如:在開始的例子中,定義的那個obj成員變數。比如我們在開始的那個例子中加入一個Test1類,在它當中定義兩個公共方法Func1、Func2,如下圖:

基類約束:
class A
{
public void Func1()
{ }
}

class B
{
public void Func2()
{ }
}

class C<S, T>
where S : A
where T : B
{
public C(S s,T t)
{
//S的變數可以調用Func1方法
s.Func1();
//T的變數可以調用Func2方法
t.Func2();
}
}
介面約束:
interface IA<T>
{
T Func1();
}

interface IB
{
void Func2();
}

interface IC<T>
{
T Func3();
}

class MyClass<T, V>
where T : IA<T>
where V : IB, IC<V>
{
public MyClass(T t,V v)
{
//T的對象可以調用Func1
t.Func1();
//V的對象可以調用Func2和Func3
v.Func2();
v.Func3();
}
}
構造器約束:
class A
{
public A()
{ }
}

class B
{
public B(int i)
{ }
}

class C<T> where T : new()
{
T t;
public C()
{
t = new T();
}
}

class D
{
public void Func()
{
C<A> c = new C<A>();
C<B> d = new C<B>();
}
}
d對象在編譯時報錯:The type B must have a public parameterless constructor in order to use it as parameter 'T' in the generic type or method C<T>
注意:C#現在只支持無參的構造器約束
此時由於我們為B類型寫入了一個有參構造器,使得系統不會再為B自動創建一個無參的構造器,但是如果我們將B類型中加一個無參構造器,那麼對象d的實例化就不會報錯了。B類型定義如下:
class B
{
public B()
{ }
public B(int i)
{ }
}
值類型/引用類型:
public struct A { }
public class B { }

public class C<T> where T : struct
{

}

C<A> c1 = new C<A>();
C<B> c2 = new C<B>();
c2對象在編譯時報錯:The type 'B' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or methor 'C<T>'.............
http://www.codefinds.net/Static/CC/SuanFa/2010-07/157.htm

⑸ java支持的編程範式

Java編程範式

1.命令式編程
核心內容就是:「用語句更改程序的狀態」
大多數流行的編程語言都或多或少基於命令式編程發展而來,命令式語言最典型的實例就是C語言

2.面向對象編程
面向對象編程經常與命令式編程聯系在一起,在實踐當中,兩者是可以共存的。Java就是這種協作的生動證明
面向對象基於四個基本原則:封裝、繼承、多態、抽象

3.聲明式編程
與命令式編程相反,聲明式編程它指定程序應該做什麼,而不具體說明怎麼做。
純粹的聲明式語言包括資料庫查詢語言(如SQL和Xpath)以及正則表達式。
與命令式編程語言相比,聲明式編程語言更加抽象,它們並不模擬硬體結構,因此不會改變程序狀態,而是將它們轉換為新狀態,並且更接近數學邏輯
通常,非命令是的編程範式都被認為屬於聲明式類別。

4.函數式編程
函數式編程是聲明式編程的子範式,與命令式編程相反,函數式變成不會改變程序的內部狀態。
在函數式編程術語中,函數類似於數學函數,函數的輸出僅依賴於其參數,而不管程序的狀態如何,完全不受函數式是何時執行的影響
函數式語言受歡迎的原因之一是它們可以輕松的在並行環境中運行,這與多線程不太一樣,函數式語言支持並行的關鍵在於它們的基本原理:函數僅依賴與輸入參數而不依賴於程序的狀態。它們可以在任何地方運行,然後將多個並行執行的結果連接起來並進一步使用

⑹ 面向對象的程序設計語言是什麼

面向對象程序設計(Object Oriented Programming,OOP)的實質是選用一種面向對象程序設計語言(OOPL),採用對象、類及其相關概念所進行的程序設計。

面向對象設計的結果,既可以用面向對象語言實現,也可以用非面向對象語言實現。面向對象程序設計語言本身就支持面向對象概念的實現,其編譯程序可以自動地實現面向對象概念到目標程序的映射。而且與非面向對象語言相比,面向對象語言還具有以下一些優點:

(1)一致的表示方法。

面向對象的採用方法從問題域表示到面向對象分析,再到面向對象設計與實現始終穩定不變。一致的表示方法不但有利於在軟體開發過程中始終使用統一的概念,也有利於維護人員理解軟體的各種配置成分。

(2)可重用性。

為了能帶來可觀的商業利益.必須在更廣泛的范圍中運用重用機制,而不是僅僅在程序設計這個層次上進行重用。軟體開發組織既可能重用它在某個問題域內的OOA結果,也可能重用相應的OOD和OOP結果。

⑺ c語言的編程範式是命令式還是聲明式

C語言是命令式編程語言,編程方式是將某種演算法表示為一系列指令讓機器去執行,從而獲得結果。常見的命令式語言除了C之外還有FORTRAN, Pascal, Ada等等,最早的機器語言也屬於命令式編程範式。
聲明式編程語言要求用戶描述具體問題而不是演算法,然後機器會選擇預先設立好的演算法去解決這些問題。聲明式的語言有GPSS和Prolog等等。

也就是說,命令式編程要求你告訴機器該怎麼做,而聲明式要求你告訴機器該做什麼。

⑻ 什麼是多範式編程語言,其中的「多範式」是什麼意思

所謂編程範式(programming paradigm),指的是計算機編程的基本風格或典範模式。借用哲學的術語,如果說每個編程者都在創造虛擬世界,那麼編程範式就是他們置身其中自覺不自覺採用的世界觀和方法論。我們知道,編程是為了解決問題,而解決問題可以有多種視角和思路,其中普適且行之有效的模式被歸結為範式。比如我們常用的「面向對象編程」就是一種範式。由於著眼點和思維方式的不同,相應的範式自然各有側重和傾向,因此一些範式常用『oriented』來描述。換言之,每種範式都引導人們帶著某種的傾向去分析問題、解決問題,這不就是「導向」嗎?如果把一門編程語言比作兵器,它的語法、工具和技巧等是招法,它採用的編程範式則是心法。編程範式是抽象的,必須通過具體的編程語言來體現。它代表的世界觀往往體現在語言的核心概念中,代表的方法論往往體現在語言的表達機制中。一種範式可以在不同的語言中實現,一種語言也可以同時支持多種範式。比如,PHP可以面向過程編程,也可以面向對象編程。任何語言在設計時都會傾向某些範式,同時迴避某些範式,由此形成了不同的語法特徵和語言風格。抽象的編程範式須要通過具體的編程語言來體現。範式的世界觀體現在語言的核心概念之中,範式的方法論體現在語言的表達機制中。一種語言的語法和風格與其所支持的編程範式密切相關。

⑼ 在哪種程序範式中,程序員主要關注的是「什麼是」

編程範式一詞最早來自 Robert Floyd 在 1979 年圖靈獎的頒獎演說,是程序員看待程序應該具有的觀點,代表了程序設計者認為程序應該如何被構建和執行的看法,與軟體建模方式和架構風格有緊密關系。
現在主流的編程範式有三種:

結構化編程(structured programming)
面向對象編程(object-oriented programming)
函數式編程(functional programming)

熱點內容
平板的數字密碼在哪裡設置 發布:2024-04-20 18:39:13 瀏覽:971
華為雲連接伺服器 發布:2024-04-20 18:34:35 瀏覽:108
c語言ini文件讀寫 發布:2024-04-20 18:34:30 瀏覽:690
c語言宏定義字元串 發布:2024-04-20 18:22:45 瀏覽:471
現在玩游戲的電腦需要什麼配置 發布:2024-04-20 17:09:57 瀏覽:195
游樂園的密碼一般為多少 發布:2024-04-20 17:09:51 瀏覽:41
興元安卓機怎麼進系統 發布:2024-04-20 17:07:16 瀏覽:806
我的世界伺服器如何放村民 發布:2024-04-20 17:05:35 瀏覽:359
手機反編譯dex 發布:2024-04-20 17:01:01 瀏覽:704
安卓怎麼設置微信拍一拍 發布:2024-04-20 16:44:48 瀏覽:569