OpenCV - тренинги приводят к другому результату при использовании TrainData_create - PullRequest
0 голосов
/ 23 ноября 2018

Я использую MLP ANN, предоставляемый OpenCV 3.4 с python.Я заметил, что когда данные обучения подготавливаются с помощью cv2.ml.TrainData_create, ANN работает хорошо, в случае, если он не используется, но используются те же образцы и параметры, ANN обучается неправильно.

Здесь я не имею в виду тренировкиразличаются, даже если используются одни и те же данные (что можно ожидать из-за случайных начальных точек), потому что я вижу здесь неработающее обучение VS-тренировка, и это происходит всегда.

В следующем коде используется cv2.ml.TrainData_create

import cv2
import numpy as np

ann = cv2.ml.ANN_MLP_create()
ann.setTrainMethod(cv2.ml.ANN_MLP_BACKPROP)
ann.setActivationFunction(cv2.ml.ANN_MLP_SIGMOID_SYM)
ann.setLayerSizes(np.array([3, 8, 4]))
ann.setTermCriteria(( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 ))

input_array = np.array([ [1.0, 0.0, 0.0],
                         [0.0, 1.0, 0.0],
                         [0.0, 0.0, 1.0],
                         [1.0, 1.0, 1.0],
                         ], dtype=np.float32)

output_array = np.array([ [1.0, 0.0, 0.0, 0.0],
                          [0.0, 1.0, 0.0, 0.0],
                          [0.0, 0.0, 1.0, 0.0],
                          [0.0, 0.0, 0.0, 1.0],
                          ], dtype=np.float32)

td = cv2.ml.TrainData_create(input_array, cv2.ml.ROW_SAMPLE, output_array)
ann.train(td, cv2.ml.ANN_MLP_NO_INPUT_SCALE | cv2.ml.ANN_MLP_NO_OUTPUT_SCALE)

SAMPLES = 5000
for x in range(0, SAMPLES):
  ann.train(td, cv2.ml.ANN_MLP_UPDATE_WEIGHTS | cv2.ml.ANN_MLP_NO_INPUT_SCALE | cv2.ml.ANN_MLP_NO_OUTPUT_SCALE)

и это хорошо работает:

print(ann.predict(input_array))

(0.0, array([[ 1.0000000e+00,  0.0000000e+00,  4.7625793e-16,  2.8575474e-16],
       [ 1.9050316e-16,  10000000e+00,  5.7150949e-16,  9.5251581e-17],
       [ 9.5251581e-17,  0.0000000e+00,  1.0000000e+00, -1.9050316e-16],
       [-1.9050316e-16, -1.9050316e-16,  0.0000000e+00,  1.0000000e+00]],
      dtype=float32))

В следующем коде не используется cv2.ml.TrainData_create, но, очевидно, используются те же данные и параметры:

import cv2
import numpy as np

ann = cv2.ml.ANN_MLP_create()
ann.setTrainMethod(cv2.ml.ANN_MLP_BACKPROP | cv2.ml.ANN_MLP_UPDATE_WEIGHTS | cv2.ml.ANN_MLP_NO_INPUT_SCALE | cv2.ml.ANN_MLP_NO_OUTPUT_SCALE)
ann.setActivationFunction(cv2.ml.ANN_MLP_SIGMOID_SYM)
ann.setLayerSizes(np.array([3, 8, 4]))
ann.setTermCriteria(( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 ))

input_array = np.array([ [1.0, 0.0, 0.0],
                         [0.0, 1.0, 0.0],
                         [0.0, 0.0, 1.0],
                         [1.0, 1.0, 1.0],
                         ], dtype=np.float32)

output_array = np.array([ [1.0, 0.0, 0.0, 0.0],
                          [0.0, 1.0, 0.0, 0.0],
                          [0.0, 0.0, 1.0, 0.0],
                          [0.0, 0.0, 0.0, 1.0],
                          ], dtype=np.float32)

SAMPLES = 5000
for x in range(0, SAMPLES):
  ann.train(np.array([[1.0, 0.0, 0.0]], dtype=np.float32), cv2.ml.ROW_SAMPLE, np.array([[1.0, 0.0, 0.0, 0.0]], dtype=np.float32))
  ann.train(np.array([[0.0, 1.0, 0.0]], dtype=np.float32), cv2.ml.ROW_SAMPLE, np.array([[0.0, 1.0, 0.0, 0.0]], dtype=np.float32))
  ann.train(np.array([[0.0, 0.0, 1.0]], dtype=np.float32), cv2.ml.ROW_SAMPLE, np.array([[0.0, 0.0, 1.0, 0.0]], dtype=np.float32))
  ann.train(np.array([[1.0, 1.0, 1.0]], dtype=np.float32), cv2.ml.ROW_SAMPLE, np.array([[0.0, 0.0, 0.0, 1.0]], dtype=np.float32))

Но этот просто не работает:

print(ann.predict(input_array))

(0.0, array([[ 1.2886142 ,  0.51306236, -1.0352006 , -0.19007786],
       [ 1.2194023 ,  0.7686653 , -1.097198  , -0.03246666],
       [ 0.99483347,  0.40380374, -0.917998  ,  0.08949649],
       [ 0.7475754 ,  0.12770385, -0.81321925,  0.37416443]],
      dtype=float32))

Что не так со вторым фрагментом кода?

...