用Java機(jī)器學(xué)習(xí):試著實(shí)現(xiàn)單層感知器

http://krr.blog.shinobi.jp/javafx_praxis/java%E3%81%A7%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%EF%BC%9A%E5%8D%98%E7%B4%94%E3%83%91%E3%83%BC%E3%82%BB%E3%83%97%E3%83%88%E3%83%AD%E3%83%B3%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B

近年來(lái)邻薯,人工智能和機(jī)械學(xué)習(xí)的話題熱烈昧旨,特別是Deep learning這種機(jī)器學(xué)習(xí)的領(lǐng)域的關(guān)注度。2012年圖像識(shí)別精度的比賽(ImageNet Large Scale Visual Recognition Challenge)Deep learnig利用隊(duì)2位以下拉開(kāi)很大的冠軍绘闷。雖然不是特別新的概念搅窿,但由于這一功績(jī)而被重新評(píng)價(jià)罚屋。與以后的利用擴(kuò)大相關(guān)聯(lián)(*1)鸡捐。另外璧瞬,在2015年户辫,很多媒體報(bào)道,圍棋用人工智能戰(zhàn)勝了世界頂級(jí)棋士李世石嗤锉。

*2)渔欢。

作為程序員團(tuán)體內(nèi)部很在意的地方,所以查了一下瘟忱,所謂DeepLearning奥额,據(jù)說(shuō)是“四層以上的新網(wǎng)絡(luò)的學(xué)習(xí)”》糜眨總之垫挨,這次的基礎(chǔ)知識(shí)和神經(jīng)網(wǎng)絡(luò)的概念進(jìn)行了調(diào)查,實(shí)現(xiàn)了這一種的單層感知器触菜,讓人聯(lián)想到機(jī)械學(xué)習(xí)的實(shí)現(xiàn)九榔。順便,本報(bào)道是從1開(kāi)始實(shí)施涡相,想利用庫(kù)的看這篇『[Javaで機(jī)械學(xué)習(xí) - Deeplearnig4j入門(mén)](http://krr.blog.shinobi.jp/site%20map#Javaで機(jī)械學(xué)習(xí) - Deeplearning4j入門(mén))』哲泊。

神經(jīng)網(wǎng)絡(luò)是?
神經(jīng)網(wǎng)絡(luò)和人類的腦功能參考的數(shù)學(xué)模型的事催蝗,神經(jīng)元稱為計(jì)算式連接到網(wǎng)絡(luò)切威。計(jì)算式連接”,是有計(jì)算式的計(jì)算結(jié)果連接處的計(jì)算式的輸入值的事丙号。ーー利用先朦,未知的計(jì)算式的(輸入值,輸出值)的組的近似式能創(chuàng)造犬缨。作為一個(gè)例子輸入層烙无、中間層?輸出層的階層構(gòu)造持ーー以下所示。


圖:神經(jīng)網(wǎng)絡(luò)的一個(gè)例子

層次結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò)遍尺,神經(jīng)元的集合層截酷。各層的神經(jīng)元前一層的神經(jīng)元開(kāi)始輸入值領(lǐng)取,內(nèi)部的線性函數(shù)(y = ax + b形函數(shù))計(jì)算運(yùn)行乾戏,計(jì)算結(jié)果也有一定的值(閾值)如果超越1迂苛,如果不把0輸出值決定的。然后鼓择,第二層的神經(jīng)元這輸入輸出值作為同樣的計(jì)算三幻,輸出值的基礎(chǔ)上又一個(gè)層的神經(jīng)元進(jìn)行計(jì)算…據(jù)說(shuō)進(jìn)行挪用了。因此呐能,輸入層賦值和出力層某種計(jì)算結(jié)果被輸出念搬,成為神經(jīng)元內(nèi)的線性函數(shù)的參數(shù)設(shè)定好的話希望能夠制作的計(jì)算式的譯抑堡。這是數(shù)值計(jì)算限定了的事,而是作為輸入圖像像素排列交貨朗徊,輸出和畫(huà)像表示物體的分類值輸出使這樣的事情可能首妖,神經(jīng)網(wǎng)絡(luò)機(jī)器學(xué)習(xí)廣泛利用的。

但是爷恳,在那里的問(wèn)題有缆,“怎么神經(jīng)元內(nèi)的參數(shù)進(jìn)行適當(dāng)?shù)脑O(shè)定?”温亲。于是登場(chǎng)的學(xué)習(xí)棚壁。學(xué)習(xí)這么難聽(tīng)到,中學(xué)學(xué)習(xí)的幾何學(xué)的世界考慮以下問(wèn)題參數(shù)a栈虚,b追求同樣的事情袖外。

