Установка вашей проблемы немного странная в том смысле, что у вас есть только четыре точки данных, но вы хотите узнать вес модели с градиентным спуском (или Адамом).Кроме того, batchnorm здесь не имеет смысла, поэтому я бы предложил удалить его.
Кроме того, ваша сеть прогнозирует числа от 0 до 1 («вероятности»), а не метки классов.Чтобы получить предсказанные метки классов, вы можете использовать model.predict_classes(predict_data)
вместо model.predict()
.
Если вы новичок в ML и хотите поэкспериментировать с игрушечными наборами данных, вы также можете взглянуть на scikit-learn, библиотеку, которая реализует более традиционные алгоритмы ML, тогда как Keras специально для глубокого изучения.,Рассмотрим, например, логистическую регрессию, которая аналогична одиночному нейрону с сигмовидной активацией, но реализована с различными решателями в sklearn:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model = model.fit(train_data, train_labels)
model.predict(predict_data)
> array([0., 0., 1., 1.])
На сайте scikit-learn есть множество примеров, иллюстрирующих эти разныеалгоритмы на игрушечных наборах данных.
В вашем втором сценарии вы не допускаете никаких изменений во второй функции, которая является единственной, которая имеет значение.Если вы хотите обучить модель 1000 точкам данных, вы можете сгенерировать данные вокруг четырех точек в исходном наборе данных и добавить к ним случайный шум:
import keras
import numpy as np
import matplotlib.pyplot as plt
# Generate toy dataset
train_data = np.random.randint(0, 2, size=(1000, 2))
# Add gaussian noise
train_data = train_data + np.random.normal(scale=2e-1, size=train_data.shape)
train_labels = (train_data[:, 1] > 0.5).astype(int)
# Visualize the data, color-coded by their classes
fig, ax = plt.subplots()
ax.scatter(train_data[:, 0], train_data[:, 1], c=train_labels)
# Train a simple neural net
model = keras.models.Sequential()
model.add(keras.layers.Dense(1, input_shape= (2,), activation='sigmoid'))
model.compile(optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy'])
history = model.fit(train_data, train_labels, epochs=20)
Вы можете использовать объект истории, чтобы визуализировать, как потеря или точность развивались во время обучения:
fig, ax = plt.subplots()
ax.plot(history.history['acc'])
Наконец,протестируйте модель на некоторых тестовых данных:
from sklearn.metrics import accuracy_score
# Test on test data
test_data = np.random.randint(0, 2, size=(100, 2))
# Add gaussion noise
test_data = test_data + np.random.normal(scale=2e-1, size=test_data.shape)
test_labels = (test_data[:, 1] > 0.5).astype(int)
accuracy_score(test_labels, model.predict_classes(test_data[:, 1]))
Однако учтите, что вы можете решить всю проблему, просто используя вторую координату.Так что все работает отлично, если выбросить первый:
# Use only second coordinate
model = keras.models.Sequential()
model.add(keras.layers.Dense(1, input_shape= (1,), activation='sigmoid'))
model.compile(optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy'])
history = model.fit(train_data[:,1], train_labels, epochs=20)
Эта модель быстро достигает высокой точности: