Нейронная сеть (персептрон) - визуализация границы решения (в виде гиперплоскости) при выполнении бинарной классификации - PullRequest
1 голос
/ 24 апреля 2020

Я хотел бы визуализировать границы решения для простой нейронной сети только с одним нейроном (3 входа, двоичный выход). Я извлекаю веса из модели Keras NN, а затем пытаюсь нарисовать плоскость поверхности, используя matplotlib. К сожалению, гиперплоскость не появляется между точками на диаграмме рассеяния, а вместо этого отображается под всеми точками данных (см. Выходное изображение).

Я рассчитываю ось z гиперплоскости, используя уравнение z = (d - ax - by) / c для гиперплоскости, определенной как ax + by + cz = d

Может ли кто-нибудь помочь мне с правильным построением и отображением гиперплоскости на основе весов NN?

Output:

Цель здесь состоит в том, чтобы классифицировать людей на две группы (диабет или отсутствие диабета) на основе 3 переменных-предикторов с использованием набора данных c (https://www.kaggle.com/uciml/pima-indians-diabetes-database).

%matplotlib notebook

import pandas as pd
import numpy as np
from keras import models
from keras import layers
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d

EPOCHS = 2

#Data source: https://www.kaggle.com/uciml/pima-indians-diabetes-database
ds = pd.read_csv('diabetes.csv', sep=',', header=0)

#subset and split
X = ds[['BMI', 'DiabetesPedigreeFunction', 'Glucose']]
Y = ds[['Outcome']]

#construct perceptron with 3 inputs and a single output
model = models.Sequential()
layer1 = layers.Dense(1, activation='sigmoid', input_shape=(3,))
model.add(layer1)

model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])

#train perceptron
history = model.fit(x=X, y=Y, epochs=EPOCHS)

#display accuracy and loss
epochs = range(len(history.epoch))

plt.figure()
plt.plot(epochs, history.history['accuracy'])
plt.xlabel('Epochs')
plt.ylabel('Accuracy')

plt.figure()
plt.plot(epochs, history.history['loss'])
plt.xlabel('Epochs')
plt.ylabel('Loss')

plt.show()

#extract weights and bias from model
weights = model.layers[0].get_weights()[0]
biases = model.layers[0].get_weights()[1]

w1 = weights[0][0] #a
w2 = weights[1][0] #b
w3 = weights[2][0] #c
b = biases[0]      #d

#construct hyperplane: ax + by + cz = d
a,b,c,d = w1,w2,w3,b

x_min = ds.BMI.min()
x_max = ds.BMI.max()

x = np.linspace(x_min, x_max, 100)

y_min = ds.DiabetesPedigreeFunction.min()
y_max = ds.DiabetesPedigreeFunction.max()

y = np.linspace(y_min, y_max, 100)

Xs,Ys = np.meshgrid(x,y)
Zs = (d - a*Xs - b*Ys) / c

#visualize 3d scatterplot with hyperplane
fig = plt.figure(num=None, figsize=(9, 9), dpi=100, facecolor='w', edgecolor='k')
ax = fig.gca(projection='3d')

ax.plot_surface(Xs, Ys, Zs, alpha=0.45)

ax.scatter(ds.BMI, ds.DiabetesPedigreeFunction, ds.Glucose, c=ds.Outcome)

ax.set_xlabel('BMI')
ax.set_ylabel('DiabetesPedigreeFunction')
ax.set_zlabel('Glucose')

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

Граница принятия решения от вашей сети не ax + by + cz = d, а ax + by + cz + d = 0.

0 голосов
/ 24 апреля 2020

Лучшее предположение, не читая весь код подробно. Похоже, вы применили сигмовидную активацию. Если вы тренируетесь без активации (активации = 'линейный'), вы должны получить визуализацию, которую вы ищете. Возможно, вам придется больше тренироваться, чтобы получить конвергенцию (при условии, что она может сходиться без активации). Если вы хотите сохранить сигмоид, то вам нужно отобразить свой линейный нейрон через эту активацию (следовательно, он больше не будет похож на плоскость).

РЕДАКТИРОВАТЬ:

Мое понимание NNs. Плотный слой от 3 до 1 и сигмовидная активация - это попытка оптимизировать переменные a, b, c, d в уравнении:

f (x, y, z) = 1 / (1 + e ^ (- D (x, y, z)); D (x, y, z) = ax + by + cz + d

, так что двоичная_кросентропия (то, что вы выбрали) сведена к минимуму, I будет использовать B для суммы бревен. Наше уравнение потерь будет выглядеть примерно так:

L = ∑ B (y, Y)

где y - значение, которое мы хотим предсказать, a 0 или 1 в этом случае, а Y - это значение, выводимое вышеприведенным уравнением, сумма складывается по всем данным (или пакетам в NN). Следовательно, это можно записать как

L = ∑ B (y, f (x, y, z))

Нахождение минимума L для заданных переменных a, b, c, d, вероятно, можно рассчитать напрямую, взяв частные производные и решив данную систему уравнений (Вот почему NN никогда не следует использовать с небольшим набором переменных (например, 4), потому что они могут быть явно решены, поэтому нет смысла в обучении.) Независимо от прямого решения или использования stocasti c gra Приемник прилично медленно перемещает a, b, c, d к минимуму; в любом случае мы получаем оптимизированные a, b, c, d.

a, b, c, d были специально настроены для получения значений, которые при подключении к сигмовидному уравнению дают предсказанные категории, которые при тестировании в уравнении потерь дают нам минимальные потери.

Я стою исправлено, хотя. В этом случае, поскольку у нас есть специфическая сигмоида, то настройка и решение граничного уравнения, по-видимому, всегда производят плоскость (я не знал этого). Я не думаю, что это будет работать с любой другой активацией или с любым NN, который имеет более одного уровня.

1/2 = 1 / (1 + e ^ (- D (x, y, z))) ... D (x, y, z) = 0 ax + by + cz + d = 0

Итак, я скачал ваши данные и запустил ваш код. Я не получаю конвергенции вообще; Я пробовал различные batch_sizes, функции потерь и функции активации. Ничего. Исходя из этой картины, представляется правдоподобным, что почти все рандомизированные веса будут способствовать удалению от скопления, а не пытаться найти его центр.

Возможно, вам сначала нужно преобразовать данные (нормализация по всем осям может помочь) или вручную установить вес в что-то в центре, чтобы обучение сходилось. Короче говоря, ваши a, b, c, d не оптимальны. Вы также можете явно решить описанные выше частные производные и найти оптимальные a, b, c, d вместо того, чтобы пытаться заставить сходиться один нейрон. Существуют также явные уравнения для расчета оптимальной плоскости, разделяющей двоичные данные (расширение линейной регрессии).

...