这个简单的Keras神经网络计算结果如何?

How is this simple Keras neural-network calculating result?

我正在尝试了解一个简单的前向神经网络是如何工作的...从示例开始 here 我已经对其进行了简化,使训练器通常可以提供 100% 的准确度 "AND" 神经元:

# import the necessary packages
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Activation
from keras.optimizers import SGD
from keras.layers import Dense
from keras.utils import np_utils
from imutils import paths
import numpy as np
import argparse
import cv2
import os

def image_to_feature_vector(image, size=(32, 32)):
    # resize the image to a fixed size, then flatten the image into
    # a list of raw pixel intensities
    return cv2.resize(image, size).flatten()

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-m", "--model", required=True,
    help="path to output model file")
args = vars(ap.parse_args())

# grab the list of images that we'll be describing
#print("[INFO] describing images...")
#imagePaths = list(paths.list_images(args["dataset"]))

## initialize the data matrix and labels list
#data = []
#labels = []

## loop over the input images
#for (i, imagePath) in enumerate(imagePaths):
    ## load the image and extract the class label (assuming that our
    ## path as the format: /path/to/dataset/{class}.{image_num}.jpg
    #image = cv2.imread(imagePath)
    #label = imagePath.split(os.path.sep)[-1].split(".")[0]

    ## construct a feature vector raw pixel intensities, then update
    ## the data matrix and labels list
    #features = image_to_feature_vector(image)
    #data.append(features)
    #labels.append(label)

    ## show an update every 1,000 images
    #if i > 0 and i % 1000 == 0:
        #print("[INFO] processed {}/{}".format(i, len(imagePaths)))
#print(labels)
#exit()
data = [[0,0],[0,1],[1,0],[1,1]]
labels = [0,0,0,1]

# encode the labels, converting them from strings to integers
le = LabelEncoder()
labels = le.fit_transform(labels)

# scale the input image pixels to the range [0, 1], then transform
# the labels into vectors in the range [0, num_classes] -- this
# generates a vector for each label where the index of the label
# is set to `1` and all other entries to `0`
data = np.array(data)# / 255.0
labels = np_utils.to_categorical(labels, 2)

# partition the data into training and testing splits, using 75%
# of the data for training and the remaining 25% for testing
print("[INFO] constructing training/testing split...")
(trainData, testData, trainLabels, testLabels) = train_test_split(
    data, labels, test_size=0.0, random_state=42)
print('train')
print(trainData)
print(trainLabels)
print('test')
print(testData) #oopse, empty...
print(testLabels)
testData = trainData
testLabels = trainLabels

# define the architecture of the network
model = Sequential()
model.add(Dense(2, input_dim=2, kernel_initializer="uniform",
    activation="relu"))
model.add(Activation("softmax"))

# train the model using SGD
print("[INFO] compiling model...")
sgd = SGD(lr=0.35)
model.compile(loss="binary_crossentropy", optimizer=sgd,
    metrics=["accuracy"])
print(model.fit.__doc__)
model.fit(trainData, trainLabels, epochs=50, batch_size=128,
    verbose=False)

print(model.predict(np.array([[0,1]])))
print('Should be [1,0]')#false
print(model.predict(np.array([[1,0]])))
print('Should be [1,0]')#false
print(model.predict(np.array([[0,0]])))
print('Should be [1,0]')#false
print(model.predict(np.array([[1,1]])))
print('Should be [0,1] true.')
# show the accuracy on the testing set
print("[INFO] evaluating on testing set...")
(loss, accuracy) = model.evaluate(testData, testLabels,
    batch_size=128, verbose=1)
print("[INFO] loss={:.4f}, accuracy: {:.4f}%".format(loss,
    accuracy * 100))

# dump the network architecture and weights to file
print("[INFO] dumping architecture and weights to file...")
model.save(args["model"])

现在当 运行 使用 python3 ./simple_andNN.py --model ./outputfile.hdf5 时,我可以在 Hdfview 应用程序中打开输出模型,这就是我所看到的:

现在我希望 [1 1] 的值(唯一分类在正组中的值,result=[更小,更大的数字])是点积一个矩阵(kernel 矩阵在这个简单的例子中?),加上一些恒定的偏差,但是当我尝试它时,它似乎没有添加任何输出都在说。我是不是误解了 "neuron" 根据这些数据应该做什么?

您在 print 语句中看到的结果是在 softmax 操作之后。

[1 1] . [-.70 .77; -.64 .81] + [1.9 -0.62] = [.53 .96]

然后

exp(.53) = 1.69, exp(.96) = 2.62

所以结果是

[1.69/(1.69+2.62) 2.62/(1.69+2.62)] = [.39 .61]

(明显有舍入误差)

另请注意,在技术上采用 softmax 之前,您有一个 relu 激活,但由于这是正数的标识,因此它对 [1 1] 示例没有影响。这会对 [1 0] 示例产生影响,因为您的 Wx + b 的第二个分量是负数,然后将被清零。