回到基础:XOR问题的基本困惑

关于XOR和多层感知机(MLP)的问题困扰我有一段时间了;这可能是一个基础问题(如果是的话,提前道歉),但我想了解更多。

解决XOR问题的MLP方法有很多,但通常看起来像这样:

from sklearn.neural_network import MLPClassifierX = [[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)) 

输出一个完美的

score: 1.0

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

预测是以这种形式进行的

model.predict(X)

这与训练时使用的X完全相同。

那么,模型不是仅仅吐回它训练过的y吗?我们怎么知道模型“学”到了什么呢?

编辑:只是为了试图澄清我的困惑——特征只有2个且仅2个独特值;这2个独特值有4种且仅4种可能的组合。每种可能组合的正确标签已经存在于标签列中。那么,当调用fit()时,模型还有什么可以“学习”的呢?这种“学习”是如何进行的?当模型可以访问每种可能输入组合的“正确”答案时,它怎么可能“错误”呢?

再次,为这可能是一个非常基础的问题道歉。


回答:

关键是XOR问题被提出是为了展示某些模型可以学习非线性问题,而某些模型则不能。

所以,当一个模型在你提到的数据集上获得1.0的准确率时,这是值得注意的,因为它学会了非线性问题。模型学会了训练数据,这足以让我们知道它可以[潜在地]学习非线性模型。注意,如果不是这样,你的模型会得到非常低的准确率,比如0.25,因为它用一条线将二维空间分成了两个子空间。

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

import tensorflow as tfimport numpy as npX = 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))

这给出:

acc = 0.5

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

import tensorflow as tfimport numpy as npX = 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))

这给出:

acc = 1.0

只通过添加一个神经元,我们的模型学会了在100个周期内用1层无法学习的东西(尽管它已经见过了数据)。

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

不过,话虽如此,也有各种具有适当训练和测试集的XOR问题。这里是一个(图表略有不同):

import numpy as npimport matplotlib.pyplot as pltx1 =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()

xor data

希望这对你有帮助;))

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注