【問(wèn)題】
函數(shù)“y = ax + b”通過(guò)點(diǎn)(0,3)和點(diǎn)(4魂务,0)的時(shí)候曼验,請(qǐng)回答a和b的值

【答案】
a=-?
b=3
也就是說(shuō),輸入x對(duì)于y知道的話头镊,計(jì)算式中出現(xiàn)的參數(shù)(=適當(dāng)?shù)暮瘮?shù))可計(jì)算蚣驼。上述的幾何學(xué)的問(wèn)題機(jī)械學(xué)習(xí)的觀點(diǎn)來(lái)看魄幕,輸入對(duì)應(yīng)的數(shù)據(jù)組「( x相艇,y )=( 0 3 ),( 4,0 )」是教師數(shù)據(jù)纯陨,被稱為“線性函數(shù)y = ax + b”的參數(shù)a坛芽,b計(jì)算學(xué)習(xí)相當(dāng)。當(dāng)然翼抠,上述例子一樣函數(shù)一次函數(shù)咙轩。如果知道瞬間準(zhǔn)確的參數(shù)計(jì)算的,完全未知的函數(shù)對(duì)用別的方法參數(shù)近似這樣的方法阴颖。這個(gè)參數(shù)的學(xué)習(xí)方法的不同和神經(jīng)元連接方法活喊,神經(jīng)網(wǎng)絡(luò)的各種各樣的分類。

■感知器量愧?
感知器是神經(jīng)網(wǎng)絡(luò)的一種钾菊,復(fù)數(shù)的投入2進(jìn)制(0或1的排列)返回模型。感知器大致分為以下兩類偎肃。

  1. 單層感知器
  2. 多層感知器

單層感知器是最簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)煞烫,輸入和輸出層只有模型。形象是以下累颂。單層感知器2層只能線性分離可能的問(wèn)題不能只解滞详,線性分離可能的話一定能解開(kāi)問(wèn)題。這是一次函數(shù)(線性函數(shù))在曲線(2次元以上的函數(shù)=非線性函數(shù))表達(dá)不了,直線的話一定能表現(xiàn)的是一樣的道理


圖:?jiǎn)螌痈兄鞯男蜗?/div>

計(jì)算式
單層感知器的神經(jīng)元利用線性函數(shù)式表示如下料饥。對(duì)于輸入xi蒲犬,以參數(shù)視圖為重點(diǎn),取得總和稀火,總和超過(guò)了閾值的話暖哨,輸出1,如果不是這樣的話凰狞,就輸出0

學(xué)習(xí)方法
單層感知器的學(xué)習(xí)方法被稱為Delta定律篇裁。需要解答Delta定律有點(diǎn)難的公式(為了使誤差函數(shù)最小而使用重降法,定義誤差函數(shù))赡若,但在編制程序的基礎(chǔ)上只要利用結(jié)果就可以了达布,以下的公式按順序更新參數(shù)。
在Delta定律中逾冬,如果輸出與教師數(shù)據(jù)不同的情況下黍聂,在“t(教師數(shù)據(jù))- o(推測(cè)的輸出)”的方向上反復(fù)更新參數(shù),總有一天會(huì)得到正確的參數(shù)(但是身腻,因?yàn)槔弥亟捣O為解決产还。也有容易陷入的缺點(diǎn))。


image.png

在學(xué)習(xí)階段嘀趟,需要在正確的輸出值之前進(jìn)行標(biāo)準(zhǔn)三角則的參數(shù)更新脐区,所以需要使用多數(shù)的教師數(shù)據(jù)的學(xué)習(xí)。但是她按,因?yàn)閷W(xué)習(xí)完成是為了不需要參數(shù)的更新牛隅,所以可以使用輕高速量的計(jì)算
另一方面,多層感知器3層以上的階層的神經(jīng)網(wǎng)絡(luò)酌泰,被稱為背景屬性學(xué)習(xí)方法用單層感知器不能的線性非分離的問(wèn)題也可以解了
■單層感知器的學(xué)習(xí)舉動(dòng)確認(rèn)
用手計(jì)算來(lái)確認(rèn)進(jìn)行OR計(jì)算的單層感知器學(xué)習(xí)的行為媒佣。首先,關(guān)于單層感知器陵刹,作為輸入的數(shù)n = 2默伍,參數(shù)是如下的初始化。


image.png

image.png

這里的教師(輸入數(shù)據(jù))

給出的話衰琐,單層感知器的輸出值如下計(jì)算


image.png

OR計(jì)算

輸出也糊,所以希望這個(gè)結(jié)果不正確的學(xué)習(xí)階段進(jìn)入。學(xué)習(xí)階段Delta定律按照參數(shù)進(jìn)行以下更新


