问题
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