質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

Model

MVCモデルの一部であるModelはアプリケーションで扱うデータとその動作を管理するために扱います。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

解決済

KerasやTensorflowのmodel.predict()は数値的に何をやっているのか?

mamoru-max
mamoru-max

総合スコア2

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

Model

MVCモデルの一部であるModelはアプリケーションで扱うデータとその動作を管理するために扱います。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1回答

0リアクション

0クリップ

380閲覧

投稿2022/05/20 10:29

編集2022/05/22 10:48

知りたい事:
Keras(またはTensorflow)でCNNのモデルを構築し学習させた後に、model.predict()で予測値をだす際の数値的な処理の詳細を知りたいです。

試したこと:
学習させたモデルのファイルからパラメータを取得し、教科書的な畳み込み演算、全結合演算をコードした自作CNNで予測値を算出したところ、model.predict()とはかなり異なる値ばかり算出されてしまいました。

Kerasで構築したモデルは以下のとおりです。

Python

model = Sequential() mode.add(Conv2D(20,kernel_size=(1,5), strides=(1,1), padding='valid', input_shape=(24,13,1), activation='relu')) mode.add(Conv2D(20,kernel_size=(1,9), strides=(1,1), padding='valid', activation='relu')) mode.add(Conv2D(20,kernel_size=(24,1), strides=(1,1), padding='valid', activation='relu')) mode.add(Flatten()) mode.add(Dense(20,activation='relu')) mode.add(Dense(2,activation='sigmoid')) model.load_weights(model_path / '[model_filename].h5') model.summary() # Prediction y = model.predict(x, batch_size=1)

私の自作CNNのコードは下の通りです(畳み込みと全結合のみ記載します)

Python

def mydense(ind, ker, bia, func): tem_dense = np.dot(ker.T, ind) + bia return func(tem_dense) def myconv(ind, ker, bia, func): # input sample data's shape H = ind.shape[0] W = ind.shape[1] # kernel' shape Hf = ker.shape[0] Wf = ker.shape[1] K = ker.shape[3] # result of convolution u = np.zeros((H - Hf + 1, W - Wf + 1, K)) # output z = np.zeros((u.shape)) for k in range(0,K): for n in range(0,W - Wf + 1): for m in range(0, H - Hf + 1): u[m,n,k] = (ind[m:m+Hf, n:n+Wf, :] * ker[:,:,:,k] + bia[k]).sum() z = np.array([func(i) for i in u]) return z

KerasまたはTensorflowのソースコード
https://github.com/keras-team/keras/tree/master/keras
などで調べていましたが、私の自作コードの畳み込み演算(上記の myconv)は

Python

from tensorflow.python.ops.nn_ops import convolution from tensorflow.python.ops.gen_nn_ops import conv2d tf.nn.conv2d() from tensorflow.python.ops.nn_ops import convolution_internal from tensorflow.pythonn.ops.nn_ops import convolution_v2

バイアスの付与は

Python

from tensorflow.python.ops.gen_nn_ops import bias_add

と活性化関数(reluとsigmoid)の処理(省略)は結果が一致していましたが、

Python

from keras.layers.convolutional import Conv2D from keras.layers.convolutional import Conv

とは一致していませんでしたので、ここで何かしら教科書的な数式以外の処理が組まれていると推測しています。

▼Kerasのmodel.predict() の数値的な厳密な処理はどのようになっているのか?
▼ソースコードなどの、どのあたりを調べれば分かりそうか?
▼ほかに質問した方が良さそうな、おすすめのサイトは?(英語版のstackoverflowには投稿していますが今のところ返答がありません、、)

この3点について、もしご存じの方いらっしゃいましたら助けて頂けますと大変ありがたいです。

長すぎないようにするためにだいぶ省略しましたので、上記でご不明点等ありましたら遠慮なく仰ってください。
何卒よろしくお願いいたします。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

fourteenlength

2022/05/20 21:47 編集

全体を通して結果を見てどこかが違う、では追跡しにくいので、関数1つ単位で純正の関数と自作関数とで同じ値を入れた時に何が出るか比較してはどうでしょうか?同じインプットをしたら同じ出力であってほしい、というのを関数単位で見ていくイメージです。ネットワーク単位で比較するのはその後がよいです。 「おそらく」その何かあるのがCONV部分だと思うのですが、そうであれば質問の流れを、 ・ ゼロから自力でCNNを作った ・ Keras等の純正ツールと結果を比較したが一致しなかった ・ 関数を一個一個追跡していったところ、CONVの部分が違いそうだった ・ その違う部分の処理を比較すると○○(実際のソースコードを並べる) ・ どこが違うか分からない みたいな感じにした方がよいです。
mamoru-max

2022/05/22 10:35

fourteenlength さん ご指摘ありがとうございます。 分かりにくい投稿で申し訳ございません。
mamoru-max

2022/05/23 00:04 編集

jbpb0 さん ご提案ありがとうございます。 こちらも結果が > from keras.layers.convolutional import Conv2D > from keras.layers.convolutional import Conv と同様に、結果が自作myconvとは異なり、実行毎に異なる値が出力されています。 ご不明点ありましたら、また何かご存じでしたら引き続きご教授頂けますと幸いです。 よろしくお願いいたします。
jbpb0

2022/05/23 13:53

tensorflow.keras.layers.Conv2D の演算に付いて、下記を実行して確認しました import numpy as np import tensorflow as tf from tensorflow.keras.layers import Conv2D from tensorflow.keras import initializers input_size = 7 kernel_size = 3 input_value = 0.5 kernel_value = 1.0 input_np = np.ones((input_size, input_size)) * input_value input_tensor = tf.convert_to_tensor(input_np.reshape(1, input_size, input_size, 1)) kernel = np.ones((kernel_size, kernel_size)) * kernel_value conv_2d = Conv2D(filters=1, kernel_size=(kernel_size, kernel_size), input_shape=(input_size, input_size, 1), kernel_initializer=initializers.Constant(kernel)) output_tensor = conv_2d(input_tensor) output_np = np.squeeze(output_tensor.numpy()) print(input_np) print(kernel) print(output_np) 結果は下記の通りとなり、問題ありませんでした [[0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5]] [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]] [[4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5]]
jbpb0

2022/05/23 23:54

質問のコードの「myconv」を、 def myconv(ind, ker, bia, func): ↓ def myconv(ind, ker, bia): z = np.array([func(i) for i in u]) return z ↓ return u と変更して、下記を実行 import numpy as np input_size = 7 kernel_size = 3 input_value = 0.5 kernel_value = 1.0 input_np = np.ones((input_size, input_size, 1)) * input_value kernel = np.ones((kernel_size, kernel_size, 1, 1)) * kernel_value output_np = myconv(input_np, kernel, [0.0]) print(np.squeeze(input_np)) print(np.squeeze(kernel)) print(np.squeeze(output_np)) 結果は下記の通り、 tensorflow.keras.layers.Conv2D の結果と同じでした [[0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5] [0.5 0.5 0.5 0.5 0.5 0.5 0.5]] [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]] [[4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5] [4.5 4.5 4.5 4.5 4.5]]
mamoru-max

2022/05/24 13:28 編集

jbpb0 さん 私の方でも確認できました、誠にありがとうございます。 また条件をjbpb0 さんのものに合わせて、(当然かもしれませんが)from keras.layers.convolutional import Conv2Dの方でも同じ結果が得られました。 私が質問の箇所で、convolutionalクラスのConv2Dでは毎回異なる結果が出力される(恐らく乱数がきいている)と申し上げましたが、今回のものとの違いは「kernel_initializer=initializers.Constant(kernel)」であり、defaultが 'glorot_uniform' であるため私が単純にConv2Dを使用して毎回ある種の一様乱数が発生していました、こちらをご教示頂いた通りConstantにしたところ、教科書通りの畳み込み計算と同じ結果結果になりました。 しかし、依然としてmodel.predict()とは異なる値になっており、また学習時にconv2Dの引数にkernel_initializerがConstantに指定されていなくても、(常識的に、な推測にはなりますが)predict()では重みに一様乱数を加えたら最適化で算出した重みが変わることになるので、kernel_initializerはpredict()には関係ないのかもしれない、と考えていますが断定もできず、、 続けてpredict()では何が起きているのか、 predict_step https://github.com/keras-team/keras/blob/2a703470e18354c7c4b4c27a2c3846e4471ec54c/keras/engine/training.py#L1785 等の処理の理解を続けてみますので、何か見つかりましたらまた投稿いたします。 またご不明点等ありましたら、または何かご存じでしたら引き続きご教授頂けますと幸いです。
jbpb0

2022/08/01 01:34 編集

> predict()では重みに一様乱数を加えたら最適化で算出した重みが変わることになるので、kernel_initializerはpredict()には関係ないのかもしれない 「kernel_initializer」を指定してない場合に、どのタイミングで重みが乱数で初期化されるのかは、下記が参考になると思います 一番下の「コメント」も見てください https://qiita.com/neptunium/items/a3a4e111c4049a6e1acf 【追記】 > model.load_weights(model_path / '[model_filename].h5') の直前と直後にそれぞれ下記を実行して、表示される結果(重み)を比べてみてください model.get_weights() 「kernel_initializer」を指定してない場合は重みが乱数で初期化されていて、「model.load_weights(...」で重みが上書きされて変わってますよね 「model.predict(...」では、その上書きされた重みが使われてるはずです
mamoru-max

2022/08/01 01:24

ありがとうございます。こちら知りませんでしたので大変助かります。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

Model

MVCモデルの一部であるModelはアプリケーションで扱うデータとその動作を管理するために扱います。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。