Керас предсказывает только один класс из 3 - PullRequest
0 голосов
/ 24 марта 2019

Я новичок в Керасе. Я взял свою модель из одного из примеров, и она сработала на удивление хорошо. Внезапно моя модель начала предсказывать всегда только один класс из многих. Я думаю, единственное изменение, которое я внес в модель - это добавление новых образцов. Теперь я потерялся и понятия не имею, как выяснить причину. Может кто-нибудь сказать мне, с чего начать и что проверить?

На всякий случай вот код. Приложение извлекает из VW отсортированных изображений, чтобы сортировать оставшиеся несортированными. Изображения выглядят следующим образом: 800 в классе в тренировочном наборе и 300 в классе в тестовом наборе. Валидация и тестирование - это одни и те же наборы.

bad cell good cell mitosis

import numpy as np
from keras.models import model_from_json
from keras.preprocessing import image
import os
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
from shutil import copyfile

# dimensions of the images.
img_width, img_height = 64, 64
input_dirs = [
    #list of dirs to sort with model,
]
out_directory = 'dir_of_auto_sorted_images'
train_base = 'dir_with_training_images'
train_dir = 'train'
val_dir = 'test'
test_dir = 'test'

nb_train_samples = 800*5 #800 training images per class, flipped V/H and zoomed in generator
nb_validation_samples = 1000 #just a number
nb_test_samples = 300*5
epochs = 100
batch_size = 32


#Read class names from training dir. In test in val they should be the same
tmp = os.path.join(train_base, train_dir)
classes = os.listdir(tmp)
classes.sort() #Classes in prediction seem to be sorted by dir_name

for c in classes: #Create output for predicted, where to copy unsorted from model
    try:
        os.makedirs(os.path.join(out_directory,c))
    except:
        pass

#############################


# Is right got gray-scale images? Shouldn't be 1 instead of 3
if K.image_data_format() == 'channels_first':
    input_shape = (1, img_width, img_height)
else:
    input_shape = (img_width, img_height, 1)

# Define model as proposed in keras tutorials
model = Sequential()
model.add(Conv2D(64, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(len(classes), activation='softmax'))
model.add(Activation('sigmoid'))

CreateModel = 1
if CreateModel:
model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

test_datagen = ImageDataGenerator(
    zoom_range=0.2,
    horizontal_flip=True,
    vertical_flip=True)

train_datagen = ImageDataGenerator(
    zoom_range=0.2,
    horizontal_flip=True,
    vertical_flip=True)

train_generator = train_datagen.flow_from_directory(
    os.path.join(train_base, train_dir),
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical',
    color_mode='grayscale',
    #save_to_dir=out_directory+"\\gendebug"
)

validation_generator = train_datagen.flow_from_directory(
    os.path.join(train_base, val_dir),
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical',
    color_mode='grayscale'
)

test_generator = test_datagen.flow_from_directory(
    os.path.join(train_base, test_dir)
    , target_size=(img_width, img_height)
    , batch_size=batch_size
    , class_mode='categorical',
    color_mode='grayscale'
    # ,save_to_dir=out_dir
)

model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size)

# Save model architecture
model_json = model.to_json()
json_file = open(train_base+"/keras_model.json", "w")
json_file.write(model_json)
json_file.close()

# Save model weights
model.save_weights(train_base+"/keras_model.h5")
print("Finished saving")

score = model.evaluate_generator(test_generator, nb_test_samples // batch_size)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

score = model.predict_generator(train_generator, nb_test_samples // batch_size)

print('Test loss:', score[0])
print('Test accuracy:', score[1])
print('Score', score)
#############################


json_file = open(train_base+"/keras_model.json", "r")
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights(train_base+"/keras_model.h5")

loaded_model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])


def get_class(prediction):
    m=max(prediction)
    if m < 0.6:
        return -1

    for i in range(0, len(prediction)):
        if prediction[i] == m:
            return i
    return -1


    right = 0
    wrong = 0





for input_directory in input_dirs:
    print(input_directory)
    cnt=0
    for filename in os.listdir(input_directory):
        os.sys.stdout.write('.')
        os.sys.stdout.flush()
        fn = os.path.join(input_directory, filename)
        img = image.load_img(fn, target_size=(64, 64), color_mode='grayscale')

        x = image.img_to_array(img)
        x = x.astype('float32')
        x /= 255
        x = np.expand_dims(x, axis=0)

        prediction = loaded_model.predict(x)[0]
        c = get_class(prediction)
        if c >= 0 and c < len(prediction):
            predicted = classes[c]
            print(fn, prediction)

            copyfile(fn, os.path.join(out_directory,predicted, filename))
            cnt += 1
            if cnt > 100:
                break
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...