Вернемся к основам проблемы XOR - путаница - PullRequest
0 голосов
/ 08 июня 2019

Это то, что беспокоит меня некоторое время о XOR и MLP;он может быть базовым (если да, заранее извиняться), но я хотел бы знать.

Существует много подходов к решению XOR с MLP, но в целом они выглядят так:

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()?И как осуществляется это «обучение»?Как модель может быть «неправильной», если у нее есть доступ к «правильному» ответу для каждой возможной комбинации входов?

Опять извините за, возможно, очень простой вопрос.

1 Ответ

1 голос
/ 08 июня 2019

Ключевым моментом является то, что задача XOR была предложена для демонстрации того, как некоторые модели могут изучать нелинейные задачи, а некоторые - нет.

Таким образом, когда модель получает точность 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))

, что дает:

acc = 1,0

Добавив только один нейрон, наша модель научилась делать то, что не могла выучить, за 100 эпох с одним слоем (хотя она уже видела данные).

Итак, подведем итоги, верно, что наш набор данных настолько мал, что сеть может легко запомнить его, но проблема 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()

xor data

надеюсь, что помогло;))

...