image.png

更新后的參數(shù)的基礎(chǔ)上尋求再次輸出值以下碘耳。仍舊是不正確的显设,比以前更正確的回答有點(diǎn)接近,可以確認(rèn)辛辨。這樣做輸入值如果反復(fù)改變學(xué)習(xí)捕捂,總有一天會(huì)正確輸出吧



■安裝程序
以下是單層感知器實(shí)施程序展示瑟枫。實(shí)現(xiàn)了單層感知器學(xué)習(xí)OR的計(jì)算

import java.util.Random;

public class TestPerceptron
{

public static void main(String[] args)
{
    // OR計(jì)算的教師數(shù)據(jù)
    // 輸入數(shù)據(jù)排列 x =(輸入1,輸入2)排列,正確數(shù)據(jù)排列 answer
    final double[][] x        = { { 1.0f , 1.0f } ,
                                { 1.0f , 0.0f } ,
                                { 0.0f , 1.0f } ,
                                { 0.0f , 0.0f }  };
    final double[]   answer   = {  1.0f ,
                                   1.0f ,
                                   1.0f ,
                                    0.0f };

    // 感知器作成
    // 初始狀態(tài)的輸出
    Perceptron perceptron     = new Perceptron( 2 );
    System.out.println( "[init]  " + perceptron );

    // 學(xué)習(xí)
    int succeed = 0;        // 初始化連續(xù)正確次數(shù)
    for( int i=0 ; i<1000 ; i++ )
    {
        // 空出行間
        System.out.println();
        System.out.println( String.format( "Trial:%d" , i ) );

        // 選擇使用的教師數(shù)據(jù)
        int k = i % answer.length;

        // 估計(jì)輸出值
        double   outY = perceptron.output( x[k] );
        System.out.println( String.format( "[input] %f , %f" , x[k][0] , x[k][1] ) );
        System.out.println( String.format( "[output] %f" , outY ) );

        // 評(píng)價(jià)?判定
        if( answer[k] != outY )
        {
            // 初始化連續(xù)正確次數(shù)
            succeed = 0;

            // 學(xué)習(xí)
            System.out.println( "[learn] before :" + perceptron );
            perceptron.learn( answer[k] , outY , x[k] );
            System.out.println( "[learn] after  :" + perceptron );

        }else{
            // 更新連續(xù)正確的次數(shù)
            // 所有的教師數(shù)據(jù)都有正確答案的話就結(jié)束了
            if( ++succeed >= answer.length ){ break; }
        }
    }

    // 所有的教師數(shù)據(jù)都有正確的正確答案
    // 超過(guò)收斂限度數(shù)(1000次)的情況下結(jié)束
    System.out.println( "[finish] " + perceptron );

}

}

/**

  • 感知器代表
  • ■x1 → V1
  • ■ → y1
  • θ
  • ■x2 → V2
  • x:入力
  • y:出力
  • v:結(jié)合加重
  • θ:閾値
  • 利用標(biāo)準(zhǔn)三角洲定律

*/
class Perceptron
{

// 內(nèi)部変數(shù)
private int         inputNeuronNum  = 0;         // 輸入數(shù)
private double[]    inputWeights    = null;      // 每個(gè)輸入的加權(quán)
private double      threshold       = 0;         // 閾値θ(臨界值)
private double      epsilon         = 0.01f;     // 學(xué)習(xí)用的定數(shù)ε

/**
 * 初期化
 * @param inputNeuronNum 輸入的神經(jīng)元個(gè)數(shù)
 */
public Perceptron( int inputNeuronNum )
{
    // 變量初期化
    Random r = new Random();
    this.inputNeuronNum = inputNeuronNum;
    this.inputWeights   = new double[ inputNeuronNum ];
    this.threshold      = r.nextDouble();               // 隨機(jī)生成閾值

    // 用隨機(jī)數(shù)初始化結(jié)合加權(quán)
    for( int i=0 ; i<inputWeights.length ; i++ )
    { this.inputWeights[i] = r.nextDouble(); }

    // 確認(rèn)信息
    System.out.println( "Init Neuron!" );
}

/**
 * 學(xué)習(xí)
 * @param t           教師數(shù)據(jù)
 * @param o           輸出值
 * @param inputValues 輸入數(shù)據(jù)
 */
public void learn( double t , double o , double[] inputValues )
{
    // 標(biāo)準(zhǔn)三角定律的學(xué)習(xí)
    for( int i=0 ; i<inputNeuronNum ; i++ )
    {
        inputWeights[i] += epsilon * ( t - o ) * inputValues[i];
        //System.out.println( String.format( "%f, %f , %f , %f , %f" , epsilon , t , o , inputValues[i] , epsilon * ( t - o ) * inputValues[i] ) );
    }
}

/**
 * 計(jì)算
 * @param  inputValues 輸入神經(jīng)元開(kāi)始的輸入值
 * @return 返回値
 */
public double output( double[] inputValues )
{
    // 計(jì)算輸入值的總和
    double  sum = 0;
    for( int i=0 ; i<inputNeuronNum ; i++ ){ sum += inputValues[i] * inputWeights[i]; }

    // 輸出函數(shù)是階梯函數(shù)
    double  out = ( sum > threshold )? 1 : 0;

    return out;
}

/**
 * 全班內(nèi)部確認(rèn)的字符串輸出
 */
@Override
public String toString()
{
    // 輸出文字列
    String output = "weight : ";
    for( int i=0 ; i<inputNeuronNum ; i++ ){ output += inputWeights[i] + " , "; }

    return output;

}

}

