#################################### # Winner-Take-All Groups # coded by Y.Suganuma #################################### ############################# # Winnerクラスの定義 # coded by Y.Suganuma ############################# class Winner ######################### # コンストラクタ # max : 最大学習回数 # n : 訓練例の数 # o : 出力セルの数 # p : 入力セルの数 ######################### def initialize(max_i, n_i, o_i, p_i) # 設定 @_max = max_i @_n = n_i @_o = o_i @_p = p_i # 領域の確保 @_e = Array.new(@_n) # 訓練例 @_c = Array.new(@_n) # 各訓練例に対する正しい出力 for i1 in 0 ... @_n @_e[i1] = Array.new(@_p+1) @_c[i1] = Array.new(@_o) end @_w_p = Array.new(@_o) # 重み(ポケット) @_w = Array.new(@_o) # 重み for i1 in 0 ... @_o @_w_p[i1] = Array.new(@_p+1) @_w[i1] = Array.new(@_p+1) end @_ct = Array.new(@_o) # 作業領域 end ######################################### # 訓練例の分類 # return : 正しく分類した訓練例の数 ######################################### def Bunrui() mx = 0 mx_v = 0 num = 0 sw = 0 for i1 in 0 ... @_n cor = 0 for i2 in 0 ... @_o if @_c[i1][i2] == 1 cor = i2 end s = 0 for i3 in 0 ... @_p+1 s += @_w[i2][i3] * @_e[i1][i3] end if i2 == 0 mx = 0 mx_v = s else if s > mx_v mx = i2 mx_v = s sw = 0 else if s == mx_v sw = 1 end end end end if sw == 0 and cor == mx 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 for i2 in 0 ... @_o @_c[i1][i2] = Integer(s[@_p+i2]) end end f.close() end ################################# # 学習と結果の出力 # pr : =0 : 画面に出力 # =1 : ファイルに出力 # name : 出力ファイル名 ################################# def Learn(pr, name="") mx = 0 mx_v = 0 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 ... @_o for i2 in 0 ... @_p+1 out.print(" " + String(@_w_p[i1][i2])) end out.print("\n") end out.print("分類結果\n") for i1 in 0 ... @_n sw = 0 for i2 in 0 ... @_o s = 0 for i3 in 0 ... @_p+1 s += @_w_p[i2][i3] * @_e[i1][i3] end if i2 == 0 mx_v = s mx = 0 else if s > mx_v sw = 0 mx_v = s mx = i2 else if s == mx_v sw = 1 end end end end for i2 in 1 ... @_p+1 out.print(" " + String(@_e[i1][i2])) end out.print(" Cor ") for i2 in 0 ... @_o out.print(" " + String(@_c[i1][i2])) end if sw > 0 mx = -1 end out.print(" Res " + String(mx+1) + "\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 mx = 0 run = 0 run_p = 0 sw = -1 num_p[0] = 0 for i1 in 0 ... @_o for i2 in 0 ... @_p+1 @_w[i1][i2] = 0 end end # 実行 while sw < 0 # 終了チェック count += 1 if count > @_max sw = 0 else # 訓練例の選択 k = Integer(rand(0) * @_n) if k >= @_n k = @_n - 1 end # 出力の計算 sw1 = 0 cor = -1 for i1 in 0 ... @_o if @_c[k][i1] == 1 cor = i1 end s = 0 for i2 in 0 ... @_p+1 s += @_w[i1][i2] * @_e[k][i2] end @_ct[i1] = s if i1 == 0 mx = 0 else if s > @_ct[mx] mx = i1 sw1 = 0 else if s == @_ct[mx] sw1 = 1 if cor >= 0 and mx == cor mx = i1 end end end end end # 正しい分類 if sw1 == 0 and cor == mx run += 1 if run > run_p num = Bunrui() if num > num_p[0] num_p[0] = num run_p = run for i1 in 0 ... @_o for i2 in 0 ... @_p+1 @_w_p[i1][i2] = @_w[i1][i2] end end if num == @_n sw = count end end end # 誤った分類 else run = 0 for i1 in 0 ... @_p+1 @_w[cor][i1] += @_e[k][i1] @_w[mx][i1] -= @_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]) o = Integer(s[5]) n = Integer(s[7]) s = gets().split(" ") name = s[1] # ネットワークの定義 srand() net = Winner.new(max, n, o, 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 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 =end