以前保存した Keras モデルをロードすると結果が異なる理由: 経験と教訓

以前保存した Keras モデルをロードすると結果が異なる理由: 経験と教訓

機械学習モデルは、これまで以上に実稼働環境で広く使用されるようになりました。 Keras は、強力な機械学習およびディープラーニング モデルを作成するための人気のあるライブラリの 1 つです。ただし、実際のデータとモデル アーキテクチャによっては、これらのモデルのトレーニング プロセスは計算コストが高く、時間がかかることがよくあります。モデルによっては、トレーニングに数週間から数か月かかるものもあります。したがって、モデルをローカルに保存し、予測が必要になったときに再度取得できることが重要になります。しかし、何らかの理由で保存したモデルが正しく読み込まれない場合はどうすればよいでしょうか? 自分の経験に基づいて回答してみたいと思います。

Keras モデルの使用方法と保存方法については詳しく説明しません。読者がこのプロセスに精通していることを前提として、ロード時に予期しないモデルの動作に対処する方法に直接進みます。つまり、Model 変数に保存されている Keras モデルをトレーニングした後、そのまま保存して、次回ロードするときにトレーニングをスキップして予測のみを行えるようにします。

私が好むアプローチは、モデルの作成時にランダムに生成され、モデルのトレーニング時に更新されるモデルの重みを保存することです。そこで、model.save_weights("model.h5")をクリックしました。モデルによって学習された重みを含む「model.h5」ファイルが作成されます。次に、別のセッションで、以前と同じアーキテクチャを使用してモデルを再構築し、 new_model.load_weights("model.h5") を使用して保存したトレーニング済みの重みをロードしました。すべて順調のようです。ただ、new_model.predict(test_data) をクリックした後、精度がゼロになるのですが、その理由はわかりません。

モデルが正しい予測を行えない理由はたくさんあることが判明しました。この記事では、最も一般的な原因をまとめ、その解決方法について説明します。

1. まずデータを注意深く確認してください。

明らかなことのように思えますが、1 つのミスが、ディスクからモデルを再ロードするときにパフォーマンスの低下につながる可能性があります。たとえば、言語モデルを構築する場合は、新しいセッションごとに次の操作を実行する必要があります。

  • クラス ラベルの順序を再確認してください。番号にマッピングした場合は、各セッションで各クラス ラベルに同じ番号が付けられていることを再確認してください。これは、毎回異なる順序でタグを返す list(set()) 関数を使用して取得している場合に発生する可能性があります。これにより、ラベルの予測が台無しになる可能性があります。
  • データセットを検査します。テスト データが別のファイルにない場合は、トレーニングとテストの分割がランダムでないことを確認してください。ランダムでないと、予測を行うたびに異なるデータに基づいて予測することになり、予測の精度に一貫性がなくなります。

もちろん、作業する分野によっては、他のデータ関連の問題に遭遇する可能性もあります。ただし、データ表現の一貫性は常に確認してください。

2. メトリクスの問題

エラーや一貫性のない結果のもう一つの原因は、精度測定の選択です。モデルを構築してその重みを保存するときは、通常、次の操作を行います。

 def build_model ( max_len , n_tags ):
input_layer = 入力( 形状= ( max_len ,))
output_layer = Dense ( n_tagsactivation = 'softmax' )( input_layer )
model = モデル( 入力層出力層)

リターンモデル

モデル= build_model ()
モデル. コンパイル( オプティマイザ= "adam"
損失= "sparse_categorical_crossentropy"メトリック= [ "accuracy" ])

モデル. フィット(..)
モデル.save_weights ( "model.h5" )

新しいセッション/スクリプトで開く必要がある場合は、次の操作を行う必要があります。

 def build_model ( max_len , n_tags ):
input_layer = 入力( 形状= ( max_len ,))
output_layer = Dense ( n_tagsactivation = 'softmax' )( input_layer )
model = モデル( 入力層出力層)

リターンモデル
モデル= build_model ()
モデル. コンパイル( オプティマイザー= "adam"損失= "sparse_categorical_crossentropy"メトリック= [ "accuracy" ])
モデル.load_weights ( "model.h5" )
モデルを評価する( )

使用される特定の Keras/Tensorflow バージョンによっては、エラーが発生する可能性があります。この問題は、モデルをコンパイルし、メトリックとして「精度」を選択すると発生します。 Keras は、「スパース分類精度」、「分類精度」など、さまざまな精度の定義を認識します。作業するデータに応じて、異なる定義が推奨されるソリューションとなります。これは、メトリックを「精度」に設定すると、Keras は、データ分布に最も適していると思われる特定の精度タイプのいずれかを割り当てようとするためです。実行ごとに異なる精度メトリックが推測される可能性があります。ここでの最善の解決策は、Keras に精度メトリックを選択させるのではなく、常に精度メトリックを明示的に設定することです。例えば、

 モデル. コンパイル( オプティマイザ= "adam"
損失= "sparse_categorical_crossentropy"メトリック= [ "accuracy" ])

次と置き換えます:

 モデル. コンパイル( オプティマイザ= "adam"
損失= "sparse_categorical_crossentropy"メトリック= [ "sparse_categorical_accuracy" ])

3. ランダム性

以前と同じデータで Keras ニューラル ネットワークを再トレーニングする場合、同じ結果が 2 回得られることはほとんどありません。これは、Keras のニューラル ネットワークが重みを初期化するときにランダム性を使用するため、重みは実行するたびに異なる方法で初期化され、学習プロセス中に異なる方法で更新され、予測を行うときに同じ精度の結果が得られにくくなるためです。

何らかの理由でトレーニング前に重みを等しくする必要がある場合は、コードの前の部分で乱数ジェネレーターを設定できます。

 numpy.random からシードをインポートします
