El modelo convertido de OpenVino no devuelve los mismos valores de puntuación que el modelo original (Sigmoid)
He convertido un modelo de Keras para usarlo con OpenVino. El modelo Keras original usaba sigmoide para devolver puntajes que iban de 0 a 1 para la clasificación binaria. Después de convertir el modelo para su uso con OpenVino, los puntajes están todos cerca de 0,99 para ambas clases, pero parecen ligeramente más bajos para una de las clases.
Por ejemplo, test1.jpg y test2.jpg (de clases opuestas) arrojan puntuaciones de 0,00320357 y 0,9999, respectivamente.
Con OpenVino, las mismas imágenes arrojan puntuaciones de 0,9998982 y 0,9962392, respectivamente.
Editar* Una sospecha es que el modelo de OpenVino todavía acepta la matriz de entrada, pero de alguna manera cambia de forma o está "codificado" y, por lo tanto, nunca es compatible con la clase uno. En otras palabras, si lo alimentara con ruido aleatorio, la puntuación también sería siempre 0,9999. ¿Tal vez tendría que hacer que el modelo OpenVino aceptara la forma original (1,180,180,3) en lugar de (1,3,180,180) para no tener que forzar la entrada en una forma diferente a la que aceptó el modelo original? Sin embargo, eso es extraño porque especifiqué la forma al crear el xml y el contenedor para openvino:
python3 /opt/intel/openvino_2021/deployment_tools/model_optimizer/mo_tf.py --saved_model_dir /Users/.../Desktop/.../model13 --output_dir /Users/.../Desktop/... --input_shape=\[1,180,180,3]
Sin embargo, sé por mensajes de error que el motor de inferencia espera (1,3,180,180) por alguna razón desconocida. ¿Podría ser el problema? La otra sospecha es que algo anda mal con la forma en que se congeló el modelo original. Estoy explorando diferentes formas de congelar el modelo original (modelo keras convertido a pb) en caso de que el problema esté relacionado con eso.
Revisé para asegurarme de que la función de activación de Sigmoid se usa en la implementación de OpenVino (la misma activación que el modelo de Keras) y parece que sí. ¿Por qué, entonces, los valores no son los mismos? Cualquier ayuda sería muy apreciada.
El código para la inferencia de OpenVino es:
import openvino
from openvino.inference_engine import IECore, IENetwork
from skimage import io
import sys
import numpy as np
import os
def loadNetwork(model_xml, model_bin):
ie = IECore()
network = ie.read_network(model=model_xml, weights=model_bin)
input_placeholder_key = list(network.input_info)[0]
input_placeholder = network.input_info[input_placeholder_key]
output_placeholder_key = list(network.outputs)[0]
output_placeholder = network.outputs[output_placeholder_key]
return network, input_placeholder_key, output_placeholder_key
batch_size = 1
channels = 3
IMG_HEIGHT = 180
IMG_WIDTH = 180
#loadNetwork('saved_model.xml','saved_model.bin')
image_path = 'test.jpg'
def load_source(path_to_image):
image = io.imread(path_to_image)
img = np.resize(image,(180,180))
return img
img_new = load_source('test2.jpg')
#Batch?
def classify(image):
device = 'CPU'
network, input_placeholder_key, output_placeholder_key = loadNetwork('saved_model.xml','saved_model.bin')
ie = IECore()
exec_net = ie.load_network(network=network, device_name=device)
res = exec_net.infer(inputs={input_placeholder_key: image})
print(res)
res = res[output_placeholder_key]
return res
result = classify(img_new)
print(result)
result = result[0]
top_result = np.argmax(result)
print(top_result)
print(result[top_result])
Y el resultado:
{'StatefulPartitionedCall/model/dense/Sigmoid': array([[0.9962392]], dtype=float32)}
[[0.9962392]]
0
0.9962392
Mostrar la mejor respuesta