推薦序
在IT技術高速發展的今天,雲端運算、人工智慧、巨量資料和雲端原生應用等新興技術的發展為我們的生活帶來了翻天覆地的變化,也對軟體開發者提出了更高的要求,特別是在人工智慧開發領域,應運而生的新概念讓人目不暇接。
作為一個.NET開發者,在開發機器學習專案的過程中會遇到很多困難。主要原因之一是我們認為C#不是適合該工作的程式語言,Python和R語言才是,而C#語言更適合用於機器學習的前期資料分析階段。
不知道各位有沒有思考一下為什麼微軟公司要在.NET平臺上引入機器學習,以及我們為什麼要探索機器學習。
一個原因是,機器學習技術正在跨越鴻溝。事實上,這個鴻溝是非常難以跨越的,之所以那麼多的高科技產品只在小眾範圍內流傳,而沒有被主流市場接受,是因為相關技術沒有跨越這個鴻溝。最早的機器學習演算法可以追溯到20世紀初,到今天為止,已經過去了100多年。從1980年機器學習技術成為一個獨立的方向開始算起,到現在已經過去了40多年。在這100多年中,經過一代又一代人的努力,近幾年機器學習技術終於跨越了鴻溝。跨越鴻溝表示機器學習技術正在從僅有少數人掌握的時代過渡到大多數人掌握的時代。微軟公司的CEO薩提亞·納德拉在他寫的《更新:重新發現商業與未來》一書中提出「民主化」的人工智慧,ML.NET正是要完成這項使命的載體之一。如何實現人工智慧「民主化」,讓它惠及每個人?如何讓每個人打造自己的人工智慧?在醫療、教育和零售機構中,打造一個相適應的人工智慧是非常重要的。當我們談人工智慧的時候,不能空談任何一個人工智慧公司,而要「民主化」人工智慧,讓人工智慧真正落地應用到個人。
我們應該探索機器學習的另一個原因是,作為人類,我們會產生大量資料,卻無法處理全部資料;從技術上講,我們面臨無法從資料中提取資訊的問題。此時,機器學習模型可以幫助我們處理巨量的資料。
在.NET生態上,人工智慧領域有一個開放原始碼團隊SciSharp Stack,他們為TensorFlow提供了.NET Standard Binding,旨在用C#實現完整的TensorFlow API,允許.NET開發人員使用跨平臺的.NET Standard框架開發、訓練和部署機器學習模型。他們打造了一個完全屬於.NET開發人員自己的機器學習平臺——TensorFlow.NET,對C#開發人員來說,這是一個零學習成本的機器學習平臺,該平臺整合了大量的API和底層封裝,力圖使TensorFlow的Python程式風格和程式設計習慣無縫移植到.NET平臺上。
雖然有大量的TensorFlow文件可以參考,但是對初學者來說,其中涉及的知識難免晦澀,特別是對.NET的開發人員來說,缺少便於上手的指南及來自生產實踐的案例複習。因此,一本系統地介紹TensorFlow.NET的圖書是很有必要的,這樣可以讓更多的.NET開發人員把人工智慧應用於生產實踐之中。
這是本書的目的和價值。本書採用.NET 5.0進行實踐,可能在本書發佈的時候.NET 6.0已經發佈,程式從.NET 5.0升級到.NET 6.0是很平滑的,請務必一邊實際運行程式,一邊閱讀本書。
微軟MVP、騰訊雲TVP、華為雲MVP 張善友
序一
幾年前一次偶然的機會接觸到機器學習領域,對我這樣習慣了十幾年強規則型機器程式開發的「老藍領程式設計師」來說,就像發現了一塊新大陸。我充滿了好奇,於是迫不及待地開啟了機器學習探索之旅。在經歷了滿世界找文件、看論文和研究演算法後,我漸漸地發現了自己力所能及並可能有所貢獻的機會。在網際網路上能找到的有關機器學習方面的範例中,幾乎99%的範例都是用Python寫的,剩下的是用C/C++寫的,可以說是Python「獨霸天下」的局面,讓人誤以為做機器學習專案就必須用Python。這個情況讓我萌生了移植一些常用的機器學習庫到.NET生態的想法,最初的想法是透過遷移這些庫來加深對機器學習的掌握程度,揭開「時髦」詞彙人工智慧(AI)和機器學習(ML)背後的秘密。
目前機器學習流行的基礎函式庫NumPy是首先要進行移植的,於是產生了NumSharp這個張量計算函式庫,移植過程並不是很順利,因為張量計算對我來說是一個全新的概念。要實現一個和現有NumPy函式庫可以相互替換的.NET函式庫比想像中更難,最具有挑戰性的是它對函式性能的要求很高。最後的效果是只移植了表面上的介面和一小部分API,滿足了少部分模型的計算要求,但性能較差,.NET天生在這方面不能和C/C++ 相提並論,雖然有SIMD的加持,但是實現起來仍然非常不方便。
隨著對機器學習的不斷深入了解,我逐步接觸了神經網路和深度學習知識。神經網路帶我進入了一個魔幻的世界,裡面充滿未知。當時Google的TensorFlow開放原始碼深度學習框架正火遍全球,同時期的PyTorch嶄露頭角,所以第一個進入目標移植深度學習庫的就是TensorFlow了,我稱之為TensorFlow.NET。
移植工作從「Hello World!」開始,API逐步增多,複雜性隨之增加,從靜態圖到動態圖,再到上層的Keras,基本上都實現了。在程式撰寫的過程中,因為專案從一開始就是在GitHub上開放原始碼的,所以我不斷收到各種各樣的使用回饋。正因為有這樣的回饋互動,我才有了不斷完善這個專案的動力。在此過程中,我結識了仇華——在影像辨識領域深耕多年的朋友,並產生了應該撰寫一本關於如何使用TensorFlow.NET的書籍的想法,把現有的範例程式透過圖文講解的方式呈現給讀者,於是有了這本書。書中詳細介紹了從張量計算到神經網路模型的架設,從理論程式開發到工業場景重現的剖析,範例涵蓋線性回歸、邏輯回歸、全連接神經網路、文字分類、影像分類和遷移學習等,是幫助.NET開發者進入機器學習世界的寶貴資料。
最後要感謝在專案編碼和宣傳上給予過我幫助的人,特別是家人對我在開放原始碼專案方面的支持,因為做開放原始碼專案幾乎佔用了我所有的業餘時間和精力,照顧3個孩子的重任都由我太太承擔了。
SciSharp Stack開放原始碼社區創辦者 陳海平
序二
我寫這本書的初衷原本是為SciSharp Stack開放原始碼社區貢獻一點自己的力量,為使用C#開發TensorFlow深度學習模型的朋友們提供一個快速入門的指南。寫著寫著,我發現很多語法和程式需要搭配理論知識才能更進一步地讀懂,因而逐漸增加了很多機器學習和深度學習的理論知識,包括在TensorFlow 2.x之後出現的一些新特性的專題說明,如Eager Mode、AutoGraph和Keras等。同時考慮到本書的定位,儘量避開了複雜數學公式的推導,而以API文件說明和實踐應用為主。作為市面上第一本,也是目前唯一的一本TensorFlow.NET開放原始碼庫官方出品的專門.NET開發者導向的TensorFlow中文開發書籍,很多社區的朋友和.NET開發者在本書的撰寫過程中提供了寶貴的建議,在大家的熱切推薦下,書中增加了大量的案例實踐,包括影像分類、物件辨識、自然語言、生成對抗等不同領域的應用。
2021年年底,這本入門手冊終於接近完成。記得我是在2019年11月認識的陳海平先生,對我個人來說,他是我進入開放原始碼社區這個新世界的領路人。當時我在實際專案開發過程中遇到了一個比較困難的抉擇(後來發現幾乎所有.NET開發者在實際專案中應用深度學習框架都會遇到這個痛點),就是現有深度學習框架以Python語言開發為主和實際工業專案以C#語言開發為主之間的矛盾。網路上有很多的解決方案。大約花了1個月的時間,我對常見的各種解決方案進行了現場專案測試和多維度的比較,綜合考慮深度學習模型GPU訓練的必要性和在實際項目中部署的便利性後,選擇了TensorFlow.NET作為自己的專案開發框架。找對方向後,我深入學習和了解了這個框架,驚喜地發現這個框架的創立者陳海平先生是一名華人,並且幾乎憑一己之力建立了TensorFlow.NET這個超級龐大而複雜的專案,陳海平先生的開發能力和開放原始碼精神令我敬佩不已,他在我心中成為大神級的存在,本書中的案例程式幾乎都是他開發的。
從2019年加入SciSharp Stack開放原始碼社區起,在大約1年的時間裡,我陸續發表了一些TensorFlow.NET相關的技術部落格文章,並在一些大學校園和所究所學生院裡給學校的老師和同學們宣導TensorFlow.NET在實際工業項目中的應用,也在微軟年度的.NET大會上給大家做了TensorFlow.NET的專題報告。作為Google蘇州TensorFlow User Group的創立者,我在每一次社區的技術公益活動中都會對TensorFlow.NET進行推廣和入門應用講解。期間,我也經常和海平聊起要給TensorFlow.NET出一個官方教學,並在GitHub上建立了庫進行教學的更新,斷斷續續地出了一些入門視訊教學和技術文章,但遲遲沒有系統地開展出書的工作。轉捩點大約在2020年的12月,F#語言之父Don Syme大神加入了我們的SciSharp Stack開放原始碼社區,帶來了F#語言同好的開發團體。至此,C#和F#這兩大.NET核心開發語言的開發者們都加入了我們的社區。隨著社區成員的壯大和熱度的提升,出書的任務迫在眉睫,官方教學的需求愈加熱烈,因此我們打算靜下心來快速地把這個教學製作完成。
出書比想像中要難,在差不多1年半的時間裡,這件事幾乎佔用了我所有的個人業餘時間,寫書過程中的點滴故事我至今記憶猶新。在每個夜深人靜的晚上,查詢資料、斟酌語詞、撰寫測試程式,為了確保這類技術書籍的準確性,書中的每個案例和程式都需要仔細地撰寫完,並在機器上實際跑一遍,不斷偵錯最佳化,確保讀者在實踐過程中沒有錯誤。可以說,這是我目前做過的單一工程量最大的事情,但是回首看,也收穫了很多,對於TensorFlow的整體框架有了更系統的認識,對機器學習和深度學習的發展歷史和理論結構也有了更深入的了解。為了講清楚F#的應用,我學習了一門新的語言,深深感受到了函式式程式設計的魅力所在。
IT技術更新飛快,深度學習領域的各種創新是層出不窮的,在本書的撰寫過程中,TensorFlow從1.x升級到了2.x,新增了很多功能和特性,.NET也推出了.NET 5.0,.NET 6.0的預覽版也發佈了,正式版不久也要面世。本書儘量做到與時俱進,書中的程式主要基於TensorFlow 2.x和.NET 5.0,讀者可以根據時下最新的語言和框架版本進行升級應用。本書適用於有一些機器學習或深度學習基礎,希望在實際生產項目中應用TensorFlow的.NET開發者和工程師。在撰寫此書的過程中,由於個人能力有限,書中肯定有很多的不足和缺陷,也有很多案例沒有來得及開發完成,包括時序分析和時下比較熱門的Transform模型等,希望讀者們能提供寶貴的意見和想法,我們期望有機會在下一版本或英文版中得到完善。
本書的出版獲得了SciSharp Stack社區、微軟技術俱樂部、TensorFlow User Group的多位朋友的幫助和支持,他們不但為本書的範例程式提供了建議和測試結果,而且提供了本書的方向和需求點,為本書的完成做出了重要貢獻。
本書中的案例程式主要來自SciSharp Stack Examples,其中C#部分主要由陳海平提供,F#部分主要由Vianney P.提供。生成對抗網路的案例程式由社區成員彭波提供,卷積神經網路視覺化的案例程式和張量檢視器由社區成員久永提供,煤礦礦區的時間序列預測應用案例程式由社區成員孫翔宇提供。在此特別表示感謝。
本書的出版過程獲得了微軟技術俱樂部的潘淳校長、盛派網路科技的蘇震巍主席、.NET圈子知名的微軟MVP張善友隊長和資料工程暢銷書作者齊偉老師的共同指導和大力幫助。在此一併表示由衷的謝意。
衷心感謝電子工業出版社的符隆美編輯對本書的細緻編校及出版流程跟進。
感謝我的太太在我寫書過程中給予的關注和大力支持,因為寫書佔據了我太多的業餘時間和精力,家裡兩個孩子全交給太太照顧了。依稀記得,2019年的大年夜晚上,在老家父母的家中,我剛剛完成了第2篇關於TensorFlow.NET的案例文章,並在筆記型電腦上使用GPU成功測試了程式,而窗外,我的太太正帶著兩個孩子在放煙火。也記得,不知多少個伏案疾書的夜晚,每當完成一個章節並提交到了GitHub,我都會在寫書計畫表上劃去一項,並在心裡暗自慶祝進度又推進一格,在此真誠地感謝太太給我創造的專注的寫作環境。
最後,感謝所有支持並幫助我們社區的朋友。
SciSharp Stack開放原始碼社區核心組成員 仇華(Henry)