Ты очень близко!
Во-первых, 50 эпох, использующих тренировочный набор только с 4 событиями, было недостаточно для воспроизведения правильного выходного результата (0,1,1,0), поэтому я увеличил количество эпох до 1000.
Ниже приведен код, который я использовал с десятичным и округленным выводом:
import numpy as np
from keras.models import Sequential
from keras.layers.core import Dense
# Set seed for reproducibility
np.random.seed(1)
# the four different states of the XOR gate
training_data = np.array([[0,0],[0,1],[1,0],[1,1]], "float32")
# the four expected results in the same order
target_data = np.array([[0],[1],[1],[0]], "float32")
model = Sequential()
model.add(Dense(4, input_dim=2, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_squared_error',optimizer='adam',metrics=['binary_accuracy'])
history = model.fit(training_data, target_data, epochs=1000, verbose=1)
# decimal output
print('decimal output:\n'+str(model.predict(training_data)))
# rounded output
print('rounded output:\n'+str(model.predict(training_data).round()))
# ouputs:
decimal output:
[[ 0.25588933]
[ 0.82657152]
[ 0.83840138]
[ 0.16465074]]
rounded output:
[[ 0.]
[ 1.]
[ 1.]
[ 0.]]
Модель дает правильную округлую мощность, хорошо! Десятичный вывод удобно использовать для сравнения ручного подхода.
Для ручного подхода, X1 является входом для модели, либо [0,0], [0,1], [1,0] или [1,1]. X2 - это выход первого слоя и ввод последнего слоя. Вес и смещения точно такие же, как вы сказали ("get_weights () [0] и get_weights () [1] - весовые коэффициенты и смещения для первого слоя соответственно), а get_weights () [2] и get_weights () [3] "веса и уклоны для второго слоя"). Но может показаться, что вы забыли функцию активации relu в первом слое? Давайте посмотрим на код решения:
# Parameters layer 1
W1 = model.get_weights()[0]
b1 = model.get_weights()[1]
# Parameters layer 2
W2 = model.get_weights()[2]
b2 = model.get_weights()[3]
# Input
X1 = np.array([[0,0],[0,1],[1,0],[1,1]], "float32")
# Use the following X1 for single input instead of all at once
#X1 = np.array([[0,0]])
# First layer calculation
L1 = np.dot(X1,W1)+b1
# Relu activation function
X2 = np.maximum(L1,0)
# Second layer calculation
L2 = np.dot(X2,W2)+b2
# Sigmoid
output = 1/(1+np.exp(-L2))
# decimal output
print('decimal output:\n'+str(output))
# rounded output
print('rounded output:\n'+str(output.round()))
# ouputs:
decimal output:
[[ 0.25588933]
[ 0.82657152]
[ 0.83840144]
[ 0.16465074]]
rounded output:
[[ 0.]
[ 1.]
[ 1.]
[ 0.]]
Вы можете использовать все 4 входа одновременно, как указано выше, или только один вход, как закомментировано # X1. Обратите внимание, что десятичный вывод «model.predict» и ручной подход дают точно такой же результат (с небольшим отклонением при третьем значении, возможно, из-за некоторого отклонения округления в керас / число пустышек?)