パーセプトロンの学習規則
フリーソフトでつくる音声認識システム パターン認識・機械学習の初歩から対話システムまで
- 作者: 荒木雅弘
- 出版社/メーカー: 森北出版
- 発売日: 2007/10/01
- メディア: 単行本(ソフトカバー)
- 購入: 45人 クリック: 519回
- この商品を含むブログ (39件) を見る
詳しい説明(理屈)はめんどくさいので省略します。
データを2クラスに分類します。
入力ベクトルをx、重みベクトルをwとすると識別関数はy(x)=wx+biasとなります。
y(x)>0ならクラス1,y(x)<0ならクラス2とします。
学習率をrhoとすると、wの更新式を次のようになる。
w = w + rho * x ( クラス1のデータをクラス2と識別したとき)
w = w - rho * x ( クラス2のデータをクラス1と識別したとき)
重みベクトルwを求めるアルゴリズムは以下の通りです。
- 重みベクトルwの初期値を決める
- 学習データから1つデータを選び、識別関数y(x)を計算
- 誤識別をした場合、更新式に従ってwを更新
- 2.3.を全ての学習データに対して行う。
- 全て正しく識別できれば終了。そうでなければ、2.へ
単純なのは良いけどベクトルを用いてまとめて計算できないし、
if文とか多くなるからRとの相性は悪そう。
以下実装コード
#パーセプトロンの学習規則 # 2クラス判別用 #識別関数 # x:入力ベクトル, w:重みベクトル myPerceptron.f <- function(x,w.with.bias){ bias <- w.with.bias[1] # バイアスのみ抽出 w <- w.with.bias[2:length(w.with.bias)] return ( sum(w*x)+bias ) } #閾値関数 # x:入力ベクトル, w:重みベクトル myPerceptron.predict <- function(x,w){ if( myPerceptron.f(x,w) > 0 ){ return (1) }else{ return (2) } } #学習関数 # data:学習データ, t:学習データのクラスベクトル # w.first:wの初期値, rho:学習率, its:最大学習回数 myPerceptron.train <- function(data,t,w.first,rho,its){ if( is.vector(data) == TRUE ){ data <- matrix(data,length(data),1) # ベクトルを行列に直す } bias <- w.first[1] #;cat("bias=",bias) w <- w.first[2:length(w.first)] #;cat(" w[1]=",w[1],",w[2]=",w[2],"\n") N <- nrow(data) #;cat("N=",N,"\n") for( i in 1:its ){ flag <- TRUE for( n in 1:N){ x <- data[n,] #; cat("x[1]=",x[1],",x[2]=",x[2],"\n") cls <- myPerceptron.predict(x,c(bias,w)) if( cls != t[n] ){ # 誤識別した時だけ学習を行う flag <- FALSE if( t[n] == 1 ){ w <- w + rho*x bias <- bias + rho }else if( t[n] == 2 ){ w <- w - rho*x bias <- bias - rho } #cat("修正後w:bias=",bias,"w[1]=",w[1],",w[2]=",w[2],"\n") } } #全学習データに対して誤りがなければ学習を終了する if( flag == TRUE ){ break; } } return (c(bias,w)) } # プロット関数 # w:学習結果, data:学習データ, t:学習データのクラスラベル myPerceptron.plot <- function(w,data,t){ a <- 200 # プロットデータの個数,大きくすると時間がかかる tx <- seq(0,9,length=a) ty <- tx rapMyPer <- function(x,y){ return ( myPerceptron.predict(c(x,y),w) ) } #z <- outer(tx,ty,rapMyPer) # 動かない orz z <- matrix(0,length(ty),length(tx)) for( y in 1:length(tx) ){ # 泣く泣くfor文 for( x in 1:length(ty) ){ z[x,y] <- rapMyPer(tx[x],ty[y]) } } # 分類結果の領域を描画 image(tx,ty,z,col=c("#00FF80","#FFBF00"),axes=TRUE,xlab="x",ylab="y") # 学習データ点をプロット points( datasrc[,1], datasrc[,2], col=ifelse(t==1,"red","blue"), pch=ifelse(t==1,16,17) ) title("myPerceptron:[testData0.csv]") return (z) }
outer関数が動かないんだよなぁ・・・
便利なのに・・・
とりあえず次のデータ(testData0.csv)で試してみた。
x,y,class
1,5,1
2,2,1
3,6,1
4,3,1
5,4,1
4,1,2
6,1,2
6,0.5,2
8,3,2
8,4,2
実行コード
#2次元2クラスのデータで実験 datasrc <- read.csv("testData0.csv") t <- datasrc[,3] datasrc <- datasrc[,1:2] data.matrix <- matrix(0,nrow(datasrc),ncol(datasrc)) for( i in 1:nrow(datasrc) ){ for( j in 1:ncol(datasrc) ){ data.matrix[i,j] <- datasrc[i,j] } } data.matrix w.first <- c(0.2,0.3,0.4) #初期値 rho <- 0.01 #学習率 its <- 100 #最大学習回数 (w <- myPerceptron.train(data.matrix,t,w.first,rho,its) ) z <- myPerceptron.plot(w,data,t) #学習結果の表示
なんか、csv読み込んだままだとエラーが出るから単純な行列に直しています。
実行すると次のプロット図が出ました。