種子( 42 )
tensorflow からset_random_seed をインポートする
ランダムシードを設定する( 42 )

numpy ランダム シードは Keras に使用されますが、Tensorflow バックエンドでは独自の乱数ジェネレーターを同じシードに設定する必要があります。このコード スニペットにより、コードを実行するたびにニューラル ネットワークの重みが同じように初期化されるようになります。

4. カスタムレイヤーの使用に注意する

Keras は多くのレイヤー (Dense、LSTM、Dropout、BatchNormalization など) を提供しますが、モデル内のデータに対して特定のアクションを実行したいのに、そのための特定のレイヤーが定義されていない場合があります。一般的に、Keras は Lambda レイヤー クラスと基本レイヤー クラスの 2 種類のレイヤーを提供します。ただし、特にモデル アーキテクチャを json 形式で保存する場合は、これら 2 つのレイヤーに注意してください。 Lambda レイヤーの難しい部分は、シリアル化の制限です。これは Python バイトコードのシリアル化とともに保存されるため、保存されたのと同じ環境にのみロードでき、移植性はありません。この問題が発生した場合は、通常、モデル全体を保存するのではなく、keras.layers.Layer レイヤーを上書きするか、その重みのみを保存してモデルを最初から再構築することをお勧めします。

5. カスタムオブジェクト

多くの場合、カスタム関数を使用してデータに適用したり、損失/精度などのメトリックを計算したりする必要があります。

Keras では、モデルの保存/読み込み時に追加のパラメータを指定できるため、これが可能になります。以前に保存したモデルとともに、独自に作成した特別な損失関数をロードするとします。

 モデル= load_model ( "model.h5"custom_objects =
{ "custom_loss" : custom_loss })

このモデルを新しい環境にロードする場合、デフォルトではモデルを保存するときにこれらの関数は記憶されないため、新しい環境で custom_loss 関数を定義するように注意する必要があります。モデルのアーキテクチャ全体を保存したとしても、そのカスタム関数の名前も保存されますが、関数本体は追加で提供する必要があるものです。

6. グローバル変数初期化子

これは、バックエンドとして Tensorflow 1.x を使用する場合に特に重要です。多くのアプリケーションでそのバックエンドが依然として必要になる可能性があります。 tf 1.x セッションを実行するときは、すべての変数をランダムに初期化する tf.global_variables_initializer() を実行する必要があります。この副作用として、モデルを保存しようとすると、すべての重みが再初期化される可能性があります。次のコマンドを実行すると、この動作を手動で停止できます。

 keras.backend からmanual_variable_initialization をインポートします。manual_variable_initialization ( True )

結論

この記事では、新しい環境で Keras モデルが正しく読み込まれない最も一般的な原因となるいくつかの要因を示します。これらの問題によって予期しない結果が発生する場合もあれば、単にエラーが発生するだけの場合もあります。これらがいつどのように発生するかは、使用している Python のバージョンや Tensorflow および Keras のバージョンによって大きく異なります。これらのバージョンの中には互換性がないものもあり、予期しない動作につながる可能性があります。この記事を読めば、次にこの種の問題に遭遇したときにどこから始めればよいかがわかるようになるでしょう。

元のタイトル: 以前に保存した Keras モデルをロードすると異なる結果になる理由: 学んだ教訓、著者: Kristina Popova

<<:  機械学習は金融自動化においてどのような役割を果たすのでしょうか?

>>:  エヌビディアによる660億ドルのアーム買収は失敗、ソフトバンクはIPOを通じてアームの事業を独立上場へ

ブログ    
ブログ    

推薦する

...

現時点では、ディープラーニング以外の実装方法を模索する必要がある。

[51CTO.com クイック翻訳] ディープラーニングは確かに多くの印象的な成功事例をもたらしま...

OpenAI、超知能AIの制御に関する中核的な技術的課題に取り組むため新チームを結成

OpenAIは、共同設立者兼主任科学者のイリヤ・スツケバー氏とアラインメント責任者のヤン・ライケ氏が...

AutoML 2.0: データ サイエンティストは時代遅れか?

AutoML はここ数年で急速に成長しました。そして、景気後退が避けられない状況となった今、人工知...

説明可能なAIと説明可能な機械学習:ブラックボックスに光を当てる

人工知能(AI)や機械学習の分野では、「ブラックボックス」という概念が常に大きな注目を集めています。...

...

機械学習の問題を解決する一般的な方法があります!これを読んでください

編集者注: この記事は、WeChat パブリック アカウント「Big Data Digest」(ID...

ビッグデータと人工知能の違いすら分からないのに、あなたはまだトップへの道を歩んでいる

ビッグデータと AI は公平に比較​​できるでしょうか? ある程度は公平ですが、まずはその違いを明確...

AI声優が偽の声を本物らしくする方法

AI音声スタートアップ企業のソナンティックは、オーディオディープフェイクで小さな進歩を遂げ、からかっ...

SIEM&AIからSIEM@AIまで、AIが次世代のエンタープライズセキュリティの頭脳を構築

[51CTO.com からのオリジナル記事] SIEM はエンタープライズ セキュリティの中核ハブで...

...

人工知能の急速な発展により、多くの人が失業し、自立できなくなるのでしょうか?

近年、人工知能が話題となっており、人工知能が人類にもたらす変化について多くの人が議論しています。多く...

15歳の少女が農場の収穫機にヒントを得てピンポン球を拾うロボットを発明

最近、上海の15歳の中学生が卓球ボールを拾うロボットを発明した。体育館の床に散らばった卓球ボールを自...

人工知能と自然言語処理の概要: AI の 3 つの主要段階と NLP の主な応用分野

最近、Xenonstack は Jagreet Kaur 氏による「人工知能の概要とビッグデータにお...