Ваша архитектура слишком проста для этой функции. Если вы используете приведенную ниже архитектуру и обучаетесь 100 эпох, вы получите точность = 1.
model = Sequential()
model.add(Dense(20,input_dim = 2,activation = 'relu'))
model.add(Dense(20,activation = 'relu'))
model.add(Dense(1,activation = 'sigmoid'))
UPD: почему простая модель не работает так хорошо?
Одна из причин заключается в том, что при активации ReLU, если один нейрон становится отрицательным в каждой точке данных, его градиент становится равным нулю, а его веса больше не изменяются. В начале у вас мало нейронов, и если некоторые из них «умирают» таким образом, оставшихся нейронов может быть недостаточно для аппроксимации функции.
Другая проблема заключается в том, что меньшее количество нейронов повышает вероятность того, что модельзастрять в локальном минимуме.
Тем не менее, вы правы, что теоретически достаточно нескольких нейронов. Модель ниже работает даже с одним слоем. Я заменил ReLU на LeakyReLU, чтобы устранить первую проблему. Это работает большую часть времени, но иногда застревает в локальном минимуме.
model = Sequential()
model.add(Dense(2,input_dim = 2,activation = LeakyReLU(alpha=0.3)))
model.add(Dense(1,activation = 'sigmoid'))
optimizer = Adam(lr=0.01)
model.compile(loss = "binary_crossentropy" , metrics = ['accuracy'], optimizer=optimizer)
model.fit(train,train_label, epochs = 500, verbose=2)