回到异或问题的基础——从根本上感到困惑
Back to basics for the XOR problem - fundamentaly confused
关于 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))
输出完美
score: 1.0
但是预测和评分的是什么?在 XOR 的情况下,我们有一个数据集,根据定义(!)有四行、两个特征和一个二进制标签。没有标准 X_train, y_train, X_test, y_test
可以使用。同样,根据定义,模型没有要消化的看不见的数据。
预测以
的形式发生
model.predict(X)
与执行训练的 X
完全相同。
所以模型不只是吐回它被训练的 y
吗?我们怎么知道模型 "learned" 什么?
编辑:只是想弄清楚是什么让我感到困惑——这些特征有 2 个且只有 2 个唯一值; 2 个唯一值有 4 种且只有 4 种可能的组合。每个可能组合的正确标签已存在于标签列中。那么当 fit()
被调用时,模型 "learn" 有什么用呢?这个 "learning" 是如何执行的?当模型可以访问每个可能的输入组合的 "right" 答案时,它怎么会是 "wrong"?
再次抱歉,这可能是一个非常基本的问题。
关键是 XOR 问题的提出是为了证明一些模型可以学习 non-linear 问题而一些模型不能。
因此,当模型在您提到的数据集上获得 1.0 准确度时,这是值得注意的,因为它已经学习了 non-linear 问题。它已经学习了训练数据这一事实足以让我们知道它可以 [潜在] 学习 non-linear 模型。请注意,如果不是这种情况,您的模型将获得非常低的精度,如 0.25,因为它将 2D space 用一条线分成两个 sub-spaces。
为了更好地理解这一点,让我们看一个模型无法在相同情况下学习数据的案例:
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))
给出:
acc = 0.5
如您所见,该模型无法对它已经看到的数据进行分类。原因是,这是一个 non-linear 数据,而我们的模型只能对线性数据进行分类。(here 是一个 link 以更好地理解 XOR 问题的 non-linear 性)。只要我们在网络中添加另一层,它就能解决这个问题:
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))
给出:
acc = 1.0
通过仅添加一个神经元,我们的模型学会了在 1 层的 100 个 epoch 中无法学习的内容(即使它已经看到了数据)。
所以总而言之,我们的数据集很小以至于网络可以很容易地记住它是正确的,但是异或问题很重要,因为它意味着有些网络可以无论如何都不要记住这个数据。
话虽如此,但在适当的训练和测试集上存在各种 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()
希望对您有所帮助 ;))
关于 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))
输出完美
score: 1.0
但是预测和评分的是什么?在 XOR 的情况下,我们有一个数据集,根据定义(!)有四行、两个特征和一个二进制标签。没有标准 X_train, y_train, X_test, y_test
可以使用。同样,根据定义,模型没有要消化的看不见的数据。
预测以
的形式发生model.predict(X)
与执行训练的 X
完全相同。
所以模型不只是吐回它被训练的 y
吗?我们怎么知道模型 "learned" 什么?
编辑:只是想弄清楚是什么让我感到困惑——这些特征有 2 个且只有 2 个唯一值; 2 个唯一值有 4 种且只有 4 种可能的组合。每个可能组合的正确标签已存在于标签列中。那么当 fit()
被调用时,模型 "learn" 有什么用呢?这个 "learning" 是如何执行的?当模型可以访问每个可能的输入组合的 "right" 答案时,它怎么会是 "wrong"?
再次抱歉,这可能是一个非常基本的问题。
关键是 XOR 问题的提出是为了证明一些模型可以学习 non-linear 问题而一些模型不能。
因此,当模型在您提到的数据集上获得 1.0 准确度时,这是值得注意的,因为它已经学习了 non-linear 问题。它已经学习了训练数据这一事实足以让我们知道它可以 [潜在] 学习 non-linear 模型。请注意,如果不是这种情况,您的模型将获得非常低的精度,如 0.25,因为它将 2D space 用一条线分成两个 sub-spaces。
为了更好地理解这一点,让我们看一个模型无法在相同情况下学习数据的案例:
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))
给出:
acc = 0.5
如您所见,该模型无法对它已经看到的数据进行分类。原因是,这是一个 non-linear 数据,而我们的模型只能对线性数据进行分类。(here 是一个 link 以更好地理解 XOR 问题的 non-linear 性)。只要我们在网络中添加另一层,它就能解决这个问题:
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))
给出:
acc = 1.0
通过仅添加一个神经元,我们的模型学会了在 1 层的 100 个 epoch 中无法学习的内容(即使它已经看到了数据)。
所以总而言之,我们的数据集很小以至于网络可以很容易地记住它是正确的,但是异或问题很重要,因为它意味着有些网络可以无论如何都不要记住这个数据。
话虽如此,但在适当的训练和测试集上存在各种 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()
希望对您有所帮助 ;))