感謝https://blog.csdn.net/sigai_csdn/article/details/81012167,聽君一席話,勝讀十年書。python
和一個有着多年工做經驗的同行朋友交流,他說:一個優秀的算法人員培養成本其實比開發人員要高的多,週期也更長,絕對不是隨便一我的均可以跨行的。linux
怎樣成爲一名優秀的算法工程師?面對市場對人才的大量需求與供給的嚴重不足,以及高薪水的誘惑,愈來愈多的人開始學習這個方向的技術,或者打算向人工智能轉型。市面上各類魚龍混雜的培訓班以及誤導人的文章會把不少初學者帶入歧途,浮躁的跟風將會讓你最後收穫甚微,根本達不到企業的用人要求。原做者寫這篇文章正是爲了更好的幫助你們學習和成長,少走彎路。這裏本身重寫當時學習,學習如何去學習也是相當重要的,有些時候甚至超越學習自己!c++
首先來看一個高度相關的問題:一個優秀的算法工程師必須具有哪些素質?做者給出的答案是這樣的:git
數學知識
編程能力
機器學習與深度學習的知識
應用方向的知識
對本身所作的問題的思考和經驗
除去教育背景,邏輯思惟,學習能力,溝通能力等其餘方面的因素,大多數公司在考察算法工程師的技術水平時都會考慮上面這幾個因素。接下來按照這幾個方面進行展開,詳細的說明如何學習這些方面的知識以及積累經驗。github
1、數學知識面試
本人主要針對人工智能、機器學習,深度學習方面。算法
人工智能尤爲是機器學習屬於數學知識密集的方向。在各類書籍,論文,算法中都充斥着大量的數學公式,這讓不少打算入門的人或者開始學習的人感到明顯的壓力。首先咱們考慮一個最核心的問題:機器學習和深度學習究竟須要哪些數學知識?編程
算法或理論 | 用到的數學知識點 |
貝葉斯分類器 | 隨機變量,貝葉斯公式,隨機變量獨立性,正態分佈,最大似然估計 |
決策樹 | 機率,熵,Gini係數 |
KNN算法 | 距離函數 |
PCA算法 | 協方差矩陣,散佈矩陣,拉格朗日乘數法,特徵值與特徵向量 |
流形學習 | 流形,最優化,測地線,測地距離,圖,特徵值與特徵向量 |
線性判別分析 | 散度矩陣,逆矩陣,拉格朗日乘數法,特徵值與特徵向量 |
支持向量機 | 點到平面的距離,Slater條件,強對偶,拉格朗日對偶,KKT條件,凸優化,核函數,Mercer條件 |
logistic迴歸 | 機率,隨機變量,最大似然估計,梯度降低法,凸優化,牛頓法 |
隨機森林 | 抽樣,方差 |
AdaBoost算法 | 機率,隨機變量,極值定理,數學指望,牛頓法 |
隱馬爾可夫模型 | 機率,離散型隨機變量,條件機率,隨機變量獨立性,拉格朗日乘數法,最大似然估計 |
條件隨機場 | 條件機率,數學指望,最大似然估計 |
高斯混合模型 | 正態分佈,最大似然估計,Jensen不等式 |
人工神經網絡 | 梯度降低法,鏈式法則 |
卷積神經網絡 | 梯度降低法,鏈式法則 |
循環神經網絡 | 梯度降低法,鏈式法則 |
生成對抗網絡 | 梯度降低法,鏈式法則,極值定理,Kullback-Leibler散度,Jensen-Shannon散度,測地距離,條件分佈,互信息 |
K-means算法 | 距離函數 |
強化學習 | 數學指望,貝爾曼方程 |
貝葉斯網絡 | 條件機率,貝葉斯公式,圖 |
VC維 | Hoeffding不等式 |
理解絕大多數算法和理論,有微積分/高等數學,線性代數,機率論,最優化方法的知識就夠了。數組
除流形學習須要簡單的微分幾何概念以外,深層次的數學知識如實變函數,泛函分析等主要用在一些基礎理論結果的證實上,即便不能看懂證實過程,也不影響咱們使用具體的機器學習算法。服務器
機率圖模型、流形學習中基於圖的模型會用到圖論的一些基本知識,若是學習過離散數學或者數據結構,這些概念很容易理解。除此以外,某些算法會用到離散數學中的樹的概念,但很容易理解。
在機器學習中主要用到了微分部分,積分用的很是少。具體的,用到了下面的概念:
導數和偏導數的定義與計算方法,與函數性質的關係
梯度向量的定義
極值定理,可導函數在極值點處導數或梯度必須爲0
雅克比矩陣,這是向量到向量映射函數的偏導數構成的矩陣,在求導推導中會用到
Hessian矩陣,這是2階導數對多元函數的推廣,與函數的極值有密切的聯繫
凸函數的定義與判斷方法泰勒展開公式
拉格朗日乘數法,用於求解帶等式約束的極值問題
其中最核心的是多元函數的泰勒展開公式,根據它咱們能夠推導出梯度降低法,牛頓法,擬牛頓法等一系列最優化方法。若是你想要深刻的學習微積分,能夠閱讀數學系的教程,稱爲數學分析:
與工科的高等數學偏重計算不一樣,它裏面有大量的理論證實,對於鍛鍊數學思惟很是有幫助。北大張築生先生所著的數學分析可謂是國內這方面教材的精品。
下面來看線性代數,一樣是同濟版的教材:
若是想更全面系統的學習線性代數,能夠看這本書:
相比之下,線性代數用的更多。具體用到的知識點有:
向量和它的各類運算,包括加法,減法,數乘,轉置,內積
向量和矩陣的範數,L1範數和L2範數
矩陣和它的各類運算,包括加法,減法,乘法,數乘
逆矩陣的定義與性質
行列式的定義與計算方法
二次型的定義
矩陣的正定性
特徵值與特徵向量
奇異值分解
線性方程組的數值解
機器學習算法處理的數據通常都是向量、矩陣或者張量。經典的機器學習算法輸入的數據都是特徵向量,深度學習算法在處理圖像時輸入的2維的矩陣或者3維的張量。掌握這些概念是你理解機器學習和深度學習算法的基礎。
機率論國內理工科專業使用最多的是浙大版的教材:
若是把機器學習所處理的樣本數據看做隨機變量/向量,就能夠用機率論的方法對問題進行建模,這表明了機器學習中很大一類方法。在機器學習裏用到的機率論知識點有:
隨機事件的概念,機率的定義與計算方法
隨機變量與機率分佈,尤爲是連續型隨機變量的機率密度函數和分佈函數
條件機率與貝葉斯公式
經常使用的機率分佈,包括正態分佈,伯努利二項分佈,均勻分佈
隨機變量的均值與方差,協方差
隨機變量的獨立性
最大似然估計
這些知識不超出普通理工科機率論教材的範圍。
最後來講最優化,幾乎全部機器學習算法歸根到底都是在求解最優化問題。求解最優化問題的指導思想是在極值點處求出函數的導數/梯度必須爲0。所以你必須理解梯度降低法,牛頓法這兩種經常使用的算法,它們的迭代公式均可以從泰勒展開公式而獲得。
凸優化是機器學習中常常會說起的一個概念,這是一類特殊的優化問題,它的優化變量的可行域是凸集,目標函數是凸函數。凸優化最好的性質是它的全部局部最優解就是全局最優解,所以求解時不會陷入局部最優解。若是一個問題被證實爲是凸優化問題,基本上已經宣告此問題獲得瞭解決。在機器學習中,線性迴歸、嶺迴歸、支持向量機、logistic迴歸等不少算法求解的都是凸優化問題。
拉格朗日對偶爲帶等式和不等式約束條件的優化問題構造拉格朗日函數,將其變爲原問題,這兩個問題是等價的。經過這一步變換,將帶約束條件的問題轉換成不帶約束條件的問題。經過變換原始優化變量和拉格朗日乘子的優化次序,進一步將原問題轉換爲對偶問題,若是知足某種條件,原問題和對偶問題是等價的。這種方法的意義在於能夠將一個不易於求解的問題轉換成更容易求解的問題。在支持向量機中有拉格朗日對偶的應用。
KKT條件是拉格朗日乘數法對帶不等式約束問題的推廣,它給出了帶等式和不等式約束的優化問題在極值點處所必須知足的條件。在支持向量機中也有它的應用。
若是你沒有學過最優化方法這門課也不用擔憂,這些方法根據微積分和線性代數的基礎知識能夠很容易推導出來。若是須要系統的學習這方面的知識,能夠閱讀《凸優化》,《非線性規劃》兩本經典教材。
2、編程能力
編程能力是學好機器學習和深度學習的又一大基礎。對於計算機類專業的學生,因爲本科已經學了c語言,c++,數據結構與算法,所以這方面通常不存在問題。對於非計算機專業的人來講,要真正學好機器學習和深度學習,這些知識是繞不開的。
雖然如今你們熱衷於學習python,但要做爲一名真正的算法工程師,仍是應該好好學習一下c++,至少,機器學習和深度學習的不少底層開源庫都是用它寫的;不少公司線上的產品,不管是運行在服務器端,仍是嵌入式端,都是用c++寫的。此外,若是你是應屆生,在校園招聘時很多公司都會面試你c++的知識。
C++最經典的教材無疑是c++ primer:
對作算法的人來講,這本書其實不用所有看,把經常使用的點學完就夠了。對於進階,Effective c++是很好的選擇,很多公司的面試題就直接出自這本書的知識點:
接下來講python,相比c++來講,學習的門檻要低不少,找一本通俗易懂的入門教程學習一遍便可。
數據結構和算法是編寫不少程序的基礎,對於機器學習和深度學習程序也不例外。不少算法的實現都依賴於數組,鏈表,數,排序,查找之類的數據結構和基礎算法。若是有時間和精力,把算法導論啃一遍,你會有不同的感覺。
對於應屆生來講,學完它對於你經過大互聯網和人工智能公司校園招聘的技術面試也很是有用。
上面說的只是編程語言的程序設計的理論知識,咱們還要考慮實際動手能力。對於開發環境如gcc/g++,visual studio之類的工具,以及gdb之類的調試工具須要作到熟練使用。若是是在linux上開發,對linux的經常使用命令也要熟記於心。這方面的知識看各類具體的知識點和教程便可。另外,對於編程的一些常識,如進程,線程,虛擬內存,文件系統等,你最好也要進行了解。
3、機器學習與深度學習
在說完了數學和編程基礎以後,下面我來看核心的內容,機器學習和深度學習知識。機器學習是現階段解決不少人工智能問題的核心方法,尤爲是深度學習,所以它們是算法工程師的核心知識。在這裏有一個問題:是否須要先學機器學習,仍是直接學深度學習?若是是一個專業的算法工程師,個人建議是先學機器學習。至少,你要知道機器學習中的基本概念,過擬合,生成模型,ROC曲線等,上來就看深度學習,如沒有背景知識你將不知所云。另外,神經網絡只是機器學習中的一類方法,對於不少問題,其餘機器學習算法如logistic迴歸,隨機森林,GBDT,決策樹等還在被大規模使用,所以你不要把本身侷限在神經網絡的小圈子裏。
首先來看機器學習,這方面的教材不少,周志華老師的機器學習,李航老師的統計學習方法是國內的經典。這裏咱們介紹國外的經典教材,首先是PRML:
此書深厚,內容全面,涵蓋了有監督學習,無監督學習的主要方法,理論推導和證實詳細深刻,是機器學習的經典。此外還有模式分類這本書,在這裏不詳細介紹。
深度學習目前最權威的教程是下面這本書:
它涵蓋了深度學習的方方面面,從理論到工程,但美中不足的是對應於介紹的相對較少。
另:強化學習是機器學習很獨特的一個分支,大多數人對它不太瞭解,這方面的教程很是少。
在這裏須要強調的是,你的知識要系統化,有總體感。不少同窗都感受到本身學的機器學習太零散,缺少總體感。這須要你多思考算法之間的關係,演化歷史之類的問題,這樣你就作到胸中有圖-機器學習算法地圖。
4、開源庫
上面介紹了機器學習和深度學習的理論教材,下面來講實踐問題。咱們無需重複造車輪子,熟練的使用主流的開源庫是須要掌握的一項技能。對於經典的機器學習,經常使用的庫的有:
libsvm
liblinear
XGBoost
OpenCV
HTK
Weka
在這裏咱們不一一列舉。藉助於這些庫,咱們能夠方便的完成本身的實驗,或是研發本身的產品。對於深度學習,目前經常使用的有:
Caffe
TensorFlow
MXNet
除此以外,還有其餘的。對於你要用到的開源庫,必定要理解它的原理,以及使用中的一些細節問題。例如不少算法要求輸入的數據先作歸一化,不然效果會很是差,並且面臨浮點數溢出的問題,這些實際經驗須要你在使用中摸索。若是有精力把這些庫的核心代碼分析一遍,你對實現機器學習算法將會更有底氣。以深度學習爲例,最核心的代碼無非是實現:
各類層,包括它們的正向傳播和反向傳播
激活函數的實現
損失函數的實現
輸入數據的處理
求解器,實現各類梯度降低法
這些代碼的量並不大,沉下心來,我相信一週以內確定能分析完。看完以後你會有一種豁然開朗的感受。
5、應用方向的知識
接下來是各個方向的知識,與機器學習有關的應用方向當前主要有:
機器視覺
語音識別
天然語言處理
數據挖掘
知識圖譜
推薦系統
除此以外,還有其餘一些特定小方向,在這裏不一一列舉。這些具體的應用方向通常都有本身的教材,若是你之後要從事此方向的研究,系統的學習一遍是必須的。
6、實踐經驗與思考
在說完理論與實踐知識以後,最後咱們來講經驗與思考。在你肯定要作某一個方向以後,對這個方向的方法要有一個全面系統的認識,不少方法是一脈相承的,若是隻追求時髦看最新的算法,你很難作出學術上的創新,以及工程上的優化。對於本問題全部的經典論文,都應該化時間細度,清楚的理解它們解決了什麼問題,是怎麼解決的,還有哪些問題沒有解決。例如:
機器視覺目標檢測中的遮擋問題
推薦系統中的冷啓動問題
天然語言處理中文分詞中的歧義切分問題
只有通過大量的編程和實驗訓練,以及持續的思考,你才能算得上對這個方向深入理解,以致於有本身的理解。不少同窗對本身實現的算法沒有底氣,解決這個問題最快的途徑就是看論文算法的開源代碼,在github上有豐富的資源,選擇一些合適的,研究一下別人是怎麼實現的,你就能明白怎麼實現本身的網絡結構和損失函數,照葫蘆畫瓢便可。
計算機以及人工智能是一個偏實踐的學科,它的方法和理論既須要咱們有紮實的理論功底,又須要有豐富的實踐能力與經驗。這兩個方面構成了算法工程師最主要的素質。科學的學習路徑可以讓你取得好的學習效果,同時也縮短學習時間。錯誤和浮躁的作法則會讓你最後事倍功半。這是做者對想進入這個領域,或者剛進入這個領域的每一個人要說的!
小時候,小學有一個班會記錄本,記得當時爸爸給我寫的一句話是:書山有路勤爲徑,學海無涯苦作舟。
後來我讀了大學,讀了碩士研究生,爸爸又對我說:攻城不怕堅,攻書莫畏難,科學有險阻,苦戰能過關。
這些話我始終記得。但願你更加是一個聰明而勤奮的人,堅決信念,而後聰明而踏實地勤奮着,就應該是這麼清晰、簡單、明瞭!
願你堅毅果敢,願你有一個美好前程!
再次附上原文:https://blog.csdn.net/sigai_csdn/article/details/81012167 ,有興趣可關注做者。
感謝!