23
$\begingroup$

When I request Keras to apply prediction with a fitted model to a new dataset without label like this:

model1.predict_classes(X_test)

it works fine. But when I try to make prediction for only one row, it fails:

model1.predict_classes(X_test[10])

Exception: Error when checking : expected dense_input_6 to have shape (None, 784) but got array with shape (784, 1)

I wonder, why?

$\endgroup$

9 Answers 9

19
$\begingroup$

You can do:

q = model.predict( np.array( [single_x_test,] )  )
$\endgroup$
1
  • 1
    $\begingroup$ Which also returns a numpy.ndarray. So to get just the value you want: q = model.predict(np.array([single_x_test]))[0] $\endgroup$ Jan 8, 2019 at 18:31
11
$\begingroup$

predict_classes is expecting a 2D array of shape (num_instances, features), like X_test is. But indexing a single instance as in X_test[10] returns a 1D array of shape (features,).

To add back the extra axis, you can use np.expand_dims(X_test[10], axis=0), or X_test[10][np.newaxis,:], or don't get rid of it in the first place (e.g., by using X_test[10:11]).

$\endgroup$
1
  • $\begingroup$ It doesn't seem to work: no error message but no output either. Weird. $\endgroup$
    – Hendrik
    Aug 17, 2016 at 7:40
8
$\begingroup$

Currently (Keras v2.0.8) it takes a bit more effort to get predictions on single rows after training in batch.

Basically, the batch_size is fixed at training time, and has to be the same at prediction time.

The workaround right now is to take the weights from the trained model, and use those as the weights in a new model you've just created, which has a batch_size of 1.

The quick code for that is

model = create_model(batch_size=64)
mode.fit(X, y)
weights = model.get_weights()
single_item_model = create_model(batch_size=1)
single_item_model.set_weights(weights)
single_item_model.compile(compile_params)

Here's a blog post that goes into more depth.

I've used this approach in the past to have multiple models at prediction time- one that makes predictions on big batches, one that makes predictions on small batches, and one that makes predictions on single items. Since batch predictions are much more efficient, this gives us the flexibility to take in any number of prediction rows (not just a number that is evenly divisible by batch_size), while still getting predictions pretty rapidly.

$\endgroup$
5
$\begingroup$

This would be how to predict for one element, this time number 17.

model.predict_classes(X_test[17:18])
$\endgroup$
1
  • $\begingroup$ what's wrong with the answer? $\endgroup$
    – Supamee
    Sep 6, 2018 at 17:42
2
$\begingroup$

You should pass a list with just 1 example, I can't test right now but this should work:

model1.predict_classes([X_test[10]])
$\endgroup$
1
  • $\begingroup$ It doesn't work unfortunately. $\endgroup$
    – Hendrik
    Aug 17, 2016 at 7:39
2
$\begingroup$

if you try to print out the instance you will see this:

x_test:\n
array([[0., 1., 1., ..., 0., 0., 0.],
        [0., 1., 1., ..., 0., 0., 0.],
        [0., 1., 1., ..., 0., 0., 0.],
        ...,
        [0., 1., 0., ..., 0., 0., 0.],
        [0., 1., 1., ..., 0., 0., 0.],
        [0., 1., 1., ..., 0., 0., 0.]])

x_test[0]:
array([0., 1., 1., ..., 0., 0., 0.])

so I think we can just add back a dimension using np.array:

mode.predict(np.array(x_test[0],ndmin=2))
$\endgroup$
1
$\begingroup$
self.result = self.model.predict(X)

where X is numpy array. That is all I did and it worked.

$\endgroup$
1
$\begingroup$

I have fixed this by using the following approach:

single_test = X_test[10]
single_test = single_test.reshape(1,784)

Please note that amount of features (784) in the reshape function is based on your example above, if you have fewer features then you need to adjust it.

Hope it will work for you too.

$\endgroup$
0
$\begingroup$

It means that your training data had the shape of (784, 1). You can just reshape it as the following. It worked for me.

model1.predict_classes(X_test[10].reshape(784,1))

You can also do transpose() if shape is (1,784),

model1.predict_classes(X_test[10].transpose())
$\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.