准确率高,预测效果差--CNN与TensorFlow Python的结合。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了准确率高,预测效果差--CNN与TensorFlow Python的结合。相关的知识,希望对你有一定的参考价值。
我正在尝试用TensorFlow创建一个二进制分类器,能够检测一个人是否戴着手术面具。问题是,我创建了一个训练数据集,其中包含2.2k张戴面具的人的剪裁脸和另外2.2k张不戴面具的人的剪裁脸(包括我的脸)。对CNN进行了100次训练(近24小时),准确率约为84.25%(val_acc)。但我的CNN仍然在大部分时间内预测错误!我已经尝试了超过100个时代(几乎24小时)的训练,准确率约为84.25%(val_acc)。我尝试了十几种CNN架构,甚至使用MobileNetV2进行转移学习,但结果还是很糟糕。我是不是做错了什么?
我的部分训练代码是:。
IMG_SIZE = 200 # Dimensões das imagens
batch_size = 50 # Quantidade de dados que serão alimentados à NN de uma só vez
epochs = 100 # Quantidade de vezes que os dados de treinamento serão passados à NN
training_data = []
### PREPARA DADOS COM AUGMENTATION PARA ALIMENTAR A NN ###
#Cria Geradores de Dados - Augmentation = Zoom, Horizontal Flip, Rotate 45°
train_datagen = ImageDataGenerator(rescale=1.0 / 255.0,
shear_range= 0.2,
zoom_range= 0.2,
rotation_range= 45,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
fill_mode='nearest'
)
test_datagen = ImageDataGenerator(rescale=1.0 / 255.0)
# Prepara os Iteradores
train_it = train_datagen.flow_from_directory(directory=TRAIN_DIR,
class_mode='binary',
batch_size=batch_size,
target_size=(IMG_SIZE, IMG_SIZE)
)
test_it = test_datagen.flow_from_directory(directory=VALIDATION_DIR,
class_mode='binary',
batch_size=batch_size,
target_size=(IMG_SIZE, IMG_SIZE)
)
############################################
model = Sequential([
Conv2D(32, kernel_size=(3,3), padding='same', activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)),
Conv2D(32, kernel_size=(3,3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(2,2), strides=2),
Dropout(0.2),
Conv2D(64, kernel_size=(3,3), activation='relu'),
Conv2D(64, kernel_size=(3, 3), activation='relu'),
BatchNormalization(),
MaxPooling2D(pool_size=(2, 2), strides=2),
Dropout(0.3),
Flatten(),
Dense(256, activation='relu'),
BatchNormalization(),
Dropout(0.5),
Dense(1, activation='sigmoid')
])
############ COMPILA NOVA REDE NEURAL ############
lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(
initial_learning_rate= 0.0000001,
decay_steps= (total_val//batch_size)*1000,
decay_rate=1,
staircase= False
)
adam = Adam(learning_rate=lr_schedule) #adam = Adam(learning_rate=1.0e-6, decay= 1.0e-4 / epochs, epsilon=1)#acrescentado epsilon
model.compile(optimizer=adam,
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
##################################################
############ PERFORMS THE NN TRAINING ############
# fit model
history = model.fit(train_it,
steps_per_epoch=total_train // batch_size,
validation_data=test_it,
validation_steps=total_val // batch_size,
epochs=epochs,
callbacks=[checkpoint_callback],
shuffle=True,
)
还有评估代码
####################################################################
#### IMAGE ANALYSIS FUNC. RETURNS RESULT ON VAR result ####
def img_analysis(x, y, w, h):
for image_path in os.listdir(WEBCAM_TEST): # Itera entre as imagens contidas no diretório WEBCAM_TEST
load_path = os.path.join(WEBCAM_TEST, image_path) # Define a variavel 'load_path' como sendo o caminho do diretório 'WEBCAM_TEST' + o nome do arquivo
img = load_img(load_path, target_size=(IMG_SIZE, IMG_SIZE)) #Carrega imagem nas dimensões declaradas em IMG_SIZE
#img_preview = img
img = img_to_array(img) #Converte imagem em um array do NumPy
img = img.reshape(1, IMG_SIZE, IMG_SIZE, 3) #Redimensiona imagem
img = img.astype('float32') #Converte imagem para Float
result = model.predict(img) #Realiza previsão
return result, load_path
###########################################################################################
#### DRAWS A RECTANGLE ON THE DETECTED FACES WITH THE RESULT ####
def show_rectangle(result,load_path, x, y, w, h):
if result == 0:
#print('Mask NOK -', CATEGORIES[1])
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.putText(frame, 'SEM MASCARA',
org=(x, y - 10),
fontFace=cv2.FONT_HERSHEY_DUPLEX,
fontScale=0.5,
color=(0, 0, 255)
)
path = os.path.join(SAVED_IMG, 'MaskOff')
try:
shutil.copy(load_path, path)
except:
pass
if result == 1:
#print('Mask OK -', CATEGORIES[0])
cv2.rectangle(frame, (x, fy), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, 'COM MASCARA',
org=(x, y - 10),
fontFace=cv2.FONT_HERSHEY_DUPLEX,
fontScale=0.5,
color=(0, 255, 0)
)
path = os.path.join(SAVED_IMG, 'MaskOn')
try:
shutil.copy(load_path, path)
except:
pass
#############################################################################
################ WEBCAM CONFIG. ################
video = cv2.VideoCapture(0) # Cria objeto de captura da webcam
video.set(cv2.CAP_PROP_FRAME_WIDTH, 640) # 1366 Define largura do video
video.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # 760 Define altura do video
################ FACE DETECTION METHOD ################
face_cascade = cv2.CascadeClassifier(HOME_DIR + 'cascade/haarcascade_frontalface_default.xml') ###########################################################################
model = tf.keras.models.load_model(HOME_DIR + 'best_TL.hdf5')
while (True):
conectado, frame = video.read() # Método para leitura da webcam (conectado é variável booleana indicando conexão; e frame é o objeto de leitura da webcam)
frame = cv2.resize(frame, (640,480), fx=0, fy=0, interpolation=cv2.INTER_CUBIC) #Redimensiona a imagem da câmera
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Cria novo objeto a partir do objeto frame e converte as cores em escala de cinza
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=3) #Método para detecção do rosto
for (fx, fy, fw, fh) in faces: #Itera entre os itens da lista faces
fh = int(fh * 1.2) #Corrige altura do quadro
roi_face_color = frame[fy:fy + fh, fx:fx + fw] #Cria Region of Interest para o rosto
roi_colorQ.put(roi_face_color) #Coloca o frame do rosto na fila
img_ready = any(os.listdir(WEBCAM_TEST)) # Teste para verificar se há imagens para verificar
if img_ready == True:
result, load_path = img_analysis(fx, fy, fw, fh) # Chama função para análise da fotografia
show_rectangle(result, load_path, fx, fy, fw, fh) # Chama função para desenho do retângulo no rosto
print('The Result is: ', result)
cv2.imshow('MaskDetector - Thread - Press "q" to quit',frame) # Exibe imagem do objeto frame em uma janela chamada Video
if cv2.waitKey(1) == ord('q'): # Cria laço condicional para manter a janela aberta até que uma tecla seja pressionada, nesse caso 'q' - 0 para qualquer tecla, 1 para tecla específica
break # Fecha a janela
### MEMORY RELEASE AND END OF THE PROGRAM ###
video.release() # Libera a captura
cv2.destroyAllWindows() # Fecha a janela e libera a memória
答案
我想,我的Dataset是不合适的。我下载了数千张戴着手术面具的人的图片,他们我把这些图片通过人脸提取算法来建立一个只包含人脸的数据集。
但不幸的是,这个策略对我来说并不太行得通。即使我的准确率在85%左右,我的CNN仍然预测错了moust的时间。解决的办法是建立一个新的数据集,由4.4k张我自己的照片组成。我的准确率提高到了98.8%,预测也终于OK了,你可以看到这里。https:/www.youtube.comwatch?v=QM41tMJSrBE
另一答案
你似乎没有对数据进行标准化。建议你在训练和推理的过程中进行。
以上是关于准确率高,预测效果差--CNN与TensorFlow Python的结合。的主要内容,如果未能解决你的问题,请参考以下文章