2022.08.19こんにちは、ヒガシです。今回は久しぶりにAI関連のお話です。AI構築時において、Kerasなんかのライブラリを使ってAIモデルを学習させたとします。その学習済モデル(変数model)を使って実際に推論をする場合、例えばKerasの場合だとmodel.predict(入力データ)とすれば学習済みモデルを使った推論を実施できます。実際の運用時においては、KerasライブラリやPythonの実行環境そのものを準備できない場合など、いつもこのやり方で推論できるとは限りません。いうわけでこのページでは、Kerasの内部で行われているニューラルネットワーク計算を、Kerasを使わないで実行する方法をご紹介していきます。※私は普段Kerasしか使わないのでPytorchのことはよくわかりませんが、おそらくほぼ同じやり方で実行できるはずです。それではさっそくやっていきましょう。実運用シーンにおいてこの計算を実施する方法おわりにニューラルネットワーク内部の計算についてそもそもニューラルネットワークの内部ではどのような計算が行われているのでしょうか?その答えは行列の積と和です。詳細については以前記載した以下の記事で解説していますので、興味があればあわせてご覧ください。【人工知能】ディープラーニング内部の計算をエクセルを使って詳細解説!今回は学習済のニューラルネットワークが保有している重みとバイアスを抜き出し、その抜き出したデータを使って行列計算をゴリゴリやっていくことによって、ニューラルネットワークの計算を再現してみます。それでは実際の作業に入っていきましょう。スポンサーリンクニューラルネットワークモデルを構築するそもそもニューラルネットワークのモデルがなければ話になりません。いうわけでまずはニューラルネットワークモデルを構築するところから始めましょう。使用するデータは以下の通りです。適当な係数を4つ使ってy=1.2*x1-2.1*x2+0.7*x3^2-0.5*x4^2+乱数という式を作成しました。今回はこのx1,x2,x3,x4を入力とし、yを出力するニューラルネットワークを構成⇒学習してみます。そのサンプルコードは以下の通りです。optimizer=Adam(lr=0.001))model.summary()validation_split_rate=0.2history=model.fit(Xdata,Ydata,batch_size=16,epochs=100,validation_split=validation_split_rate)これで変数modelに学習済のニューラルネットワークが構成されました。本題から少しそれますが、念のため以下のコードで精度を確認しておきましょう。※ここではmodel.predictを使います。color="b")plt.xlabel('Predict_data')plt.ylabel('Row_data')plt.show()しっかりと正解データを予測できていますね。いうわけで問題なくAIモデルを構築することができました。以降の項目では、先ほどのコード内で実行したmodel.predictの部分をnumpyの行列計算のみで実行し、model.predictで得られた結果と一致するのかを確認していきます。スポンサーリンクニューラルネットワーク内部の重みとバイアスを取り出す先ほども簡単に紹介したとおり、ニューラルネットワーク内部で行われているのは行列の積と和です。この行列の積の部分で使われるのが「重み」、行列の和の部分で使われるのが「バイアス」です。行列計算をするにあたっては、まずはこれら「重み」と「バイアス」を取り出す必要があります。そのやり方は以下の通りです。※先ほどのコードの続きという立ち位置で書いています。今回構築したモデルは3層のニューラルネットワークなので、3層分の重みとバイアスを取り出しています。model.layers[2]L3_weights=layer3.get_weights()[0]L3_bias=layer3.get_weights()[1]以下のコードでそれぞれの変数の大きさを確認してみましょう。print('1層目の重み、バイアス')print(L1_weights.shape)print(L1_bias.shape)print('2層目の重み、バイアス')print(L2_weights.shape)print(L2_bias.shape)print('3層目の重み、バイアス')print(L3_weights.shape)print(L3_bias.shape)以下の結果が出力されました。入力:4中間層Dense:20,10出力:1ですので、しっかりとそれに対応した形で重み、バイアスが取得されていますね。これで事前の準備は完了です。スポンサーリンク取り出した重みとバイアスで行列計算してみるそれでは事前の準備が非常に長くなってしまいましたが、本題であるニューラルネットワーク内部の計算を行列の積&和のみで表現してみましょう。※ここも先ほどまでのコードの続きで書いていきます。そのコードは以下の通りです。今回はnumpyのdotを使って行列の積を計算しています。Pred_mat.append(L3P)順番にコード追いかけていただければ、各層の重みと入力との積を計算し、バイアスと和をとっていることが確認できると思います。最終的な出力結果はPred_matというリストに格納されています。ニューラルネットワークの計算って複雑そうですが、意外とこんなもんなんですよね。※今回は活性化関数をまったく使っていない単純なモデルでの計算結果です。活性化関数が入っているモデルを再現しようと思ったらその部分を追記する必要がありますのでご注意ください。活性化関数付きモデルで同じことをやる方法は以下で解説していますので、興味があればこちらもご覧ください。【AI】活性化関数付MLPモデルの計算を行列計算で再現する方法!スポンサーリンク重みとバイアスで行列計算した結果の確認それでは重みとバイアスでの計算は終わりましたので、もともとmodel.predictで計算した推論結果と比較してみましょう。そのコードは以下の通りです。※変数Predictdataには先ほどの項目でmodel.predictにて推論を行った結果が格納されています。color="b")plt.xlabel('Keras_Predict')plt.ylabel('numpy_Predict')plt.show()実行結果は以下の通りです。横軸がmodel.predictで推論を行った結果、縦軸が取り出した重みとバイアスを使って行列計算して算出した結果です。ご覧の通り完璧に一致していますね。いうわけで学習済モデルから取り出した重みとバイアスを使った行列の積&和によって、moderl.predictで算出した結果を再現できることが確認できました。スポンサーリンク実運用シーンにおいてこの計算を実施する方法ここまでの計算をおさらいしてみましょう。上記の流れをkerasがインポートされたpython環境上で実施してきました。今回の手法を解説するモチベーションは、kerasなんかのライブラリや、pythonそのものが使えない環境においてニューラルネットワークの計算を再現したい人を救いたい、というものでした。この項目ではkerasやpython自体を準備できない環境でこの計算を実施する方法をご紹介します。◾️運用先でkerasは準備できないけどpython自体は準備できている場合この場合、まずはkerasがインポートできている環境下にて先程紹介した重み&バイアスの取得を行います。取得した重み、バイアスはただの配列データですので、そのまま配列データとして保存することができます。その保存した配列データを実際のAI運用環境下から読める場所に置き、その環境で配列をロードし直せば先程紹介したような行列計算を実施することができます。配列のロード、セーブについては以下の記事でご紹介していますので参考にしてみてください。【python】numpy形式のまま配列を保存&既存配列をロードする方法!◾️運用先でpython自体を準備できない場合この場合も、まずはkerasがインポートできている環境下にて先程紹介した重み&バイアスの取得を行います。取得した重み、バイアスのデータはcsvファイルなんかに書き出しておきましょう。実際のAI運用環境から読める場所にそのcsvファイルを置き、その環境からcsvを読み込んでしまえば、後は先程紹介したように行列計算を実施するだけです。スポンサーリンクおわりにというわけで今回は、学習済のニューラルネットワークモデルから重みとバイアスを取り出し、その取り出した係数と入力データで行列計算することによって、ニューラルネットワーク内部の計算を再現する方法をご紹介しました。このやり方さえ理解していれば、エクセルだろうが何だろうが、最悪手計算でもニューラルネットワークの計算を実施することができますよね。実務においては常にPythonを使えるとは限りませんので、このようなやり方もぜひ覚えておきましょう。仕事中で時間がないかもしれませんが、ぜひ通勤時間中などに他の記事も読んでいただけると嬉しいです。⇒興味をもった方は【ヒガサラ】で検索してみてください。確実にスキルアップできるはずです。最後に、この記事が役に立ったという方は、ぜひ応援よろしくお願いします。コピーヒガシをフォローするスポンサーリンクヒガシヒガサラblogスポンサーリンクpython【Python-openCV】白黒画像に輝度の等高線を追加する方法!こんにちは、ヒガシです。こんな感じで輝度の等高線を追加する方法をご紹介していきます。...python【Python】変則的な階段状データを作成!位置、高さ指定するだけ!こんにちは、ヒガシです。このページでは、以下の画像のように変則的な階段状データ配列を作成する方法をご紹介していきます。段が上がる位置と高さを任意の数だけ指定してあげるだけで、ど...python【Python-OpenCV】画像からランダムに指定サイズで切り抜く方法!こんにちは、ヒガシです。画像認識系の機械学習を実施する際、既存のデータを加工してデータを水増しすることが有効な場合もあります。Augmentationってやつですね。...python【python-openCV】2枚の画像輝度を割り算した画像を作成する方法!この記事では、python-openCVを使って、2枚の画像の輝度を割り算した画像を作成する方法をご紹介しています。作成するうえでの注意点解説あり。python【python-openCV】画像にグリッド線(目盛り線)を入れる方法!この記事では以下の画像のように、既存の画像にグリッド線を入れる方法をご紹介します。単純に画像の端から等間隔で線を引くわけではなく、縦、横方向の開始ピクセル、線の本数、線を引く間隔、線の太さを自由に変更可能です。...python【python-openCV】複数の画像から平均輝度値画像を作成する方法!この記事では、pythonを使って複数の画像から平均輝度値画像を作成する方法をご紹介します。実験で撮影された画像から平均データを取得する際などにぜひご活用ください。コメントをキャンセルメールアドレスが公開されることはありません。※サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。上に表示された文字を入力してください。ご指摘ありがとうございます。修正させていただきましました。【python-openCV】背景画像に別の画像を合成する方法!やぎ2023.05.29こんにちは。書く必要があると思います。【python-openCV】背景画像に別の画像を合成する方法!サトシ2023.05.11承知しました。アドバイス本当にありがとうございます。【VBA】大量のファイル名変更!指定したフォルダ内を一括操作!ヒガシ2023.05.11/はフォルダの階層が変わることを意味しますので使えません。substitute関数などを使って別文字に変換してから実行すると良いと思います。【VBA】大量のファイル名変更!指定したフォルダ内を一括操作!サトシ2023.05.10何度もすみません。/を使うと出来ないみたいです。2001-001-1/4とかにしたいのですが、ファイルが見つかりませんとかパスが無効ですとなります。検索タイトルとURLをコピーしました。