■解說(shuō)

作為感知器學(xué)習(xí)用的數(shù)據(jù),準(zhǔn)備了輸入數(shù)據(jù)x /輸出數(shù)據(jù)answer的組(16行~ 23行)指攒。以這個(gè)教師數(shù)據(jù)為基礎(chǔ)進(jìn)行神經(jīng)元顯示函數(shù)計(jì)算慷妙,在輸出值與教師數(shù)據(jù)不同的情況下,反復(fù)進(jìn)行學(xué)習(xí)(32行~62行)允悦。在學(xué)習(xí)發(fā)生時(shí)膝擂,進(jìn)行“[ learn ]○○”的標(biāo)準(zhǔn)輸出,從而能夠看到內(nèi)部參數(shù)的變化(第53行~55行)隙弛。 學(xué)習(xí)的結(jié)束條件是所有的教師數(shù)據(jù)都是正確的或者是一定次數(shù)(1000次)的循環(huán)執(zhí)行架馋。在上述執(zhí)行中,從第127次的試行中「0 or 0 = 0」「1 or 1 = 1」「1 or 0 = 1」「1 or 1 = 1」和所有的教師數(shù)據(jù)是正確的全闷。為此叉寂,試行結(jié)束了130次,學(xué)習(xí)結(jié)束了总珠,也有試行4次結(jié)束的情況屏鳍,也有1000次也不會(huì)結(jié)束的情況
感知器實(shí)施班中Perceptron,定義了初始化函數(shù)(101行~115行)局服、學(xué)習(xí)函數(shù)(123行~131行)?計(jì)算函數(shù)(138行~ 148行)钓瞭。學(xué)習(xí)函數(shù)和計(jì)算函數(shù)是如上所述的實(shí)施。另外淫奔,在本程序中山涡,為了實(shí)現(xiàn)每個(gè)執(zhí)行的學(xué)習(xí)內(nèi)容,作為參數(shù)的初始值搏讶,給予了隨機(jī)數(shù)(110行~111行)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佳鳖,一起剝皮案震驚了整個(gè)濱河市霍殴,隨后出現(xiàn)的幾起案子媒惕,更是在濱河造成了極大的恐慌,老刑警劉巖来庭,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妒蔚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡月弛,警方通過(guò)查閱死者的電腦和手機(jī)肴盏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)帽衙,“玉大人菜皂,你說(shuō)我怎么就攤上這事±髀埽” “怎么了恍飘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵榨崩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我章母,道長(zhǎng)母蛛,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任乳怎,我火速辦了婚禮彩郊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚪缀。我一直安慰自己秫逝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布询枚。 她就那樣靜靜地躺著筷登,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哩盲。 梳的紋絲不亂的頭發(fā)上前方,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音廉油,去河邊找鬼惠险。 笑死,一個(gè)胖子當(dāng)著我的面吹牛抒线,可吹牛的內(nèi)容都是我干的班巩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嘶炭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼抱慌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起眨猎,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤抑进,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后睡陪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體寺渗,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年兰迫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了信殊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡汁果,死狀恐怖涡拘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情据德,我是刑警寧澤鳄乏,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布府蔗,位于F島的核電站,受9級(jí)特大地震影響汞窗,放射性物質(zhì)發(fā)生泄漏姓赤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一仲吏、第九天 我趴在偏房一處隱蔽的房頂上張望不铆。 院中可真熱鬧,春花似錦裹唆、人聲如沸誓斥。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)劳坑。三九已至,卻和暖如春成畦,著一層夾襖步出監(jiān)牢的瞬間距芬,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工循帐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留框仔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓拄养,卻偏偏與公主長(zhǎng)得像离斩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瘪匿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355