How to use one hot encoded ouput vector with Dense to train a model in keras

喜夏-厌秋 提交于 2019-12-24 21:03:30

问题


I'm a newbie in machine learning. I have a image dataset which contains 6 classes each one with 800 train & 200 validation images. I'm using keras to train the model model. Previously I used sparse_categorical_crossentropy as loss parameter to compile the model as I was supplying integer(total no. of classes) which ran with no problem. The code as follows:

import numpy as np
from keras import applications
from keras import Model
from keras.models import Sequential
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Input
from keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
from keras import backend as K
from keras import optimizers
from numpy import array
import cv2
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder


img_width, img_height = 150, 150

class_indics = 'class_indices.npy'
bottleneck_train_path = 'bottleneck_features_train.npy'
bottleneck_validation_path = 'bottleneck_features_validation.npy'
top_model_weights_path = 'bottleneck_fc_model.h5'
train_data_dir = 'data/train'
validation_data_dir = 'data/validation/'

nb_train_samples = 4800
nb_validation_samples = 1200

epochs = 50
batch_size = 15


def generate_class_indics():
    datagen = ImageDataGenerator(rescale=1. / 255)

    generator_top = datagen.flow_from_directory(train_data_dir,
                                                    target_size=(img_width, img_height),
                                                    batch_size=batch_size,
                                                    class_mode='categorical',
                                                    shuffle=False)

    # save the class indices to use later in predictions
    np.save(class_indics, generator_top.class_indices)


def train_top_model():
    print('Training of top model started.')
    train_data = np.load(open(bottleneck_train_path, 'rb'))
    train_labels = np.array(
        [0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2))

    validation_data = np.load(open(bottleneck_validation_path, 'rb'))
    validation_labels = np.array(
        [0] * (nb_validation_samples // 2) + [1] * (nb_validation_samples // 2))

    class_dictionary = np.load('class_indices.npy').item()
    num_classes = len(class_dictionary)

    model = Sequential()
    model.add(Flatten(input_shape=train_data.shape[1:]))
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='softmax'))

    model.compile(optimizer='rmsprop',
                  loss='sparse_categorical_crossentropy', metrics=['accuracy'])

    model.fit(train_data, train_labels,
              epochs=epochs,
              batch_size=batch_size,
              validation_data=(validation_data, validation_labels))
    model.save_weights(top_model_weights_path)
    print('Training of top model completed & saved as: ',top_model_weights_path)

Now I wanna use on hot encoding vector with categorial_crossentropy to compile the model.

def generate_one_hot_encoded():

        temp_class_label = os.listdir("data/train")
        if '.DS_Store' in temp_class_label:
            temp_class_label.remove('.DS_Store')
        sorted_class_labels =  sorted(temp_class_label)

        # integer encode
        label_encoder = LabelEncoder()
        integer_encoded = label_encoder.fit_transform(sorted_class_labels)
        print(integer_encoded)
        # binary encode
        onehot_encoder = OneHotEncoder(sparse=False, categories='auto') # silence warning using categories='auto'
        integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
        onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
        print(onehot_encoded)
        return onehot_encoded

But whenever I was going to use onehot encoded output into Dense like:

model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(generate_one_hot_encoded(), activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

It gives error:

scale /= max(1., float(fan_in + fan_out) / 2) TypeError: only size-1 arrays can be converted to Python scalars

I think I'm trying to fit a multidimensional arrays into size-1 arrays but how could I use this on hot encoded vector properly?

来源:https://stackoverflow.com/questions/53594864/how-to-use-one-hot-encoded-ouput-vector-with-dense-to-train-a-model-in-keras

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!