with tutorial software machine learning example machine-learning deep-learning keras

machine-learning - tutorial - tensorflow



ResNet: 100% de precisión durante el entrenamiento, pero 33% de precisión de predicción con los mismos datos (2)

Soy nuevo en el aprendizaje automático y el aprendizaje profundo, y con fines de aprendizaje intenté jugar con Resnet. Traté de sobreajustar datos pequeños (3 imágenes diferentes ) y ver si puedo obtener casi 0 pérdidas y 1,0 de precisión, y lo hice.

El problema es que las predicciones en las imágenes de entrenamiento (es decir, las mismas 3 imágenes utilizadas para el entrenamiento) no son correctas.

Imágenes de entrenamiento

Etiquetas de imagen

[1,0,0] , [0,1,0] , [0,0,1]

Mi código de python

#loading 3 images and resizing them imgs = np.array([np.array(Image.open("./Images/train/" + fname) .resize((197, 197), Image.ANTIALIAS)) for fname in os.listdir("./Images/train/")]).reshape(-1,197,197,1) # creating labels y = np.array([[1,0,0],[0,1,0],[0,0,1]]) # create resnet model model = ResNet50(input_shape=(197, 197,1),classes=3,weights=None) # compile & fit model model.compile(loss=''categorical_crossentropy'', optimizer=''adam'',metrics=[''acc'']) model.fit(imgs,y,epochs=5,shuffle=True) # predict on training data print(model.predict(imgs))

El modelo sobreajusta los datos:

3/3 [==============================] - 22s - loss: 1.3229 - acc: 0.0000e+00 Epoch 2/5 3/3 [==============================] - 0s - loss: 0.1474 - acc: 1.0000 Epoch 3/5 3/3 [==============================] - 0s - loss: 0.0057 - acc: 1.0000 Epoch 4/5 3/3 [==============================] - 0s - loss: 0.0107 - acc: 1.0000 Epoch 5/5 3/3 [==============================] - 0s - loss: 1.3815e-04 - acc: 1.0000

pero las predicciones son:

[[ 1.05677405e-08 9.99999642e-01 3.95520459e-07] [ 1.11955103e-08 9.99999642e-01 4.14905685e-07] [ 1.02637095e-07 9.99997497e-01 2.43751242e-06]]

lo que significa que todas las imágenes tienen label=[0,1,0]

¿por qué? y como puede suceder eso?


Lo que sucede es básicamente que keras.fit () es decir, su

model.fit()

mientras se tiene el mejor ajuste, se pierde la precisión. Como la precisión se pierde, el ajuste de los modelos da problemas y resultados variados. Keras.fit solo tiene un buen ajuste, no la precisión requerida


Se debe a las capas de normalización por lotes.

En la fase de entrenamiento, el lote se normaliza con su media y varianza. Sin embargo, en la fase de prueba, el lote se normaliza con el promedio móvil de la media y la varianza previamente observadas.

Ahora, este es un problema cuando el número de lotes observados es pequeño (por ejemplo, 5 en su ejemplo) porque en la capa BatchNormalization , por defecto, moving_mean se inicializa en 0 y moving_variance se inicializa en 1.

Dado que el momentum predeterminado es 0,99, deberá actualizar los promedios móviles muchas veces antes de que converjan en la media y la varianza "real".

Es por eso que la predicción es incorrecta en la etapa inicial, pero es correcta después de 1000 épocas.

Puede verificarlo obligando a las capas de BatchNormalization a operar en "modo de entrenamiento".

Durante el entrenamiento, la precisión es 1 y la pérdida es cercana a cero:

model.fit(imgs,y,epochs=5,shuffle=True) Epoch 1/5 3/3 [==============================] - 19s 6s/step - loss: 1.4624 - acc: 0.3333 Epoch 2/5 3/3 [==============================] - 0s 63ms/step - loss: 0.6051 - acc: 0.6667 Epoch 3/5 3/3 [==============================] - 0s 57ms/step - loss: 0.2168 - acc: 1.0000 Epoch 4/5 3/3 [==============================] - 0s 56ms/step - loss: 1.1921e-07 - acc: 1.0000 Epoch 5/5 3/3 [==============================] - 0s 53ms/step - loss: 1.1921e-07 - acc: 1.0000

Ahora, si evaluamos el modelo, observaremos una alta pérdida y una baja precisión porque después de 5 actualizaciones, los promedios móviles todavía están bastante cerca de los valores iniciales:

model.evaluate(imgs,y) 3/3 [==============================] - 3s 890ms/step [10.745396614074707, 0.3333333432674408]

Sin embargo, si especificamos manualmente la variable "fase de aprendizaje" y dejamos que las capas de BatchNormalization usen la media y la varianza del lote "real", el resultado será el mismo que el observado en fit() .

sample_weights = np.ones(3) learning_phase = 1 # 1 means "training" ins = [imgs, y, sample_weights, learning_phase] model.test_function(ins) [1.192093e-07, 1.0]

También es posible verificarlo cambiando el impulso a un valor menor.

Por ejemplo, al agregar momentum=0.01 a todas las capas de normas de lote en ResNet50 , la predicción después de 20 épocas es:

model.predict(imgs) array([[ 1.00000000e+00, 1.34882026e-08, 3.92139575e-22], [ 0.00000000e+00, 1.00000000e+00, 0.00000000e+00], [ 8.70998792e-06, 5.31159838e-10, 9.99991298e-01]], dtype=float32)