2017-07-04 2 views
6

pima indians diabetes datasetを使用して、私はKerasを使用して正確なモデルを構築しようとしています。私は、次のコードを書いている:簡単なフィードフォワードネットワークのオーバーフィットを回避する方法

# Visualize training history 
from keras import callbacks 
from keras.layers import Dropout 

tb = callbacks.TensorBoard(log_dir='/.logs', histogram_freq=10, batch_size=32, 
          write_graph=True, write_grads=True, write_images=False, 
          embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None) 
# Visualize training history 
from keras.models import Sequential 
from keras.layers import Dense 
import matplotlib.pyplot as plt 
import numpy 

# fix random seed for reproducibility 
seed = 7 
numpy.random.seed(seed) 
# load pima indians dataset 
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",") 
# split into input (X) and output (Y) variables 
X = dataset[:, 0:8] 
Y = dataset[:, 8] 
# create model 
model = Sequential() 
model.add(Dense(12, input_dim=8, kernel_initializer='uniform', activation='relu', name='first_input')) 
model.add(Dense(500, activation='tanh', name='first_hidden')) 
model.add(Dropout(0.5, name='dropout_1')) 
model.add(Dense(8, activation='relu', name='second_hidden')) 
model.add(Dense(1, activation='sigmoid', name='output_layer')) 

# Compile model 
model.compile(loss='binary_crossentropy', 
       optimizer='rmsprop', 
       metrics=['accuracy']) 

# Fit the model 
history = model.fit(X, Y, validation_split=0.33, epochs=1000, batch_size=10, verbose=0, callbacks=[tb]) 
# list all data in history 
print(history.history.keys()) 
# summarize history for accuracy 
plt.plot(history.history['acc']) 
plt.plot(history.history['val_acc']) 
plt.title('model accuracy') 
plt.ylabel('accuracy') 
plt.xlabel('epoch') 
plt.legend(['train', 'test'], loc='upper left') 
plt.show() 
# summarize history for loss 
plt.plot(history.history['loss']) 
plt.plot(history.history['val_loss']) 
plt.title('model loss') 
plt.ylabel('loss') 
plt.xlabel('epoch') 
plt.legend(['train', 'test'], loc='upper left') 
plt.show() 

いくつかの試行の後、私は過学習を避けるために、ドロップアウト層を追加しましたが、ない幸運を持ちます。次のグラフは、検証の損失とトレーニングの損失が1つの時点で分かれていることを示しています。

enter image description here

私はこのネットワークを最適化するために他に何ができますか?

UPDATE:私はそうのようなコードを微調整してきてしまったコメントに基づいて :ここ

model = Sequential() 
model.add(Dense(12, input_dim=8, kernel_initializer='uniform', kernel_regularizer=regularizers.l2(0.01), 
       activity_regularizer=regularizers.l1(0.01), activation='relu', 
       name='first_input')) # added regularizers 
model.add(Dense(8, activation='relu', name='first_hidden')) # reduced to 8 neurons 
model.add(Dropout(0.5, name='dropout_1')) 
model.add(Dense(5, activation='relu', name='second_hidden')) 
model.add(Dense(1, activation='sigmoid', name='output_layer')) 

は500のエポックのために

enter image description here enter image description here

+0

はあなたのための私の解決策の仕事をしましたか?もう助けが必要な場合はお知らせください。 – CoolPenguin

+0

各高密度層の後にドロップアウト層を推奨します。 –

+0

私はそれをしました、ラインはちょうど平らになったより多くの... :( –

答えて

7

enter image description here

最初の例では、> 75%の検​​証精度を与え、もう一つは< 65%の正確さを与え、あなたが100以下のエポックのために損失を比較する場合、最初のもののために以下< 0.5第2のものは> 0.6であった。しかし、2番目のケースはどのように優れていますか?

私にとって2番目のものは、under-fittingのケースです:モデルには十分な学習能力がありません。最初のケースでは、オーバーフィッティングが開始されたときにそのトレーニングが中止されなかったので、over-fittingという問題が発生しましたが(early stopping)。トレーニングが100エポックで止まっていれば、両者の比較ではるかに優れたモデルになります。

目に見えないデータの小さな予測エラーを取得し、オーバーフィットが発生し始めるポイントまでネットワークの容量を増やすことが目的です。

このような場合、over-fittingの回避方法を教えてください。 early stoppingを採用してください。

コードの変更:early stoppinginput scalingを含める。

# input scaling 
scaler = StandardScaler() 
X = scaler.fit_transform(X) 

# Early stopping 
early_stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=3, verbose=1, mode='auto') 

# create model - almost the same code 
model = Sequential() 
model.add(Dense(12, input_dim=8, activation='relu', name='first_input')) 
model.add(Dense(500, activation='relu', name='first_hidden')) 
model.add(Dropout(0.5, name='dropout_1')) 
model.add(Dense(8, activation='relu', name='second_hidden')) 
model.add(Dense(1, activation='sigmoid', name='output_layer'))) 

history = model.fit(X, Y, validation_split=0.33, epochs=1000, batch_size=10, verbose=0, callbacks=[tb, early_stop]) 

Accuracylossグラフ:

enter image description here

+0

それも私の結論だったが、私は私が75%以上することができますかと思っていた –

+1

あなたと同様ですが、スケーリングすると、「85%」のスコアが得られます。そして、他のものは、 'keras'のデフォルトパラメタは'ベストプラクティス 'に設定されています。なぜなら、特定の理由がなければ、それをそのまま残しておく方が良いからです。 –

2

ためのグラフであります糖尿病のようなデータセットは、はるかに単純なネットワークを使用することができます。 2番目の層のニューロンを減らすようにしてください。 (そこに活性化としてtanhを選択した理由はありますか?)

あなたは、単にあなたのトレーニングにEarlyStoppingコールバックを追加することができます加えて:https://keras.io/callbacks/

+0

私の更新を参照してください –

3

まず、このコードのようないくつかの正則(https://keras.io/regularizers/)を追加してみてください:

model.add(Dense(12, input_dim=12, 
      kernel_regularizer=regularizers.l2(0.01), 
      activity_regularizer=regularizers.l1(0.01))) 

また、あなたを減少することを確認してくださいネットワークの大きさ、つまり、500ニューロンの隠れたレイヤーは必要ありません。表現力を低下させるためにそれを取り除くことを試みてください。まだオーバーフィットしている場合は別のレイヤーにすることもできます。また、reluのアクティブ化だけを使用してください。多分、あなたの脱落率を0.75のようなものに上げてみてください(既に高いですが)。あなたはたぶん、多くの時代にそれを実行する必要はありません - それはちょうど十分な時間が過ぎてから過ぎ始めるでしょう。

+0

ありがとう、私は試して返すよ –

+0

私の更新を参照してください –

関連する問題