1
$\begingroup$

I am trying to build a binary classifier with tensorflow.keras Currently unable to identify a solution to having the model generating only 0s and 1s.

The code for compiling my tensorflow model.

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

def build_model(train_dataset):
  model = keras.Sequential([
    layers.Dense(10, activation='relu', input_shape=[len(train_dataset.keys())]),
    layers.Dense(1, activation='sigmoid')
  ])
  optimizer = 'adam'

  model.compile(loss='binary_crossentropy',
                optimizer=optimizer,
                metrics=[tf.keras.metrics.Precision(), tf.keras.metrics.Recall(), tf.keras.metrics.Accuracy()])
  return model

model = build_model(X)

After calling model.fit(X,y) and model.predict(X_test) an array of numbers are produced as prediction values:

array([[8.3726919e-01],
       [9.1233850e-04],
       [8.3726919e-01],
       ...,
       [4.6819448e-05],
       [1.5565268e-08],
       [0.0000000e+00]], dtype=float32)

My current solution to the problem is to get the output as a number in the range (0,1) from the sigmoid activation function; and then transforming the values to 0 or 1

reset_predictions = []
for p in predictions:
    if p >= 0.5:
        reset_predictions.append(1)
    else:
        reset_predictions.append(0)

However this is not ideal; what I hope to achieve is for the model to classify 0 or 1 for me without an external function.

$\endgroup$
2
$\begingroup$

I don't believe that's possible, in order for the model to return 0 or 1, your activation function on the output layer would have to return 0 or 1, which would mean that the activation function is non-differentiable, and you cannot do that.

Also you can simplify your transformer function to:

In [20]: predictions = np.array([[0.1], [0.9], [0.3], [0.6]])                              

In [21]: (predictions[:, 0] > 0.5).astype(np.int8)                                         
Out[21]: array([0, 1, 0, 1], dtype=int8)

So it is very little extra work, and it gives your more flexibility if you want to see how confident the model is about the prediction, and you can change the threshold if you like.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.