2017-10-07 10 views
1

ケラスモデルで生成されたウェイトを使ってPythonで結果を計算する方法を明確に理解しようとしています予測するKerasモデル)。下のものより単純なケース(隠れたレイヤーを持たない2つのフィーチャまたは隠れたレイヤーを持つ1つのフィーチャ)があると、私は期待した結果を得る(私の計算値はモデルの予測値と同じです)。下のコードでは、出力値が一致しません。だから私は理解していないか、何かを見ていない。患者さんが簡単な英語で説明することができたら、私はこれをやることができます。私は最も満足しています。モデルで予測される値を計算するのにKerasウェイトを使用できません

例コード(2つの機能と1つの隠れ層を有する)

from keras.models import Sequential 
from keras.layers import Dense 
import numpy 

# sigmoid function: nonlinearity. 
def nonlin(x, deriv = False): 
    if (deriv == True): 
     return x * (1 - x) 
    return 1/(1 + numpy.exp(-x)) 

# fix random seed for reproducibility 
numpy.random.seed(5) 
# load dataset 
dataset = numpy.loadtxt("values2.txt", delimiter=",") # 4 samples 2 factors 1 y 
# split into input (X) and output (Y) variables 
X = dataset[:,0:2] 
Y = dataset[:,2] 
# create model (1 hidden layer) 
model = Sequential() 
model.add(Dense(2, input_dim=2, activation='relu')) 
model.add(Dense(1, activation='sigmoid')) 
# Compile model 
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) 
# Fit the model 
model.fit(X, Y, epochs=200, batch_size=1) 
# calculate predictions 
predictions = model.predict(X) 
# round predictions 
rounded = [round(x[0]) for x in predictions] 
#print(rounded) 
#model.summary() 
for layer in model.layers: 
    weights = layer.get_weights() # list of numpy arrays 
    print(weights) 
M = model.get_weights() 
# Example where X = 0() 
print (X[0,0], X[0,1], "=", Y[0]) 
L1 = numpy.array([ [0.0], [0.0] ]) # to hold result of input * weights 
L1[0] = X[0,0] * M[0][0][0] + X[0,1] * M[0][1][0] + M[1][0] 
L1[1] = X[0,0] * M[0][0][1] + X[0,1] * M[0][1][1] + M[1][1] 
L2 = numpy.array([ [0.0] ]) 
L2[0] = L1[0] * M[2][0][0] + L1[1] * M[2][1][0] + M[3][0] 
print (nonlin(L2[0]), predictions[0]) # compare 

入力(Values2.txt:最初のxがyを決定する)

0,0,0 
0,1,0 
1,0,1 
1,1,1 

出力 ...

Epoch 200/200 
4/4 [==============================] - 0s - loss: 0.4380 - acc: 1.0000  
[0.0, 0.0, 1.0, 1.0] 
[array([[ 1.69063699, 0.1998844 ], 
     [ 0.07858475, 0.89751321]], dtype=float32), array([-0.00052627, -0.17762977], dtype=float32)] 
[array([[ 0.83898878], 
     [-0.54218996]], dtype=float32), array([-0.05681464], dtype=float32)] 
0.0 0.0 = 0.0 
[ 0.50976198] [ 0.48580015] 

おかげマティアスValdenegroは

あなたのコメントに応答して、私は次のようにコードを変更している、それが所望の出力を生成します。最初のレイヤーでreluからsigmoidにアクティベーションを変更し、2番目のレイヤーでそれらを使用するときは、最初のレイヤーの結果にnonlin関数を使用しました。あれは正しいですか?

修正されたコード

from keras.models import Sequential 
from keras.layers import Dense 
import numpy 

# sigmoid function: nonlinearity. 
def nonlin(x, deriv = False): 
    if (deriv == True): 
     return x * (1 - x) 
    return 1/(1 + numpy.exp(-x)) 

# fix random seed for reproducibility 
numpy.random.seed(5) 
# load dataset 
dataset = numpy.loadtxt("values2.txt", delimiter=",") # 4 samples 2 factors 1 y 
# split into input (X) and output (Y) variables 
X = dataset[:,0:2] 
Y = dataset[:,2] 
# create model (1 hidden layer) 
model = Sequential() 
model.add(Dense(2, input_dim=2, activation='sigmoid')) 
model.add(Dense(1, activation='sigmoid')) 
# Compile model 
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) 
# Fit the model 
model.fit(X, Y, epochs=200, batch_size=1) 
# calculate predictions 
predictions = model.predict(X) 
# round predictions 
rounded = [round(x[0]) for x in predictions] 
#print(rounded) 
#model.summary() 
for layer in model.layers: 
    weights = layer.get_weights() # list of numpy arrays 
    print(weights) 
M = model.get_weights() 
# Example where X = 0() 
print (X[0,0], X[0,1], "=", Y[0]) 
L1 = numpy.array([ [0.0], [0.0] ]) # to hold result of input * weights 
L1[0] = X[0,0] * M[0][0][0] + X[0,1] * M[0][1][0] + M[1][0] 
L1[1] = X[0,0] * M[0][0][1] + X[0,1] * M[0][1][1] + M[1][1] 
L2 = numpy.array([ [0.0] ]) 
L2[0] = nonlin(L1[0]) * M[2][0][0] + nonlin(L1[1]) * M[2][1][0] + M[3][0] 
print (nonlin(L2[0]), predictions[0]) # compare 

修正されたコード

Epoch 200/200 
4/4 [==============================] - 0s - loss: 0.6463 - acc: 1.0000  
[array([[ 1.70278633, 0.0848918 ], 
     [-0.0271775 , 0.92663836]], dtype=float32), array([-0.14723039, 0.00718958], dtype=float32)] 
[array([[ 0.56880862], 
     [-0.60756117]], dtype=float32), array([ 0.03559623], dtype=float32)] 
0.0 0.0 = 0.0 
[ 0.4985573] [ 0.4985573] 

からの出力Iは、計算は現在の通りであるReLU機能(X×(X> 0)) を添加期待される結果をもたらす。

L1 = numpy.array([ [0.0], [0.0] ]) # to hold result of input * weights 
L1[0] = relu(X[0,0] * M[0][0][0] + X[0,1] * M[0][1][0] + M[1][0]) 
L1[1] = relu(X[0,0] * M[0][0][1] + X[0,1] * M[0][1][1] + M[1][1]) 
L2 = numpy.array([ [0.0] ]) 
L2[0] = L1[0] * M[2][0][0] + L1[1] * M[2][1][0] + M[3][0] 
print (nonlin(L2[0]), predictions[0]) 

ありがとうございます。 (これは基本的な答えだとすれば、私は何かを答えとしてマークするために何をすべきか分かりません...)

+1

PythonコードでReLUを適用することはありません。それはおそらく問題です。 –

+0

ありがとうございます。私は応答して自分のコードを修正しました。編集を参照してください。 –

+1

新しいコードにまだ何の不満もありません... –

答えて

0

私はこの質問に誰も答えたくないとは思っていません。私はMatiasとDanielがすでに言っていることを理解しています)

覚えておく必要がある各層のノードの値を見つけるためにニューラルネットワークの重みを掛ける通常はReLU機能(整流されたリニアユニット)(別名ランプ機能)である起動機能を含みます。

関連する問題