近年來(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入門](http://krr.blog.shinobi.jp/site%20map#Javaで機(jī)械學(xué)習(xí) - Deeplearning4j入門)』。
神經(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)造持ーー以下所示。

層次結(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的排列)返回模型。感知器大致分為以下兩類。
- 單層感知器
- 多層感知器
單層感知器是最簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò),輸入和輸出層只有模型。形象是以下。單層感知器2層只能線性分離可能的問(wèn)題不能只解,線性分離可能的話一定能解開(kāi)問(wèn)題。這是一次函數(shù)(線性函數(shù))在曲線(2次元以上的函數(shù)=非線性函數(shù))表達(dá)不了,直線的話一定能表現(xiàn)的是一樣的道理

計(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))。

在學(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ù)是如下的初始化。



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

OR計(jì)算

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

更新后的參數(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行)
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。