斯坦福編程範式
A. C語言之父——丹尼斯·里奇
人們對里奇的紀念,遠不及對喬布斯鋪天蓋地的悼念。可是,里奇值得人們那樣去做。
還是有人出來說了句公道話。
「史蒂夫·喬布斯去世引發了巨大的反響,這當然合情合理。即便影響實際上更為廣泛,丹尼斯卻不為公眾所知」,羅伯·派克說。羅伯是一名在Google工作的程序員,作為業界的傳奇性人物,曾經與里奇在著名的貝爾實驗室共事20年。
周三晚間,派克在Google+上發表消息稱,在與病魔進行長久的抗爭後,里奇於上周末在新澤西的家中溘然長逝。雖然在技術圈內引起大量反響,但在主流媒體上,里奇卻沒有得到同巨大影響相稱的悼念。丹尼斯·里奇作為C語言之父,和貝爾實驗室資深研究員肯·湯姆森一起使用C語言開發了Unix,當今世界大量依賴的操作系統,其中包括史蒂夫·喬布斯治下的蘋果帝國。
「現下互聯網基本都在用這兩樣東西:C語言和UNIX」,派克對《連線》雜志稱,「瀏覽器是用C語言寫的。UNIX的內核——基本上是網際網路運作的基礎——也是用C寫的。Web伺服器也是用C語言寫的,如果不是的話,那就是用Java或者C++寫的,兩者都是C語言的派生;要不就是python或者Ruby,用C語言實現的。然後我幾乎敢保證,運行這些程序的網路硬體,是用C語言開發的軟體驅動的。」
「幾乎很難誇大丹尼斯在信息經濟基礎設施方面無所不在的影響力。」
他補充說,Windows曾經也是用C語言編寫,而UNIX同時也支撐了蘋果桌面操作系統Mac OS X,以及iPhone與iPad的操作系統iOS。「如果說喬布斯是台前之王,那裡奇就是幕後之王。」MIT電氣工程與計算機系教授Martin Rinard如此評價道。Rinard也是計算機科學與人工智慧實驗室的成員。
「喬布斯的過人之處在於其品位獨特,打造人們為之著迷並引人注目的產品。而里奇卻擅長於開發一些技術人員使用的基礎設施,天天被人們使用卻不為人知。」
從B語言到C語言
為了更好開發UNIX,丹尼斯·里奇而發明了C語言。最初的UNIX內核使用匯編語言編寫,之後他們很快決定要用一種高級語言,讓他們更好的駕馭操作系統中的復雜數據。1970年左右,他們嘗試使用Fortran,不過沒有達到預期目標。接著,在湯姆森創立的B語言基礎上,里奇提出了一門新語言
不管你是從哪裡聽來的消息,B語言得名於湯姆森的妻子Bonnie,抑或是BCPL,一門劍橋於60年代中期開發的語言。
B語言是一種解釋性語言——意味著它由一個運行於CPU之上的中間件解釋執行——而C卻是一門編譯語言。它被翻譯成機器代碼,在CPU上直接執行。即便如此,C當時被認為是一門高級語言。C語言提供了里奇和湯姆森想要的靈活性,卻也很快。
關於里奇一直流傳的一個笑話是:C語言同時擁有了「匯編語言的強大能力以及...匯編語言的便利性」。換句話說,他承認C語言並不完美,並且十分接近硬體層次。如今C語言被認為是一門低級語言而不是高級語言。不過這個笑話並不公平。C語言提供了真正的數據結構概念,從這個角度來說已經足夠高級了。
「當你在編寫一個大型程序——比如UNIX——你必須管理好各種各樣模塊之間的交互:所有用戶、文件系統、磁碟、程序執行等等。而有效的管理則需要良好的數據表示,這就是所謂的數據結構」,派克說。
「在沒有數據結構組織的情況下,編寫一個與UNIX一樣一致和優雅的內核基本上是不可能的。需要一個機制組織好數據,而Fortran卻不擅長於此。」
在那個時候,寫一個操作系統並不多見,這也給了里奇和湯姆森機會,在70年代末把操作系統移植到其它平台。「從此UNIX洪水之門被打開」,派克說,「這全都多虧有了C語言。」
蘋果、微軟及其他
與此同時,C語言也開始傳播到全世界,從貝爾實驗室到全世界的大學,也到了微軟,一個在80年代異軍突起的軟體公司。「C語言的開發是一個重大的飛躍,是個很好的折衷...C語言達到了完美的平衡,讓你在較高層次高效率開發的同時,卻不失去對每處細節的控制」,NVIDIA和貝爾的首席科學家兼斯坦福大學工程系教授Bill Dally說。「它為之後數十年來軟體開發定下了基調。」
正如派克指出的那樣,C語言內置的數據結構後來發展出面向對象範式,被現代編程語言如C++和Java大量採用。
1973年,里奇發表了關於這門語言的論文,被認為是革命開始的標志。5年後,他和同事布萊恩·克尼漢(Brian Kernighan)發布了C語言的權威著作:《C程序設計語言》。該書最早是克尼漢為C語言編寫的教程,後來他拉著丹尼斯一起把書寫完。
當派克還在多倫多大學讀本科的時候,在一個因病返家的下午里讀到了這本書。「那本參考手冊相對於其他的手冊而言,簡直就是清晰和可讀的典範。毋庸置疑是一部經典之作。」,他說,「我生病躺床上翻一翻,沒想到竟讓我忘記了病痛。」
和許多大學生一樣,Pike那時已經開始使用C語言了。由於貝爾實驗室開始分發UNIX源代碼,它逐漸風靡大學校園。此外,UNIX還催生了現代開源運動。這並不是什麼言過其實,里奇的影響之大怎麼說都不為過。即便里奇在1983年獲得的圖靈獎和1998年獲得的國家技術勛章也不能完全彰顯他的貢獻。
在克尼漢和派克眼中,里奇是一個少有的孤僻的人。「我和他一同工作了超過20個年頭,但還是覺得不是很了解他這個人」,派克說。但這並不是他低調的理由。史蒂夫·喬布斯也是一個孤僻的人,只不過保持低調只使得人們對他的崇拜有增無減。
里奇所處的時代和工作環境與喬布斯千差萬別,這也許是他未得到應得紀念的原因。但是,他留下的遺產總有大佬能夠明白。「眾所周知牛頓說過他是站在巨人的肩膀上」,克尼漢說,「我們都站在丹尼斯的肩膀上。」
B. 如何系統地自學 Python
是否非常想學好 Python,一方面被瑣事糾纏,一直沒能動手,另一方面,擔心學習成本太高,心裡默默敲著退堂鼓?
幸運的是,Python 是一門初學者友好的編程語言,想要完全掌握它,你不必花上太多的時間和精力。
Python 的設計哲學之一就是簡單易學,體現在兩個方面:
語法簡潔明了:相對 Ruby 和 Perl,它的語法特性不多不少,大多數都很簡單直接,不玩兒玄學。
切入點很多:Python 可以讓你可以做很多事情,科學計算和數據分析、爬蟲、Web 網站、游戲、命令行實用工具等等等等,總有一個是你感興趣並且願意投入時間的。
- 用一種方法,最好是只有一種方法來做一件事。
廢話不多說,學會一門語言的捷徑只有一個: Getting Started
¶ 起步階段
任何一種編程語言都包含兩個部分:硬知識和軟知識,起步階段的主要任務是掌握硬知識。
硬知識
「硬知識」指的是編程語言的語法、演算法和數據結構、編程範式等,例如:變數和類型、循環語句、分支、函數、類。這部分知識也是具有普適性的,看上去是掌握了一種語法,實際是建立了一種思維。例如:讓一個 Java 程序員去學習 Python,他可以很快的將 Java 中的學到的面向對象的知識 map 到 Python 中來,因此能夠快速掌握 Python 中面向對象的特性。
如果你是剛開始學習編程的新手,一本可靠的語法書是非常重要的。它看上去可能非常枯燥乏味,但對於建立穩固的編程思維是必不可少。
下面列出了一些適合初學者入門的教學材料:
廖雪峰的 Python 教程 Python 中文教程的翹楚,專為剛剛步入程序世界的小白打造。
笨方法學 Python 這本書在講解 Python 的語法成分時,還附帶大量可實踐的例子,非常適合快速起步。
The Hitchhiker』s Guide to Python! 這本指南著重於 Python 的最佳實踐,不管你是 Python 專家還是新手,都能獲得極大的幫助。
Python 的哲學:
學習也是一樣,雖然推薦了多種學習資料,但實際學習的時候,最好只選擇其中的一個,堅持看完。
必要的時候,可能需要閱讀講解數據結構和演算法的書,這些知識對於理解和使用 Python 中的對象模型有著很大的幫助。
軟知識
「軟知識」則是特定語言環境下的語法技巧、類庫的使用、IDE的選擇等等。這一部分,即使完全不了解不會使用,也不會妨礙你去編程,只不過寫出的程序,看上去顯得「傻」了些。
對這些知識的學習,取決於你嘗試解決的問題的領域和深度。對初學者而言,起步階段極易走火,或者在選擇 Python 版本時徘徊不決,一會兒看 2.7 一會兒又轉到 3.0,或者徜徉在類庫的大海中無法自拔,Scrapy,Numpy,Django 什麼都要試試,或者參與編輯器聖戰、大括弧縮進探究、操作系統辯論賽等無意義活動,或者整天跪舔語法糖,老想著怎麼一行代碼把所有的事情做完,或者去構想聖潔的性能安全通用性健壯性全部滿分的解決方案。
很多「大牛」都會告誡初學者,用這個用那個,少走彎路,這樣反而把初學者推向了真正的彎路。
還不如告訴初學者,學習本來就是個需要你去走彎路出 Bug,只能腳踏實地,沒有奇跡只有狗屎的過程。
選擇一個方向先走下去,哪怕臟丑差,走不動了再看看有沒有更好的解決途徑。
自己走了彎路,你才知道這么做的好處,才能理解為什麼人們可以手寫狀態機去匹配卻偏要發明正則表達式,為什麼面向過程可以解決卻偏要面向對象,為什麼我可以操縱每一根指針卻偏要自動管理內存,為什麼我可以嵌套回調卻偏要用 Promise...
更重要的是,你會明白,高層次的解決方法都是對低層次的封裝,並不是任何情況下都是最有效最合適的。
技術涌進就像波浪一樣,那些陳舊的封存已久的技術,消退了遲早還會涌回的。就像現在移動端應用、手游和 HTML5 的火熱,某些方面不正在重演過去 PC 的那些歷史么?
因此,不要擔心自己走錯路誤了終身,堅持並保持進步才是正道。
起步階段的核心任務是掌握硬知識,軟知識做適當了解,有了穩固的根,粗壯的枝幹,才能長出濃密的葉子,結出甜美的果實。
¶ 發展階段
完成了基礎知識的學習,必定會感到一陣空虛,懷疑這些語法知識是不是真的有用。
沒錯,你的懷疑是非常正確的。要讓 Python 發揮出它的價值,當然不能停留在語法層面。
發展階段的核心任務,就是「跳出 Python,擁抱世界」。
在你面前會有多個分支:科學計算和數據分析、爬蟲、Web 網站、游戲、命令行實用工具等等等等,這些都不是僅僅知道 Python 語法就能解決的問題。
拿爬蟲舉例,如果你對計算機網路,HTTP 協議,HTML,文本編碼,JSON 一無所知,你能做好這部分的工作么?而你在起步階段的基礎知識也同樣重要,如果你連循環遞歸怎麼寫都還要查文檔,連 BFS 都不知道怎麼實現,這就像工匠做石凳每次起錘都要思考錘子怎麼使用一樣,非常低效。
在這個階段,不可避免要接觸大量類庫,閱讀大量書籍的。
類庫方面
「Awesome Python 項目」:vinta/awesome-python · GitHub
這里列出了你在嘗試解決各種實際問題時,Python 社區已有的工具型類庫,如下圖所示:
vinta/awesome-python
你可以按照實際需求,尋找你需要的類庫。
至於相關類庫如何使用,必須掌握的技能便是閱讀文檔。由於開源社區大多數文檔都是英文寫成的,所以,英語不好的同學,需要惡補下。
書籍方面
這里我只列出一些我覺得比較有一些幫助的書籍,詳細的請看豆瓣的書評:
科學和數據分析:
❖「集體智慧編程」:集體智慧編程 (豆瓣)
❖「數學之美」:數學之美 (豆瓣)
❖「統計學習方法」:統計學習方法 (豆瓣)
❖「Pattern Recognition And Machine Learning」:Pattern Recognition And Machine Learning (豆瓣)
❖「數據科學實戰」:數據科學實戰 (豆瓣)
❖「數據檢索導論」:信息檢索導論 (豆瓣)
爬蟲:
❖「HTTP 權威指南」:HTTP權威指南 (豆瓣)
Web 網站:
❖「HTML & CSS 設計與構建網站」:HTML & CSS設計與構建網站 (豆瓣)
...
列到這里已經不需要繼續了。
聰明的你一定會發現上面的大部分書籍,並不是講 Python 的書,而更多的是專業知識。
事實上,這里所謂「跳出 Python,擁抱世界」,其實是發現 Python 和專業知識相結合,能夠解決很多實際問題。這個階段能走到什麼程度,更多的取決於自己的專業知識。
¶ 深入階段
這個階段的你,對 Python 幾乎了如指掌,那麼你一定知道 Python 是用 C 語言實現的。
可是 Python 對象的「動態特徵」是怎麼用相對底層,連自動內存管理都沒有的C語言實現的呢?這時候就不能停留在表面了,勇敢的拆開 Python 的黑盒子,深入到語言的內部,去看它的歷史,讀它的源碼,才能真正理解它的設計思路。
這里推薦一本書:
「Python 源碼剖析」:Python源碼剖析 (豆瓣)
這本書把 Python 源碼中最核心的部分,給出了詳細的闡釋,不過閱讀此書需要對 C 語言內存模型和指針有著很好的理解。
另外,Python 本身是一門雜糅多種範式的動態語言,也就是說,相對於 C 的過程式、 Haskell 等的函數式、Java 基於類的面向對象而言,它都不夠純粹。換而言之,編程語言的「道學」,在 Python 中只能有限的體悟。學習某種編程範式時,從那些面向這種範式更加純粹的語言出發,才能有更深刻的理解,也能了解到 Python 語言的根源。
這里推薦一門公開課
「編程範式」:斯坦福大學公開課:編程範式
講師高屋建瓴,從各種編程範式的代表語言出發,給出了每種編程範式最核心的思想。
值得一提的是,這門課程對C語言有非常深入的講解,例如C語言的范型和內存管理。這些知識,對閱讀 Python 源碼也有大有幫助。
Python 的許多最佳實踐都隱藏在那些眾所周知的框架和類庫中,例如 Django、Tornado 等等。在它們的源代碼中淘金,也是個不錯的選擇。
¶ 最後的話
每個人學編程的道路都是不一樣的,其實大都殊途同歸,沒有迷路的人只有不能堅持的人!
希望想學 Python 想學編程的同學,不要猶豫了,看完這篇文章,
Just Getting Started !!!
C. 如何系統地自學 Python
按照這個大綱按部就班的學習,就能系統的學習Python了!
階段一:Python開發基礎
Python全棧開發與人工智慧之Python開發基礎知識學習內容包括:Python基礎語法、數據類型、字元編碼、文件操作、函數、裝飾器、迭代器、內置方法、常用模塊等。
階段二:Python高級編程和資料庫開發
Python全棧開發與人工智慧之Python高級編程和資料庫開發知識學習內容包括:面向對象開發、Socket網路編程、線程、進程、隊列、IO多路模型、Mysql資料庫開發等。
階段三:前端開發
Python全棧開發與人工智慧之前端開發知識學習內容包括:Html、CSS、JavaScript開發、Jquery&bootstrap開發、前端框架VUE開發等。
階段四:WEB框架開發
Python全棧開發與人工智慧之WEB框架開發學習內容包括:Django框架基礎、Django框架進階、BBS+Blog實戰項目開發、緩存和隊列中間件、Flask框架學習、Tornado框架學習、Restful API等。
階段五:爬蟲開發
Python全棧開發與人工智慧之爬蟲開發學習內容包括:爬蟲開發實戰。
階段六:全棧項目實戰
Python全棧開發與人工智慧之全棧項目實戰學習內容包括:企業應用工具學習、CRM客戶關系管理系統開發、路飛學城在線教育平台開發等。
階段七:演算法&設計模式
階段八:數據分析
Python全棧開發與人工智慧之數據分析學習內容包括:金融量化分析。
階段九:機器學習、圖像識別、NLP自然語言處理
Python全棧開發與人工智慧之人工智慧學習內容包括:機器學習、圖形識別、人工智慧玩具開發等。
階段十:Linux系統&百萬級並發架構解決方案
階段十一:高並發語言GO開發
Python全棧開發與人工智慧之高並發語言GO開發學習內容包括:GO語言基礎、數據類型與文件IO操作、函數和面向對象、並發編程等。
D. 人工智慧需要學習哪些課程
人工智慧專業學習的主要課程有認知心理學、神經科學基礎、人類的記憶與學習、語言與思維、計算神經工程等。人工智慧專業是中國高校人才計劃設立的專業,旨在培養中國人工智慧產業的應用型人才,推動人工智慧一級學科建設。
E. 網易公開課的大學課程
網易公開課課程內容不斷更新,以下為部分課程舉例。 《編程方法學》全28集 翻譯至第28集
《7個顛覆你思想的演講》 全7集 翻譯至第7集(網易首翻1-5集)
《經濟學》 全10集 翻譯至第10集(網易首翻1-5集)
《商業領袖和企業家》 全4集 翻譯至第4集(網易首翻1-4集)
《人與計算機的互動》全10集 翻譯至第10集
《扎克伯格談facebook創業過程》 全9集 翻譯至第9集
《iphone開發教程2010年冬》 全28集 翻譯至第26集
《機器學習課程》 全20集 翻譯至第20集
《抽象編程》 全27集 翻譯至第27集
《編程範式》 全27集 翻譯至第27集
《法律學》 全6集 翻譯至第2集
《機器人學》全16集 翻譯至第2集
《健康圖書館》全80集 翻譯至第80集
《臨床解剖學》 全14集 翻譯至第14集
《癌症綜合研究》全56集 翻譯至第56集
《從生物學看人類行為》 全25集 翻譯至第25集
《非裔美國人歷史——當代自由斗爭》全18集 翻譯至第10集
《斯坦福創意與藝術協會講座》 全16集 翻譯至第0集
《忘掉你學過的MBA——戴維談創業37 signals》全11集 翻譯至11集
《全球氣候與能源計劃》 全12集 翻譯至第1集 《國際座談會》 全17集 翻譯至第17集(網易首翻1-12集)
《領導能力簡介》 全5集 翻譯至第5集(網易首翻1-5集)
《能源和環境》 全11集 翻譯至第1集
《人性》 全12集 翻譯至第12集
《科技世界的領導能力》 全15集 翻譯至第15集 《電影哲學》 全4集 翻譯至第4集(網易首翻1-4集)
《西方世界的愛情哲學》 全4集 翻譯至第4集(網易首翻1-2集)
《音樂的各種聲音》 全1集 翻譯至第1集
《振動與波》 全23集 翻譯至第23集
《單變數微積分》 全35集 翻譯至第15集
《微分方程》 全33集 翻譯至第15集
《媒體、教育、市場》 全14集 翻譯至第14集
《商業及領導能力》 全16集 翻譯至第1集
《熱力學與動力學》 全36集 翻譯至第30集
《搜索黑洞》 全6集 翻譯至第6集
《城市面貌——過去和未來》全4集 翻譯至第0集
《經典力學》 全35集 翻譯至第35集
《生物學導論》 全35集 翻譯至第35集
《微積分重點》 全18集 翻譯至第18集
《多變數微積分》全35集 翻譯至第35集
《化學原理》 全36集 翻譯至第31集
《演算法導論》 全6集 翻譯至第6集
《計算機科學及編程導論》 全24集 翻譯至第23集 《幸福課》 全23集 翻譯至第23集(網易首翻1-5集)
《公正—該如何做是好?》 全12集 翻譯至第12集
《計算機科學導論》 全22集 翻譯至第0集
《2006年計算機課程》 全32集(缺第3、5、7、集) 翻譯至第0集
《2005年計算機課程》 全15集 翻譯至第0集
《計算機科學cs50》 全20集 翻譯至第17集
《科學與烹飪》 翻譯至22集 《空氣污染》集數:5 類型:科學 環境 社會
《十分鍾英語史》集數:10 類型:歷史 文學
《銀行業危機-源起與後果》集數:7 類型:金融 經濟 《古希臘歷史簡介》 全24集 翻譯至第8集 (1-8集字幕由人人字幕組提供)
《聆聽音樂》 全23集 翻譯至第10集(網易首翻5-10集)(1-4集字幕由人人字幕組提供)
《死亡》 全26集 翻譯至第11集(網易首翻8-21集)(1-7集字幕由人人字幕組提供)
《心理學導論》 全20集 翻譯至第18集(網易首翻9-18集)(1-8集字幕由人人字幕組提供)
《政治哲學導論》 全24集 翻譯至第14集(網易首翻1-14集)
《金融市場》 全26集 翻譯至第17集(網易首翻14-17集)(1-13集字幕由人人字幕組提供)
《博弈論》 全24集 翻譯至第9集 (1-9集字幕由人人字幕組提供)
《歐洲文明》 全24集 翻譯至第23集 (1-23集字幕由TLF字幕組提供)
《1871年後的法國》 全24集 翻譯至第3集 (1-3集字幕由人人字幕組提供)
《基礎物理》 全24集 翻譯至第23集 (1-5集字幕由人人字幕組提供)
《羅馬建築》 全23集 翻譯至第4集 (1-4集字幕由TLF字幕組提供)
《天體物理學之探索和爭議》 全24集 翻譯至第10集 (1-10集字幕由TLF字幕組提供)
《生物醫學工程探索》 全25集 翻譯至第12集 (1-12集字幕由人人字幕組提供)
《新生有機化學》 全37集 翻譯至第10集 (1-10集字幕由人人字幕組提供)
《進化、生態和行為原理》 全36集 翻譯至第4集 (1-4集字幕由TLF字幕組提供)
《1945年後的美國小說》 全25集 翻譯至第3集 (1-3集字幕由人人字幕組提供)
《美國內戰與重建,1845-1877》 全27集 翻譯至第5集 (1-5集字幕由人人字幕組提供)
《全球人口增長問題》 全24集 翻譯至第7集 (1-7集字幕由TLF字幕組提供)
《有關食物的心理學、生物學和政治學》 全23集 翻譯至第7集 (1-7集字幕由人人字幕組提供)
《彌爾頓》 全24集
《文學理論導論》 全26集
《現代詩歌》 全25集
《解讀但丁》 全24集
《舊約全書導論 》全24集
《新約及其歷史背景》 全26集 《尼採的心靈與自然》 全7集
《哲學概論》 全17集 《綜合生物學》 全39集
《社會認知心理學》 全25集
《數據統計分析》 全42集
《世界各地區人民和國家》 全19集(缺第17、18、20)
《大災難時期的倫理和公共健康》 全14集 點擊右上方的「播放」按鈕,或者直接點擊課時按鈕,經過短暫的緩沖之後便可以開始在線收看課程,緩沖時會顯示課時和該課時視頻大小。由於是在線收看,因此課程的視頻和音頻不可能達到高清的效果,不過完全可以滿足授課的需要,並且在wifi環境下播放流暢,絲毫不會卡頓。此外手機本身需要支持MP4格式才可以收看在線課程,不過這項要求基本Android平台手機都可以達到。網易公開課的課程視頻對手機的硬體要求並不高,小編用setcpu將CPU頻率由1GHz降至500MHz後,仍然可以流暢播放。
播放過程中可以點擊屏幕任意位置叫出播放控制按鈕,用戶可以暫停/播放視屏,快進和快退,以及拖動進度條來跳轉至視頻的任意位置。但是小編在實際使用中發現,在某些情況下,拖動進度條會造成程序失去響應,實際能夠使用的只有快進/快退和播放/暫停三個按鍵。小編之後又用另一台手機Nexus S測試,發現強行關閉的問題仍然存在。 1、收集世界多所知名學府授課視頻;
2、wifi環境下播放流暢。 1、當視頻在線播放時拖動進度條,若遇網路環境不太好,或進程多系統繁忙,偶爾會出現無響應,造成程序強行關閉;
2、課程翻譯進度較慢。
F. 講C語言內存管理的書籍或者博客
我推薦的是斯坦福的一門公開課 -- 《編程範式》。不是題主說的博客或者書,但是個人覺得很好用,希望對你有幫助。
還有一些其他的編程語言,如方案、Python等。
我只看到了多線程同步的一部分,個人的感覺受益於它。如果以後還有別的發現,願意及時分享給大家。
G. 放棄手工標記數據,斯坦福大學開發弱監督編程範式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小技巧、 科技 數碼新聞!