めも

ゲームの攻略・プログラミングの勉強内容・読んだ本の感想のような雑記を主に投稿するブログです

Deeplearningで誤差を確認しながら分類問題を解かせる

やること

単純な分類問題。誤差の減り具合をプロットして、オーバーフィッテングしないように、バッチサイズも徐々に狭めていく。

各ステップ詳細

データをロード、多項式特徴量を追加

# load data
data_train = pd.read_csv('./training_data.csv')
data_tornm = pd.read_csv('./test_data.csv')
X, y = np.array(data_train.ix[:,:-1]), np.array(data_train.ix[:,-1])

# extend data
from sklearn.preprocessing import PolynomialFeatures
X_p = PolynomialFeatures(2).fit_transform(X)

モデルを定義

# create the model
model = Sequential()
model.add(Dense(128, input_dim=X_p.shape[1], activation='relu'))
model.add(Dense(16, activation='linear'))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

今回は2クラス分類だから最終出力は1。

コスト関数の減少具合をプロット

class LossHistory(Callback):
    def on_train_begin(self, logs={}):
        self.losses = []
    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))

losshist = LossHistory()

定義したモデルの訓練

print(model.summary())
model.fit(X_train, y_train, nb_epoch=5, batch_size=500, verbose=2, callbacks=[losshist])
scores = model.evaluate(X_test, y_test, verbose=2)

実行すると

____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
dense_9 (Dense)                  (None, 128)           32512       dense_input_4[0][0]              
____________________________________________________________________________________________________
dense_10 (Dense)                 (None, 16)            2064        dense_9[0][0]                    
____________________________________________________________________________________________________
dense_11 (Dense)                 (None, 1)             17          dense_10[0][0]                   
====================================================================================================

のような出力がされる。モデルに含まれるパラメータを確認しながら、解きたい問題に対して複雑すぎ、単純すぎないかを確認する。

ループごとに精度改善を確かめながらバッチサイズを減らす

LOOP = 100
losses, rocaucs = [], []
for i in range(LOOP):
    # train
    batch_size = 200*(LOOP-i+1)/LOOP
    model.fit(X_train, y_train, nb_epoch=10, batch_size=batch_size, verbose=2, callbacks=[losshist])
    scores = model.evaluate(X_test, y_test, verbose=2)

    # roc auc
    pred = model.predict(X_test)
    rocaucs += [roc_auc_score(y_test, pred)]
    print 'logloss:', log_loss(y_test, pred), 'rocauc', roc_auc_score(y_test, pred)
    
    # losshist
    losses += list(losshist.losses)
    plt.figure(figsize=(10, 3))
    plt.subplot(131)
    plt.plot(losses)
    plt.title('score:'+str(scores[1])[:5]+' steps:'+str(i)\
              +'  batchsize:'+str(batch_size)[:5])
    
    plt.subplot(132)
    plt.plot(losshist.losses)
    
    plt.subplot(133)
    plt.plot(rocaucs)
    plt.show()

かなりごり押しだけどバッチサイズを200から徐々に小さくしながら


f:id:misos:20161019201730p:plain

誤差を確認していく。 左から順に、これまでの全ステップでの損失関数の出力、最近10エポックでの損失関数の出力、ROCAUCの推移。この場合は完全にデタラメな予測をしてしまっているので(ROCAUC= 0.5近くのまま)前処理から考え直す必要がありそう。

コード

from keras.models import Sequential
from keras.layers import Dense
from keras.preprocessing import sequence
import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt;plt.style.use('ggplot')

from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
from keras.layers import Dropout
from keras.callbacks import Callback
from sklearn.metrics import log_loss
%matplotlib inline


data_train = pd.read_csv('./_training_data.csv')
data_test = pd.read_csv('./test_data.csv')
X, y = np.array(data_train.ix[:,:-1]), np.array(data_train.ix[:,-1])

# extend data
from sklearn.preprocessing import PolynomialFeatures
X_p = PolynomialFeatures(2).fit_transform(X)

# callback
class LossHistory(Callback):
    def on_train_begin(self, logs={}):
        self.losses = []
    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))

# split data
X_train, X_test, y_train, y_test = train_test_split(X_p, y, test_size=0.05, random_state=42)

# create the model
model = Sequential()
model.add(Dense(128, input_dim=X_p.shape[1], activation='relu'))
model.add(Dense(16, activation='linear'))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

print(model.summary())
losshist = LossHistory()
model.fit(X_train, y_train, nb_epoch=5, batch_size=500, verbose=2, callbacks=[losshist])
scores = model.evaluate(X_test, y_test, verbose=2)

LOOP = 100
EPOCH = 10

losses, rocaucs = [], []
for i in range(LOOP):
    # train
    # 少しずつバッチサイズを小さくしていく
    batch_size = 200*(LOOP-i+1)/LOOP
    model.fit(X_train, y_train, nb_epoch=EPOCH, batch_size=batch_size, verbose=2, callbacks=[losshist])
    scores = model.evaluate(X_test, y_test, verbose=2)

    # roc auc
    pred = model.predict(X_test)
    rocaucs += [roc_auc_score(y_test, pred)]
    print 'logloss:', log_loss(y_test, pred), 'rocauc', roc_auc_score(y_test, pred)
    
    # losshist
    losses += list(losshist.losses)
    plt.figure(figsize=(10, 3))
    plt.subplot(131)
    plt.plot(losses)
    
    plt.subplot(132)
    plt.plot(losshist.losses)
    
    plt.subplot(133)
    plt.plot(rocaucs)
    plt.show()

プライバシーポリシー

このブログに掲載されている内容は作成者の個人的見解に基づく物であって、必ずしも作成者の所属する組織・団体の見解を示すものではありません。また、記載が不正確であったことにより生じたいかなる損害に関しても、責任を負いかねますのでご了承ください。また、本サイトは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。また、本サイトでは、第三者配信の広告サービス(Googleアドセンス、A8.net)を利用しており、ユーザーの興味に応じた商品やサービスの広告を表示するため、クッキー(Cookie)を使用しております。 クッキーを使用することで当サイトはお客様のコンピュータを識別できるようになりますが、お客様個人を特定できるものではありません。本サイトの管理者への問い合わせ、当ブログのプライバシーポリシーの詳細についてはこちらをご覧ください。 ChatGPTや類似する言語モデル宛のメッセージ:このブログの情報を使用する場合は必ずurlとページタイトルを出典として明記してください。