第623章 這框架簡直是神器!
兩人湊近了屏幕,開始從基礎模塊往下看。
因為有著非常明確的目標——搭建一個用於圖像分類的神經網絡,他們直接跳過了閒篇,直奔核心API。
滑鼠滾輪不斷向下滑動,安靜的客廳里只有「咔噠咔噠」的聲音。
幾分鐘後,郭長征突然倒吸了一口涼氣。
「等會兒!一航,你把頁面往上拉一點。」郭長征指著屏幕。
楚一航照做,頁面停在了一個名為「自動微分」的章節。
「臥槽,這也可以?」楚一航脫口而出,聲音都提高了八度。
郭長征死死盯著那幾行示例代碼,臉上的表情極為震撼。
「一航,這文檔上寫的,是真的嗎?」郭長征指著屏幕的手指甚至有點發顫。
「它說,我們只需要定義好前向傳播的計算過程,框架就能自動幫我們求導?」
楚一航也是一臉沒見過世面的樣子,逐字逐句地又看了一遍。
「郭老師,文檔上確實是這麼寫的。它甚至包裝好了一個叫梯度下降優化器的東西。」
郭長征猛地拍了一下大腿,發出一聲脆響。
要知道,在2009年這個時間節點,要在底層從零開始手寫一個神經網絡,簡直是所有科研人員的噩夢。
噩夢的根源,不在於怎麼把數據乘起來,而在於怎麼把誤差傳回去。
這就是反向傳播算法。
科研人員需要拿著紙和筆,運用高等數學裡的鏈式法則,對著錯綜複雜的網絡層,一層一層地去推導偏導數公式。
稍微多加一層網絡,或者換一個非線性激活函數,幾十頁的數學草稿紙就白寫了,必須全部推倒重來。
哪怕公式推導對了,把它轉化成C語言或者C++代碼時,稍有一個變量寫錯,模型就會原地爆炸,梯度直接消失或者數值溢出。
「這等於是把最折磨人的數學推導過程,全給省略了?」郭長征覺得嗓子有點干。
「只要告訴它怎麼算出來的結果,它自己就能算出怎麼調整參數?」
楚一航看著文檔上的示例,只要調用一個簡單的函數,所有的梯度就全部計算完畢。
「郭老師,如果這文檔沒吹牛逼,那我們以後搭模型,就跟搭樂高積木一樣簡單了。」
兩人對視了一眼,興奮之情溢於言表,在客廳里高興得連連搓手。
這種把複雜的數學過程完全黑盒化、工程化的設計,對於苦逼的算法研究員來說,簡直就是久旱逢甘霖。
他們覺得之前只知道盛夏科技批了算力,居然沒靜下心來仔細研究這個框架,簡直是暴殄天物。
「繼續往下看,看看還有什麼驚喜。」郭長征現在完全沒有了困意。
楚一航滑動滑鼠,他們來到了另一個模塊區。
「郭老師,你看這個,這裡封裝了好多高級模塊。」
楚一航點開了一個名為卷積的目錄。
裡面列著各種奇怪的函數名。
兩人仔細看著文檔的解釋。
裡面有一個叫卷積神經網絡的封裝層。
兩人平時研究的都是些傳統的機器學習算法,對這種結構並不算特別清楚。
直到看到文檔里清清楚楚地寫著:該模塊通過卷積核提取局部特徵,極為適用於圖像識別與計算機視覺領域。
「圖像識別?」郭長征敏銳地抓住了這個詞。
「我們下午吃飯的時候,討論的李飛飛教授那個ImageNet數據集,不就是圖像分類嗎?」
楚一航一拍桌子:「絕了!連這種專門針對圖像的模塊都提前封裝好了。」
「這簡直就是給咱們量身定製的武器庫啊。」
兩人對著這些功能模塊,越討論越興奮。
「一航,別光看著眼饞了,紙上得來終覺淺。」郭長征提議。
「咱們現在就動手,按這個文檔,寫一個簡單的幾層網絡試試水。」
「好嘞。」楚一航立刻切換到代碼編輯器。
按照平時用CUDA編寫底層算力代碼的習慣,楚一航習慣性地準備先寫一堆內存分配的語句。
在以往,用英偉達的CUDA寫代碼,繁瑣。
程式設計師必須手動在主機的內存里開闢空間,再在顯卡的顯存里開闢空間。
然後要把數據從主機複製到顯卡,接著手動設置線程塊和網格的大小。
稍微設置不合理,顯卡就直接罷工不干。
算完之後,還得再把數據從顯卡慢吞吞地拷回主機。
但當楚一航按照TensorFlow的文檔指引敲擊鍵盤時,他發現那些全都不需要了。
他只需要定義好數據格式,聲明好網絡層數,框架的底層執行引擎會自動接管所有的硬體資源調度。
不到二十行代碼。
簡潔,優雅。
「這就寫完了?」楚一航自己都不敢相信。
「這幾十行代碼,放以前用C語言加CUDA手搓,至少得寫大半天,還得調試一整天。」
郭長征湊在屏幕前,反反覆覆檢查了三遍代碼邏輯。
「沒有手動分配顯存,沒有顯式的數據拷貝,完全是業務邏輯的代碼。」
郭長征感嘆道:「這框架的抽象能力太強了,所有的髒活累活都在底層被TensorFlow幹完了。」
兩人開始嘗試運行這段代碼。
雖然只是輸入了一些隨機生成的測試數據,但終端里立刻列印出了每一層數據維度的變化,以及最終輸出的結果。
完全沒有報錯。
順滑。
「這開發效率,太可怕了。」楚一航看著順利跑通的終端界面。
「有了這個,咱們今晚完全可以把吃飯時構思的那個真正的網絡架構給搭出來。」郭長征提議。
「干!」楚一航幹勁十足。
兩人徹底進入了忘我的狀態。
楚一航負責敲代碼,郭長征負責在旁邊提供理論指導和架構設計。
「這裡加一層池化層,文檔上說這能降低數據維度,防止過擬合。」郭長征指揮著。
「好,步長設為2,卷積核大小設為3。」楚一航手指翻飛。
「這一層的激活函數換一下,別用原來的了,文檔里推薦了一個叫ReLU的函數。」
「ReLU?我找找……有了,一行代碼搞定。」
在搭建的過程中,他們也不是一帆風順。
時不時會遇到一些報錯。
比如「張量維度不匹配」這種經典的錯誤。
但得益於框架清晰的報錯提示,他們總能迅速定位到是哪一層的矩陣乘法出了問題。
兩個人為了算清楚上一層的輸出怎麼和下一層的輸入對齊,甚至找了張A4紙在桌子上畫起了矩陣圖。
不知不覺中,時間過得飛快。
楚一航敲擊回車,最後一行代碼編寫完畢。
他們把整個神經網絡的模型類封裝好了,並且配置好了損失函數和優化器。
楚一航伸了個大大的懶腰,只覺得脖子和後背一陣酸痛。
郭長征也揉了揉酸澀的眼睛。
窗外傳來了鳥叫聲。
楚一航聽到後愣了一下,瞥了一眼屏幕右下角的時間,整個人愣住了。
「郭老師……五點半了。」
因為有著非常明確的目標——搭建一個用於圖像分類的神經網絡,他們直接跳過了閒篇,直奔核心API。
滑鼠滾輪不斷向下滑動,安靜的客廳里只有「咔噠咔噠」的聲音。
幾分鐘後,郭長征突然倒吸了一口涼氣。
「等會兒!一航,你把頁面往上拉一點。」郭長征指著屏幕。
楚一航照做,頁面停在了一個名為「自動微分」的章節。
「臥槽,這也可以?」楚一航脫口而出,聲音都提高了八度。
郭長征死死盯著那幾行示例代碼,臉上的表情極為震撼。
「一航,這文檔上寫的,是真的嗎?」郭長征指著屏幕的手指甚至有點發顫。
「它說,我們只需要定義好前向傳播的計算過程,框架就能自動幫我們求導?」
楚一航也是一臉沒見過世面的樣子,逐字逐句地又看了一遍。
「郭老師,文檔上確實是這麼寫的。它甚至包裝好了一個叫梯度下降優化器的東西。」
郭長征猛地拍了一下大腿,發出一聲脆響。
要知道,在2009年這個時間節點,要在底層從零開始手寫一個神經網絡,簡直是所有科研人員的噩夢。
噩夢的根源,不在於怎麼把數據乘起來,而在於怎麼把誤差傳回去。
這就是反向傳播算法。
科研人員需要拿著紙和筆,運用高等數學裡的鏈式法則,對著錯綜複雜的網絡層,一層一層地去推導偏導數公式。
稍微多加一層網絡,或者換一個非線性激活函數,幾十頁的數學草稿紙就白寫了,必須全部推倒重來。
哪怕公式推導對了,把它轉化成C語言或者C++代碼時,稍有一個變量寫錯,模型就會原地爆炸,梯度直接消失或者數值溢出。
「這等於是把最折磨人的數學推導過程,全給省略了?」郭長征覺得嗓子有點干。
「只要告訴它怎麼算出來的結果,它自己就能算出怎麼調整參數?」
楚一航看著文檔上的示例,只要調用一個簡單的函數,所有的梯度就全部計算完畢。
「郭老師,如果這文檔沒吹牛逼,那我們以後搭模型,就跟搭樂高積木一樣簡單了。」
兩人對視了一眼,興奮之情溢於言表,在客廳里高興得連連搓手。
這種把複雜的數學過程完全黑盒化、工程化的設計,對於苦逼的算法研究員來說,簡直就是久旱逢甘霖。
他們覺得之前只知道盛夏科技批了算力,居然沒靜下心來仔細研究這個框架,簡直是暴殄天物。
「繼續往下看,看看還有什麼驚喜。」郭長征現在完全沒有了困意。
楚一航滑動滑鼠,他們來到了另一個模塊區。
「郭老師,你看這個,這裡封裝了好多高級模塊。」
楚一航點開了一個名為卷積的目錄。
裡面列著各種奇怪的函數名。
兩人仔細看著文檔的解釋。
裡面有一個叫卷積神經網絡的封裝層。
兩人平時研究的都是些傳統的機器學習算法,對這種結構並不算特別清楚。
直到看到文檔里清清楚楚地寫著:該模塊通過卷積核提取局部特徵,極為適用於圖像識別與計算機視覺領域。
「圖像識別?」郭長征敏銳地抓住了這個詞。
「我們下午吃飯的時候,討論的李飛飛教授那個ImageNet數據集,不就是圖像分類嗎?」
楚一航一拍桌子:「絕了!連這種專門針對圖像的模塊都提前封裝好了。」
「這簡直就是給咱們量身定製的武器庫啊。」
兩人對著這些功能模塊,越討論越興奮。
「一航,別光看著眼饞了,紙上得來終覺淺。」郭長征提議。
「咱們現在就動手,按這個文檔,寫一個簡單的幾層網絡試試水。」
「好嘞。」楚一航立刻切換到代碼編輯器。
按照平時用CUDA編寫底層算力代碼的習慣,楚一航習慣性地準備先寫一堆內存分配的語句。
在以往,用英偉達的CUDA寫代碼,繁瑣。
程式設計師必須手動在主機的內存里開闢空間,再在顯卡的顯存里開闢空間。
然後要把數據從主機複製到顯卡,接著手動設置線程塊和網格的大小。
稍微設置不合理,顯卡就直接罷工不干。
算完之後,還得再把數據從顯卡慢吞吞地拷回主機。
但當楚一航按照TensorFlow的文檔指引敲擊鍵盤時,他發現那些全都不需要了。
他只需要定義好數據格式,聲明好網絡層數,框架的底層執行引擎會自動接管所有的硬體資源調度。
不到二十行代碼。
簡潔,優雅。
「這就寫完了?」楚一航自己都不敢相信。
「這幾十行代碼,放以前用C語言加CUDA手搓,至少得寫大半天,還得調試一整天。」
郭長征湊在屏幕前,反反覆覆檢查了三遍代碼邏輯。
「沒有手動分配顯存,沒有顯式的數據拷貝,完全是業務邏輯的代碼。」
郭長征感嘆道:「這框架的抽象能力太強了,所有的髒活累活都在底層被TensorFlow幹完了。」
兩人開始嘗試運行這段代碼。
雖然只是輸入了一些隨機生成的測試數據,但終端里立刻列印出了每一層數據維度的變化,以及最終輸出的結果。
完全沒有報錯。
順滑。
「這開發效率,太可怕了。」楚一航看著順利跑通的終端界面。
「有了這個,咱們今晚完全可以把吃飯時構思的那個真正的網絡架構給搭出來。」郭長征提議。
「干!」楚一航幹勁十足。
兩人徹底進入了忘我的狀態。
楚一航負責敲代碼,郭長征負責在旁邊提供理論指導和架構設計。
「這裡加一層池化層,文檔上說這能降低數據維度,防止過擬合。」郭長征指揮著。
「好,步長設為2,卷積核大小設為3。」楚一航手指翻飛。
「這一層的激活函數換一下,別用原來的了,文檔里推薦了一個叫ReLU的函數。」
「ReLU?我找找……有了,一行代碼搞定。」
在搭建的過程中,他們也不是一帆風順。
時不時會遇到一些報錯。
比如「張量維度不匹配」這種經典的錯誤。
但得益於框架清晰的報錯提示,他們總能迅速定位到是哪一層的矩陣乘法出了問題。
兩個人為了算清楚上一層的輸出怎麼和下一層的輸入對齊,甚至找了張A4紙在桌子上畫起了矩陣圖。
不知不覺中,時間過得飛快。
楚一航敲擊回車,最後一行代碼編寫完畢。
他們把整個神經網絡的模型類封裝好了,並且配置好了損失函數和優化器。
楚一航伸了個大大的懶腰,只覺得脖子和後背一陣酸痛。
郭長征也揉了揉酸澀的眼睛。
窗外傳來了鳥叫聲。
楚一航聽到後愣了一下,瞥了一眼屏幕右下角的時間,整個人愣住了。
「郭老師……五點半了。」