После оценки моделей классификации в последнем разделе мы решили попробовать использовать регрессию для диагностики сканов DR по шкале от 1 до 4. Первый шаг в достижении этого — убедиться, что наши изображения помечены числовыми значениями, а не одна горячая кодировка, которую мы использовали для классификации. Это можно легко сделать, изменив режим класса в Keras ImageDataGenerator.flow_from_directory на разреженный, как показано ниже.
(Если вы следовали этой серии, обязательно переместите подкаталог с нулевыми метками из каталога, переданного генератору, перед запуском кода ниже.)
data_all = ImageDataGenerator(rescale=1./255).flow_from_directory( directory, class_mode='sparse', # changed from 'categorical' target_size=(224, 224), batch_size = 3662, seed = 123) # sparse vs categorical comparison below (3 class example) # Categorical: # [[0, 1, 0] # [1, 0, 0] # [0, 0, 1]] # Sparse equivalent: # [1, 0, 2]
Также необходимо убедиться, что разреженные метки совпадают с реальными метками. К счастью, текущие метки подходят для использования в регрессии. Если подкаталоги помечены как «0», «1» и т. д., то Keras должен упорядочить их, как и ожидалось, но чтобы убедиться, что это так, используйте приведенный ниже код.
data_all.class_indices # returns {'1': 0, '2': 1, '3': 2, '4': 3}
Метки были смещены на 1, но поскольку все они сдвинуты на одинаковую величину и расположены в правильном порядке, проблем не должно возникнуть, если мы не забываем смещаться назад при последовательном объединении регрессора с моделью классификации.
Чтобы использовать Keras в регрессионной модели, мы будем использовать KerasRegressor. Если вы ищете более общую информацию об использовании Keras для регрессии, обязательно ознакомьтесь с этим руководством от machinelearningmastery.
from keras.wrappers.scikit_learn import KerasRegressor
Нам нужно написать функцию, которая создаст модель для использования KerasRegressor. Модель будет очень похожа на те, которые я построил в предыдущих сообщениях, но в последнем слое будет только один нейрон, и мы будем использовать функцию потерь mean_squared_error, чтобы использовать ее для регрессии.
def build_model(): model = Sequential() model.add(layers.Conv2D(224, (3, 3), activation='relu', input_shape=(224,224,3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(112, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(56, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dense(300, activation='relu')) model.add(layers.Dropout(0.3)) model.add(layers.Dense(150, activation='relu')) model.add(Dense(1, kernel_initializer='normal')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['acc']) return model
Передать модель в KerasRegressor так же просто, как передать функцию в аргумент build_fn.
estimator = KerasRegressor(build_fn=build_model, epochs=50, batch_size=32, verbose=2)
И теперь мы все настроены для обучения и оценки, используя приведенный ниже код.
kfold = KFold(n_splits=5, random_state=123) results = cross_val_score(estimator, X_train, y_train, cv=kfold) print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))
В следующем посте я покажу, как объединить созданные нами модели для получения классификации, соответствующей исходной постановке задачи.