首先先來講講閑話
如果讓你現在去搞機器學習,你會去嗎?不會的話是因為你對這方面不感興趣,還是因為你覺得這東西太難了,自己肯定學不來?如果你覺的太難了,很好,相信看完這篇文章,你就會有膽量踏入機器學習這一領域。
機器學習(Machine-Learning),一個在才學一年編程的人看來十分高大尚的東西,不知不覺就接觸了它。暑假的時候表哥給我布置了任務,在github上有一篇DeepLearningFlappyBird,他當時要我一天之內先讓這段代碼跑起來,然后第二天再把這段代碼翻譯成C++的.......wtf???我當時一臉懵逼,一個才學編程一年不到的,C和C++的水平也就差不多是大學課堂教完后的那種,跑起來可能還算容易,但要翻譯?!! 饒了我吧 orz。。。當時配了一天的環境,到那天晚上快12點了,終於跑起來了。然后到了第二天,我先去查了查tensorflow,opencv3在VS上使用,發現根本搞不定。。。我電腦上裝的是VS2013,里面只有32位的,emmmm。。得下個VS2017,看了看電腦空間,不夠了!好的,放棄,以后有空閑得慌了再來搞吧。。。。
前幾天開學了,還沒什么事干,突然就想到機器學習了(其實dalao提到了感知機這東西),就試着去做了做,也就當個入門吧。
再來聊聊機器學習
機器學習說白了跟人類學習是一樣的,只不過機器可以無止境的學習,並且,機器學習時完全不需要懂什么原理,只要知道怎么去實現就行。就如Alpha Go,你們覺得它懂得棋理嗎?我覺得肯定不懂,但通過對無數的棋譜的學習,讓人覺得它肯定掌握了圍棋的真諦。
機器學習的標准范式表達
對於一個Task及其Performance的度量方法,給出特定的Algorithm,能夠通過利用Experience Data不斷提高在該Task上的
Performance的方法,就稱為機器學習。
其實這個定義就是“學習”的全部含義,這個事情按照機器的思路來做,就是機器學習
說白了,只要算法合理,每次學習都能有提高,機器有足夠的運算能力,就能將機器的能力達到極致從而超越人類。機器學習的本質就是建立("數據"——"認知")關系庫。
下面就來講講感知機
先扯扯定義:感知機(perceptron)是二分類的線性分類模型,輸入為實例的特征向量,輸出為實例的類別(取+1和-1)。感知機對應於輸入空間中將實例划分為兩類的分離超平面。感知機旨在求出該超平面,為求得超平面導入了基於誤分類的損失函數,利用梯度下降法 對損失函數進行最優化(最優化)。感知機的學習算法具有簡單而易於實現的優點,分為原始形式和對偶形式。感知機預測是用學習得到的感知機模型對新的實例進行預測的,因此屬於判別模型。感知機由Rosenblatt於1957年提出的,是神經網絡和支持向量機的基礎。
拿二維平面舉例,
看這張圖,很明顯,直線沒有將紅藍點完全分開在兩個區域,我們可以將其稱為錯誤的直線,感知機要做的,就是根據各點坐標,將錯誤的直線糾正為正確的,這樣得到的直線就是訓練的結果。
說了這么多,要怎么實現呢? 看下面的流程圖
/* * 判斷所有點的位置關系,進行分類 */ public boolean classify() { boolean flag = false; while (!flag) { for (int i = 0; i < arrayList.size(); i++) { if (Anwser(arrayList.get(i)) <= 0) { Update(arrayList.get(i)); break; } if (i + 1 == arrayList.size()) { flag = true; } } } return true; }
/* * 點乘返回sum */ private double Dot(double[] w, double[] x) { double sum = 0; for (int i = 0; i < x.length; i++) { sum += w[i] * x[i]; } return sum; } /* * 返回函數計算的值 */ private double Anwser(Point point) { System.out.println(Arrays.toString(w)); System.out.println(b); return point.y * (Dot(w, point.x) + b); }
如果還有疑問,那可能就是w與b怎么修改了,我們會定義一個變量η(0≤η≤1)作為步長,在統計學是中成為學習速率。步長越大,梯度下降的速度越快,更能接近極小點。如果步長過大,有可能導致跨過極小點,導致函數發散;如果步長過小,有可能會耗很長時間才能達到極小點。默認為1
對於wi wi+=η*y*xi
對於b b+=η*y
public void Update(Point point) { for (int i = 0; i < w.length; i++) { w[i] += eta * point.y * point.x[i]; } b += eta * point.y; return; }
這樣,我們就可以完成成w、b的更新了。
將上面的步驟組合起來,就可以實現感知機了。
談談自己的想法
寫了這個感知機后,發現機器學習並不是想象當中那么難,其實只要知道怎么去算就可以了(目前比較淺顯的理解,可能我還沒接觸到難的地方),而且Python中,有關機器學習的庫可以說是很完善了,如果熟悉了這些庫的用法,即使不懂算法,也時能用這些庫來做開發的,要知道算法崗和開發崗還是不一樣的
這是我選取的測試用例及結果
1 Point p1 = new Point(new double[] { 0, 0, 0, 1 }, -1); 2 Point p2 = new Point(new double[] { 1, 0, 0, 0 }, 1); 3 Point p3 = new Point(new double[] { 2, 1, 0, 0 }, 1); 4 Point p4 = new Point(new double[] { 2, 1, 0, 1 }, -1);
[0.0, 0.0, 0.0, 0.0] 0.0 [0.0, 0.0, 0.0, -1.0] -1.0 [0.0, 0.0, 0.0, -1.0] -1.0 [1.0, 0.0, 0.0, -1.0] 0.0 [1.0, 0.0, 0.0, -1.0] 0.0 [1.0, 0.0, 0.0, -1.0] 0.0 [1.0, 0.0, 0.0, -1.0] 0.0 [-1.0, -1.0, 0.0, -2.0] -1.0 [-1.0, -1.0, 0.0, -2.0] -1.0 [0.0, -1.0, 0.0, -2.0] 0.0 [0.0, -1.0, 0.0, -2.0] 0.0 [1.0, -1.0, 0.0, -2.0] 1.0 [1.0, -1.0, 0.0, -2.0] 1.0 [1.0, -1.0, 0.0, -2.0] 1.0 [1.0, -1.0, 0.0, -2.0] 1.0 [-1.0, -2.0, 0.0, -3.0] 0.0 [-1.0, -2.0, 0.0, -3.0] 0.0 [0.0, -2.0, 0.0, -3.0] 1.0 [0.0, -2.0, 0.0, -3.0] 1.0 [0.0, -2.0, 0.0, -3.0] 1.0 [2.0, -1.0, 0.0, -3.0] 2.0 [2.0, -1.0, 0.0, -3.0] 2.0 [2.0, -1.0, 0.0, -3.0] 2.0 [2.0, -1.0, 0.0, -3.0] 2.0 [0.0, -2.0, 0.0, -4.0] 1.0 [0.0, -2.0, 0.0, -4.0] 1.0 [0.0, -2.0, 0.0, -4.0] 1.0 [2.0, -1.0, 0.0, -4.0] 2.0 [2.0, -1.0, 0.0, -4.0] 2.0 [2.0, -1.0, 0.0, -4.0] 2.0 [2.0, -1.0, 0.0, -4.0] 2.0 [0.0, -2.0, 0.0, -5.0] 1.0 [0.0, -2.0, 0.0, -5.0] 1.0 [0.0, -2.0, 0.0, -5.0] 1.0 [2.0, -1.0, 0.0, -5.0] 2.0 [2.0, -1.0, 0.0, -5.0] 2.0 [2.0, -1.0, 0.0, -5.0] 2.0 [2.0, -1.0, 0.0, -5.0] 2.0 [0.0, -2.0, 0.0, -6.0] 1.0 [0.0, -2.0, 0.0, -6.0] 1.0 [0.0, -2.0, 0.0, -6.0] 1.0 [2.0, -1.0, 0.0, -6.0] 2.0 [2.0, -1.0, 0.0, -6.0] 2.0 [2.0, -1.0, 0.0, -6.0] 2.0 [2.0, -1.0, 0.0, -6.0] 2.0