0

这是关于 XOR 和 MLP 困扰我一段时间的事情。它可能是基本的(如果是这样,请提前致歉),但我想知道。

使用 MLP 解决 XOR 的方法有很多,但通常它们看起来像这样:

from sklearn.neural_network import MLPClassifier

X = [[0, 0], [0, 1], [1, 0], [1, 1]]
y = [0, 1, 1, 0]

model = MLPClassifier(
    activation='relu', max_iter=1000, hidden_layer_sizes=(4,2))

现在拟合模型:

model.fit(X, y)

你猜怎么着?

print('score:', model.score(X, y)) 

输出完美

得分:1.0

但预测和评分的是什么?在 XOR 的情况下,我们有一个数据集,根据定义(!)有四行、两个特征和一个二进制标签。没有标准X_train, y_train, X_test, y_test可以使用。同样,根据定义,模型没有可以消化的看不见的数据。

预测以以下形式发生

model.predict(X)

这与进行培训的情况完全相同X

那么模型不只是吐回y它训练的内容吗?我们怎么知道模型“学到”了什么?

编辑:只是想澄清什么让我感到困惑-这些功能有 2 个且只有 2 个唯一值;2 个唯一值有 4 种且只有 4 种可能的组合。每个可能组合的正确标签已经存在于标签列中。那么模型在fit()被调用时要“学习”什么?这种“学习”是如何进行的?当模型可以访问每个可能的输入组合的“正确”答案时,它怎么会是“错误的”?

再次抱歉,这可能是一个非常基本的问题。

4

1 回答 1

1

关键是异或问题的提出是为了证明一些模型可以学习非线性问题而一些模型不能。

因此,当模型在您提到的数据集上获得 1.0 的准确度时,这是值得注意的,因为它已经学习了一个非线性问题。它已经学习了训练数据这一事实足以让我们知道它可以[潜在地]学习非线性模型。请注意,如果不是这种情况,您的模型将获得非常低的准确度,例如 0.25,因为它通过一条线将 2D 空间分成两个子空间。

为了更好地理解这一点,让我们看一个模型在相同情况下无法学习数据的情况:

import tensorflow as tf
import numpy as np

X = np.array(X)
y = np.array(y)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(2, activation='relu'))

model.compile(optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.1), loss='categorical_crossentropy', metrics=['categorical_accuracy'])
model.fit(X, y, epochs=100)
_, acc = model.evaluate(X, y)
print('acc = ' + str(acc))

这使:

累积 = 0.5

如您所见,该模型无法对已经看到的数据进行分类。原因是,这是一个非线性数据,我们的模型只能对线性数据进行分类。(这里有一个链接可以更好地理解 XOR 问题的非线性)。只要我们在网络中添加另一层,它就能够解决这个问题:

import tensorflow as tf
import numpy as np

X = np.array(X)
y = np.array(y)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(1, activation='relu'))
model.add(tf.keras.layers.Dense(2, activation='relu'))


tb_callback = tf.keras.callbacks.TensorBoard(log_dir='./test/', write_graph=True)

model.compile(optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.1), loss='categorical_crossentropy', metrics=['categorical_accuracy'])
model.fit(X, y, epochs=5, callbacks=[tb_callback, ])
acc = model.evaluate(X, y)
print('acc = ' + str(acc))

这使:

累积 = 1.0

通过只添加一个神经元,我们的模型学会了做它在 100 个 epoch 中无法学习的事情(即使它已经看到了数据)。

总而言之,我们的数据集非常小,网络可以轻松记住它是正确的,但 XOR 问题很重要,因为这意味着有些网络无论如何都无法记住这些数据。

话虽如此,但在适当的训练和测试集上存在各种 XOR 问题。这是一个(情节略有不同):

import numpy as np
import matplotlib.pyplot as plt

x1 =np.concatenate([np.random.uniform(0, 100, 100), np.random.uniform(-100, 0, 100)])
y1 =np.concatenate([np.random.uniform(-100, 0, 100), np.random.uniform(0, 100, 100)])

x2 =np.concatenate([np.random.uniform(0, 100, 100), np.random.uniform(-100, 0, 100)])
y2 =np.concatenate([np.random.uniform(0, 100, 100), np.random.uniform(-100, 0, 100)])

plt.scatter(x1, y1, c='red')
plt.scatter(x2, y2, c='blue')
plt.show()

异或数据

希望有所帮助;))

于 2019-06-08T14:28:31.173 回答