27
$\begingroup$

I am newbie on machine learning and keras and now working a multi-class image classification problem using keras. The input is tagged image. After some pre-processing, the training data is represented in Python list as:

[["dog", "path/to/dog/imageX.jpg"],["cat", "path/to/cat/imageX.jpg"], 
 ["bird", "path/to/cat/imageX.jpg"]]

the "dog", "cat", and "bird" are the class labels. I think one-hot encoding should be used for this problem but I am not very clear on how to deal it with these string labels. I've tried sklearn's LabelEncoder() in this way:

encoder = LabelEncoder()
trafomed_label = encoder.fit_transform(["dog", "cat", "bird"])
print(trafomed_label)

And the output is [2 1 0], which is different that my expectation output of somthing like [[1,0,0],[0,1,0],[0,0,1]]. It can be done with some coding, but I'd like to know if there is some "standard" or "traditional" way to deal with it?

$\endgroup$

3 Answers 3

20
$\begingroup$

Sklearn's LabelEncoder module finds all classes and assigns each a numeric id starting from 0. This means that whatever your class representations are in the original data set, you now have a simple consistent way to represent each. It doesn't do one-hot encoding, although as you correctly identify, it is pretty close, and you can use those ids to quickly generate one-hot-encodings in other code.

If you want one-hot encoding, you can use LabelBinarizer instead. This works very similarly:

 from sklearn.preprocessing import LabelBinarizer
 encoder = LabelBinarizer()
 transfomed_label = encoder.fit_transform(["dog", "cat", "bird"])
 print(transfomed_label)

Output:

[[0 0 1]
 [0 1 0]
 [1 0 0]]
$\endgroup$
3
  • $\begingroup$ But how could hotencoding help you when you will try to predict a new color ? Maybe in your case you have to retrain the model. Do you have any solution ? $\endgroup$
    – gtzinos
    Commented Dec 27, 2017 at 12:25
  • $\begingroup$ @gtzinos: That looks like a different question. Perhaps ask it on the site. If you do, make clear whether you are concerned about NN predicting a brand new item (not seen in training data, but logically should happen on new inputs), or adding new classes on the fly when they are encountered in online training data. $\endgroup$ Commented Dec 28, 2017 at 18:32
  • 1
    $\begingroup$ Pay attention that LabelBinarizer() breaks when there are 2 categories only: see stackoverflow.com/questions/31947140/… and stackoverflow.com/questions/48074462/…. $\endgroup$
    – gented
    Commented Jan 20, 2020 at 10:28
0
$\begingroup$

With the imagegenerator feature in keras we can leverage that directly giving a sample code:

datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True,
    validation_split=0.2)


img_size=128
train_generator = datagen.flow_from_directory('train',
                                                    target_size=(img_size, img_size),
                                                    subset='training',
                                                    batch_size=32)
X, y = next(train_generator)

print('Input features shape', X.shape)
print('Actual labels shape', y.shape)

The other advantage of using this is that when we do prediction on a new file then we can use train_generator.class_indices to map back labels from the prediction to actual string names.

$\endgroup$
0
$\begingroup$

Also you can use sparse_categorical_crossentropy as loss function, and then you don't need onehot-encoding.
sample code: model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')

more info at Keras website

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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