機器學習入門 一、理解機器學習+簡單感知機(JAVA實現)


首先先來講講閑話

  如果讓你現在去搞機器學習,你會去嗎?不會的話是因為你對這方面不感興趣,還是因為你覺得這東西太難了,自己肯定學不來?如果你覺的太難了,很好,相信看完這篇文章,你就會有膽量踏入機器學習這一領域。

  機器學習(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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM