【ディープラーニング】kerasで多クラス分類

kerasで多クラス分類

前回

前回は2クラス分類をやりました。

www.tcom242242.net

今回は多クラス分類をやりたいと思う。

やりたいこと

irisデータセットをsklearnから取得して分類してみる。

irisデータセット

sklearnのirisデータセットには3種類の花の萼の長さと幅、花弁の長さと幅のデータがある

iris = datasets.load_iris()
x = iris.data
y = iris.target 

print(x[0]) # => array([ 5.1,  3.5,  1.4,  0.2]) 0番目の花の情報
print(y[0]) # => 0 # 0番目の花は0クラス


コード

from sklearn import datasets
from keras.models import Sequential
from keras.layers import Dense,  Activation
from keras.optimizers import SGD
import numpy as np
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.utils import np_utils

model = Sequential()
model.add(Dense(10, input_dim=4))    # 入力層4ノード, 隠れ層に10ノード, 全結合
model.add(Activation("sigmoid"))    # 活性化関数はsigmoid
model.add(Dense(3)) # 出力層3ノード,全結合
model.add(Activation("sigmoid"))

model.compile(loss="binary_crossentropy",   # 誤差関数
              optimizer="adam",     # 最適化手法
              metrics=['accuracy'])

iris = datasets.load_iris() # データを取得
x = iris.data   # 花の特徴量、長さなど
y = iris.target # 0, 1, 2のラベル
x = preprocessing.scale(x)  # 標準化

y = np_utils.to_categorical(y)  # one-hotエンコード.例) 1 => [0, 1, 0]
x_train, x_test, y_train, y_test= train_test_split(x, y, train_size=0.8)    # 教師データとテストデータに分割

model.fit(x_train, y_train, nb_epoch=1000, batch_size=1) # 学習

# 学習できているか見てみる
print("==============TEST=====================")
print("-----------correct answer-----------")
print(y_test[0])
print(y_test[10])
print("-----------predict answer-----------")
print(np.round(model.predict(x_test)[0]))
print(np.round(model.predict(x_test)[10]))

結果

省略

Epoch 998/1000
120/120 [==============================] - 0s - loss: 0.0249 - acc: 0.9889         
Epoch 999/1000
120/120 [==============================] - 0s - loss: 0.0249 - acc: 0.9889         
Epoch 1000/1000
120/120 [==============================] - 0s - loss: 0.0247 - acc: 0.9889         
==============TEST=====================
-----------correct answer-----------
[ 0.  1.  0.]
[ 0.  0.  1.]
-----------predict answer-----------
[ 0.  1.  0.]
[ 0.  0.  1.]

感想

活性化関数や誤差関数をもう少ししっかり変えれば、

もう少しうまく学習できる気がする。

参考

以下のサイトは非常にわかりやすいです。大いに参考にさせていただきました。 ありがとうございます。

aidiary.hatenablog.com

簡易的なニューラルネットのライブラリをrubyで作ってみた

フィードフォワードニューラルネット用ライブラリ

rubyでkeras風に簡単にニューラルネットを構築できるようなものを作ってみました。

インストール方法

gem install t_nn

2値分類

x1 x2 y
0 0 0
1 0 1
0 1 1
1 1 0

サンプルコード

require "t_nn"

model = TNN::FeedForwardNeuralNetwork.new(learning_rate=0.1)

model.add_layer(node_num=2) # 入力層
model.add_layer(node_num=3) # 中間層
model.add_layer(node_num=1) # 出力層

x_train = [[0.0, 0.0],[0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]
y_train = [[ 0.0 ], [ 1.0 ],[ 1.0 ],[ 0.0 ]]

model.fit(x_train, y_train, learning_num=20000) # 学習

x_test = x_train
y_test = y_train

err_rate = model.evaluate(x_test, y_test)
puts "err rate: #{err_rate}%"

# 各テストに対しての結果出力
x_test.zip(y_test).each do |x, y|
    output = model.propagation(x)
    puts "x#{x},  y#{y},  output#{output}"
end

結果

err rate: 4.178057783239726%
x [0.0, 0.0], y [0.0] , output [0.05228744153982793]
x [0.0, 1.0], y [1.0] , output [0.9559390081562715]
x [1.0, 0.0], y [1.0] , output [0.9560109121906053]
x [1.0, 1.0], y [0.0] , output [0.02678479013663796]

簡単な関数近似

問題設定

以下のような二次関数

{
  \begin{equation}
  y = x^2
  \end{equation}
}

関数近似をおこなってみる。

サンプルコード

require "t_nn"

LEARN_NUM = 10000
def test_fun(x)
  return x*x
end

model = TNN::FeedForwardNeuralNetwork.new(learning_rate=0.1)
model.add_layer(node_num=1)
model.add_layer(node_num=5)
model.add_layer(node_num=1)

x_train = []
100.times do |num|
  x_train.push([( num.to_f/100.0 )])
end

y_train = []
x_train.each do |x|
  y_train.push([test_fun(x[0])])
end

model.fit(x_train, y_train, LEARN_NUM)

x_test = x_train
y_test = y_train

err_rate = model.evaluate(x_test, y_test)
puts "err rate: #{err_rate}%"

# 各テストに対しての結果出力
# x_test.zip(y_test).each do |x, y|
#     output = model.propagation(x) #
#     puts "x#{x},  y#{y},  output#{output}"
# end

結果

出力してみた

f:id:ttt242242:20170108103134p:plain

LEARN_NUM = 10

f:id:ttt242242:20170108103201p:plain

LEARN_NUM = 100

f:id:ttt242242:20170108103206p:plain

LEARN_NUM = 1000

最後に

まだ最適化などdeeplearingに必要なことは実装できていないです。簡単なニューラルネットを使ってみたい人向けです。 これから、少しづつ拡張していく予定です。

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)