Как показать достоверность прогноза в классификаторе Python (Tensorflow 2.2 / Keras) - PullRequest
0 голосов
/ 18 июня 2020

У меня проблема с выводом прогноза. Я оставляю прикрепленным код модели моего классификатора (6 классов). Я использую Tensorflow 2.2. Код:

import tensorflow as tf
from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow import keras
import cv2
import PIL
import os
import numpy as np

#Dir
train_dir ='/home/Tensorflow/Dataset_mix/train/'
validation_dir = '/home/Tensorflow/Dataset_mix/test/'

ACCURACY_THRESHOLD = 0.99
class myCallback(tf.keras.callbacks.Callback): 
    def on_epoch_end(self, epoch, logs={}): 
        if(logs.get('accuracy') > ACCURACY_THRESHOLD):   
            print("\nReached %2.2f%% accuracy, so stopping training!!" %(ACCURACY_THRESHOLD*100))   
            self.model.stop_training = True

train_0_dir = os.path.join(train_dir, '0')  
train_1_dir = os.path.join(train_dir, '1')
train_2_dir = os.path.join(train_dir, '2')  
train_3_dir = os.path.join(train_dir, '3')  
train_4_dir = os.path.join(train_dir, '4')  
train_5_dir = os.path.join(train_dir, '5')  
validation_0_dir = os.path.join(validation_dir, '0')  
validation_1_dir = os.path.join(validation_dir, '1')  
validation_2_dir = os.path.join(validation_dir, '2')  
validation_3_dir = os.path.join(validation_dir, '3')  
validation_4_dir = os.path.join(validation_dir, '4')  
validation_5_dir = os.path.join(validation_dir, '5')  


num_0_tr = len(os.listdir(train_0_dir))
num_1_tr = len(os.listdir(train_1_dir))
num_2_tr = len(os.listdir(train_2_dir))
num_3_tr = len(os.listdir(train_3_dir))
num_4_tr = len(os.listdir(train_4_dir))
num_5_tr = len(os.listdir(train_5_dir))

num_0_val = len(os.listdir(validation_0_dir))
num_1_val = len(os.listdir(validation_1_dir))
num_2_val = len(os.listdir(validation_2_dir))
num_3_val = len(os.listdir(validation_3_dir))
num_4_val = len(os.listdir(validation_4_dir))
num_5_val = len(os.listdir(validation_5_dir))

total_train = num_0_tr + num_1_tr + num_2_tr + num_3_tr + num_4_tr + num_5_tr
total_val = num_0_val + num_1_val + num_2_val + num_3_val + num_4_val + num_5_val

batch_size = 32
epochs = 20
IMG_HEIGHT = 128
IMG_WIDTH = 128
callbacks = myCallback()
CLASS_NAMES = ['0','1','2','3','4','5']

train_image_generator = ImageDataGenerator(rescale=1./255, zoom_range=0.25, horizontal_flip=True, height_shift_range=.15, rotation_range=75, brightness_range=(0.25,0.9)) # Generator for our training data
validation_image_generator = ImageDataGenerator(rescale=1./255) # Generator for our validation data

train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                           directory=train_dir,
                                                           color_mode='grayscale',
                                                           shuffle=True,
                                                           target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                           classes = list(CLASS_NAMES))

val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size,
                                                              directory=validation_dir,
                                                              color_mode='grayscale',
                                                              target_size=(IMG_HEIGHT, IMG_WIDTH),                                                              
                                                              classes = list(CLASS_NAMES))


model = Sequential([
    Conv2D(16, 3, activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH ,1)), #(W-F)/S +1 (128-3)/1 + 1 = 126  (32, 126, 126)
    Conv2D(16, 3, activation='relu'), #(32, 124, 124)
    MaxPooling2D(), #(32, 62. 62)
    Conv2D(32, 3, activation='relu'), #   (64, 60, 60)
    Conv2D(32, 3, activation='relu'), #   (64, 58, 58)
    MaxPooling2D(),   #   (64, 26, 26)
    Conv2D(64, 3, activation='relu'), #   (128, 24, 24)
    Conv2D(64, 3, activation='relu'), #   (128, 22, 22)
    MaxPooling2D(),   #   (128, 11, 11)
    Conv2D(128, 3, activation='relu'), #   (256, 9, 9)
    Conv2D(128, 3, activation='relu'), #   (256, 7, 7)
    MaxPooling2D(),   #   (256, 3, 3)
    Flatten(),
    Dense(1152, activation='relu'),
    Dropout(0.3),
    Dense(1152, activation='relu'),
    Dropout(0.3),
    Dense(6, activation='softmax')

])

opt = keras.optimizers.Adam(learning_rate=0.0001)
model.compile(optimizer=opt,
              loss='categorical_crossentropy',
              metrics=['accuracy'])


model.summary()

history = model.fit(
    train_data_gen,
    steps_per_epoch=total_train // batch_size,
    epochs=epochs,
    validation_data=val_data_gen,
    validation_steps=total_val // batch_size,
    callbacks= callbacks,
    verbose=1
)

model.save('saved_model/ModelMix')
model.save('Modelmix.h5') 

И для прогноза:

image_to_predict = cv2.imread('./image054.png')

image_to_predict = cv2.cvtColor(image_to_predict, cv2.COLOR_BGR2GRAY)
image_to_predict = image_to_predict.reshape(1, 128, 128, 1)
print(image_to_predict.shape)

prediction = model.predict(image_to_precit)

print(prediction)

Ну, когда я это сделаю model.predict (image_to_predict), и я распечатываю результат, результат, который мне возвращается, следующий:

[[0. 0. 0. 1. 0. 0.]]

Результат правильный, обнаруженный класс является ожидаемым, но это не то, что я хотеть. Мне нужно было бы получить результат, который вернул бы мне процент уверенности, с которой был сделан выбор, например:

[[0.02 0.04 0.10 0.72 0.08 0.04]]

Но я не могу найти ни одной функции, которая дает мне уверенность в том, что оценка. У кого-нибудь есть идеи, как я могу это сделать?

...