Keras: matching logistic regression performance with sequential neural network?
Some question you might want to think about:

Is your dataset big enough? What kind of data is it? Time series? Should you be shuffling? What learning rate are you using? Can you change it and see the effect on the learning curves: plot(history) output?



With regards to your model, you usually leave the last connected layers joined only by a linear activation (i.e. don't use an activation function, just an identity matrix). You have used the sigmoid all the way through, which is fine, but not for final layer! I have corrected this by not including such a non-linearity, rather the softmax activation, which will squash all values into the range of [0, 1], so they can be interpreted as probabilities. 

I have increased the number of layers and neurons in the initial layers, and swapped in the preferred non-linearity: the Rectified Linear Unit (ReLU). I would recommend having a quick read of this intro from Stanford's CS231n course, which covers some of the best practices. Also, have a look here for a sample of a larger network performing classification, to see how R Keras is best used.

Give the following code a test, and also plot the history to get more intuition as to how the training is progressing: how many epochs might be necessary, whether you are over- or underfitting, etc.

model &lt;- keras_model_sequential() %&gt;%
    layer_dense(units = 200, activation = "relu", input_shape = 39) %&gt;%
    layer_dense(units = 100, activation = "relu") %&gt;%
    layer_dense(units = 100, activation = "relu") %&gt;%
    layer_dense(units = 50, activation = "relu") %&gt;%
    layer_dense(units = 2, activation = "softmax")


model %&gt;% compile(
              optimizer = "rmsprop",
              loss = "categorical_crossentropy",
              metrics = c("accuracy")
          )

history &lt;- model %&gt;% keras::fit(
                                x_train,
                                y_train,
                                epochs = 500,
                                batch_size = 16,
                                validation_split = 0.7, shuffle = T
                            )


plot(history)                           # Are we overfitting?


Disclaimer: If you don't have much data, this model might be even worse that your original one - or you will massively overfit and get 100% training accuracy and terrible validation/test accuracy.

It could well be the case that your data is just better modelled with a simpler model, or that you do not have enough data to get a neural network to hone in on a nice optimum in its optimisation.