Даже изображение в наборе данных, используемом для обучения, дает противоположные значения при прогнозировании - PullRequest
0 голосов
/ 08 ноября 2019

Я новичок в ML и TensorFlow. Я пытаюсь создать CNN, чтобы классифицировать хорошее изображение по отношению к искаженным изображениям, подобно учебным пособиям по ножницам из каменной бумаги в тензорном потоке, за исключением только двух категорий.

Блокнот Colab

Архитектура модели

train_generator = training_datagen.flow_from_directory(
    TRAINING_DIR,
    target_size=(150,150),
    class_mode='categorical'
)

validation_generator = validation_datagen.flow_from_directory(
    VALIDATION_DIR,
    target_size=(150,150),
    class_mode='categorical'
)

model = tf.keras.models.Sequential([
    # Note the input shape is the desired size of the image 150x150 with 3 bytes color
    # This is the first convolution
    tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(150, 150, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    # The second convolution
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # The third convolution
    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # The fourth convolution
    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # Flatten the results to feed into a DNN
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.5),
    # 512 neuron hidden layer
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(2, activation='softmax')
])


model.summary()

model.compile(loss = 'categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

history = model.fit_generator(train_generator, epochs=25, validation_data = validation_generator, verbose = 1)

model.save("rps.h5")

Единственное изменение, которое я сделал, превратило форму ввода в (150,150,1) в (150,150,3) и изменило последние слоивывод на 2 нейрона с 3 . Обучение давало мне постоянную точность 90 выше для набора данных 600 изображений в каждом классе. Но когда я делаю прогноз с использованием кода в учебнике, он дает мне очень неправильные значения даже для данных в наборе данных.

PREDICTION

Исходный код в учебнике TensorFlow

for file in onlyfiles:
  path = fn
  img = image.load_img(path, target_size=(150, 150,3)) # changed target_size to (150, 150,3)) from (150,150 )
  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)

  images = np.vstack([x])
  classes = model.predict(images, batch_size=10)
  print(fn)
  print(classes)

Я изменил target_size на (150, 150,3)) с (150,150), полагая, что мой вход является трехканальным изображением,

Результат

Это дает очень неправильные значения [0,1] [0,1] для четных изображений, в которых находятся в наборе данных

Но когда я изменил код на этот

 for file in onlyfiles:
  path = fn
  img = image.load_img(path, target_size=(150, 150,3))
  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)
  x /= 255.   
  classes = model.predict(images, batch_size=10)
  print(fn)
  print(classes)

В этом случае значения приходят как

    [[9.9999774e-01 2.2242968e-06]]
    [[9.9999785e-01 2.1864464e-06]]
    [[9.9999785e-01 2.1641024e-06]]

есть одна или две ошибки, но они очень правильные

Так что мой вопрос, хотя последнийАктивация - это softmax, почему она теперь идет в десятичных значениях, есть ли логическая ошибка в том, как я делаю предсказания? Я также попробовал двоичный файл, но не смог найти особой разницы.

Ответы [ 2 ]

0 голосов
/ 11 ноября 2019

Обратите внимание -

  1. Когда вы меняете выходные классы с 2 на 3, вы просите модель разделить на 3 класса. Это противоречило бы вашей постановке задачи, которая разделяет хорошие и испорченные, то есть 2 выходных класса (двоичная проблема). Я думаю, что это можно поменять с 3 на 2, если я правильно понял вопрос.
  2. Во-вторых, полученный вами результат совершенно правильный, модели нейронной сети выводят вероятности вместо абсолютных значений класса, таких как 0 или 1. По вероятности, он говорит, насколько вероятно, что он относится к классу 0 или классу 1.
  3. Также, как упомянуто выше @BBloggsbott - вам просто нужно использовать np.argmax в выходном массиве, который сообщит вам вероятностьпринадлежность к классу 1 (положительный класс) по умолчанию. Надеюсь это поможет. Спасибо.
0 голосов
/ 08 ноября 2019

Softmax возвращает распределения вероятностей для вектора, который он получает в качестве входных данных. Таким образом, тот факт, что вы получаете десятичные значения, не является проблемой. Если вы хотите найти точный класс, к которому относится каждое изображение, попробуйте использовать в прогнозах функцию argmax.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...