#################################### # パーセプトロン学習 # (Pocket Algorith with Ratcet) # coded by Y.Suganuma #################################### ########################### # Perceptronクラスの定義 # coded by Y.Suganuma ########################### class Perceptron ######################### # コンストラクタ # max : 最大学習回数 # n : 訓練例の数 # p : 入力セルの数 ######################### def initialize(max_i, n_i, p_i) # 設定 @_max = max_i @_n = n_i @_p = p_i # 領域の確保 @_E = Array.new(@_n) # 訓練例 for i1 in 0 ... @_n @_E[i1] = Array.new(@_p+1) end @_W_p = Array.new(@_p+1) # 重み(ポケット) @_W = Array.new(@_p+1) # 重み @_C = Array.new(@_n) # 各訓練例に対する正しい出力 end ######################################### # 訓練例の分類 # return : 正しく分類した訓練例の数 ######################################### def Bunrui() num = 0 for i1 in 0 ... @_n s = 0 for i2 in 0 ... @_p+1 s += @_W[i2] * @_E[i1][i2] end if (s > 0 and @_C[i1] > 0) or (s < 0 and @_C[i1] < 0) num += 1 end end return num end ########################## # 学習データの読み込み # name : ファイル名 ########################## def Input(name) f = open(name, "r") f.gets() for i1 in 0 ... @_n @_E[i1][0] = 1 s = f.gets().split(" ") for i2 in 1 ... @_p+1 @_E[i1][i2] = Integer(s[i2-1]) end @_C[i1] = Integer(s[@_p]) end f.close() end ################################# # 学習と結果の出力 # pr : =0 : 画面に出力 # =1 : ファイルに出力 # name : 出力ファイル名 ################################# def Learn(pr, name="") num = Array.new(1) n_tri = Pocket(num) if pr == 0 out = $stdout else out = open(name, "w") end out.print("重み\n") for i1 in 0 ... @_p+1 out.print(" " + String(@_W_p[i1])) end out.print("\n") out.print("分類結果\n") for i1 in 0 ... @_n s = 0 for i2 in 0 ... @_p+1 s += @_E[i1][i2] * @_W_p[i2] end if s > 0 s = 1 else if s < 0 s = -1 else s = 0 end end for i2 in 1 ... @_p+1 out.print(" " + String(@_E[i1][i2])) end out.print(" Cor " + String(@_C[i1]) + " Res " + String(s) + "\n") end if @_n == num[0] print(" !!すべてを分類(試行回数:" + String(n_tri) + ")\n") else print(" !!" + String(num[0]) + " 個を分類\n") end end ############################################ # Pocket Algorith with Ratcet # num_p : 正しく分類した訓練例の数 # return : =0 : 最大学習回数 # >0 : すべてを分類(回数) ############################################ def Pocket(num_p) # 初期設定 count = 0 run = 0 run_p = 0 sw = -1 num_p[0] = 0 for i1 in 0 ... @_p+1 @_W[i1] = 0 end # 実行 while sw < 0 count += 1 if count > @_max sw = 0 else # 訓練例の選択 k = Integer(rand(0) * @_n) if k >= @_n k = @_n - 1 end # 出力の計算 s = 0 for i1 in 0 ... @_p+1 s += @_W[i1] * @_E[k][i1] end # 正しい分類 if (s > 0 and @_C[k] > 0) or (s < 0 and @_C[k] < 0) run += 1 if run > run_p num = Bunrui() if num > num_p[0] num_p[0] = num run_p = run for i1 in 0 ... @_p+1 @_W_p[i1] = @_W[i1] end if num == @_n sw = count end end end # 誤った分類 else run = 0 for i1 in 0 ... @_p+1 @_W[i1] += @_C[k] * @_E[k][i1] end end end end return sw end end if ARGV[0] != nil # 基本データの入力 s = gets().split(" ") max = Integer(s[1]) p = Integer(s[3]) n = Integer(s[5]) s = gets().split(" ") name = s[1] # ネットワークの定義 srand() net = Perceptron.new(max, n, p) net.Input(name) # 学習と結果の出力 if ARGV[0] == nil net.Learn(0) else net.Learn(1, ARGV[0]) end else print("***error 入力ファイル名を指定して下さい\n") end =begin ---------------------入力ファイル------------ 最大試行回数 100 入力セルの数 2 訓練例の数 4 入力データファイル or.dat ---------------------or.dat-------------- OR演算の訓練例.最後のデータが目標出力値 -1 -1 -1 -1 1 1 1 -1 1 1 1 1 =end