Как просмотреть ярлыки классов после одного горячего кодирования во время обучения / тестирования и после предсказания в керасе - PullRequest
0 голосов
/ 26 марта 2020
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from keras.applications.vgg16 import decode_predictions
from imutils import paths
from pathlib import path
import numpy as np
import argparse
import cv2
import os


imagePaths = list(paths.list_images('D:/keras-cat-dog/dataset'))
data = []
labels = []


for imagePath in imagePaths:
  # extract the class label from the filename
    label = imagePath.split(os.path.sep)[-2]

# load the image, swap color channels, and resize it to be a fixed
# 224x224 pixels while ignoring aspect ratio
image = cv2.imread(imagePath)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.resize(image, (224, 224))

# update the data and labels lists, respectively
data.append(image)
labels.append(label)


# convert the data and labels to NumPy arrays while scaling the pixel
# intensities to the range [0, 255]
data = np.array(data) / 255.0
labels = np.array(labels)


# perform one-hot encoding on the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
labels = to_categorical(labels)

# partition the data into training and testing splits using 80% of
# the data for training and the remaining 20% for testing
(trainX, testX, trainY, testY) = train_test_split(data, labels,
test_size=0.20, stratify=labels, random_state=42)


# initialize the training data augmentation object
trainAug = ImageDataGenerator(
rotation_range=15,
fill_mode="nearest")


# load the VGG16 network, ensuring the head FC layer sets are left
# off
baseModel = VGG16(weights="imagenet", include_top=False,
input_tensor=Input(shape=(224, 224, 3)))


# construct the head of the model that will be placed on top of the
# the base model
headModel = baseModel.output
headModel = AveragePooling2D(pool_size=(4, 4))(headModel)
headModel = Flatten(name="flatten")(headModel)
headModel = Dense(64, activation="relu")(headModel)
headModel = Dropout(0.5)(headModel)
headModel = Dense(2, activation="softmax")(headModel)

# place the head FC model on top of the base model (this will become
# the actual model we will train)
model = Model(inputs=baseModel.input, outputs=headModel)

# loop over all layers in the base model and freeze them so they will
# *not* be updated during the first training process
for layer in baseModel.layers:
    layer.trainable = False

INIT_LR = 1e-3
EPOCHS = 25
BS = 8

# compile our model
print("[INFO] compiling model...")
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="binary_crossentropy", optimizer=opt,
    metrics=["accuracy"])


# train the head of the network
print("[INFO] training head...")
H = model.fit_generator(
    trainAug.flow(trainX, trainY, batch_size=BS),
    steps_per_epoch=len(trainX) // BS,
    validation_data=(testX, testY),
    validation_steps=len(testX) // BS,
    epochs=EPOCHS)


# make predictions on the testing set
print("[INFO] evaluating network...")
predIdxs = model.predict(testX, batch_size=BS)

# for each image in the testing set we need to find the index of the
# label with corresponding largest predicted probability
predIdxs = np.argmax(predIdxs, axis=1)



imagePath_1 = os.path.normpath('D:/Classification-master/data_two_class/test/cat/NORMAL2-IM- 
1396-0001.jpeg')
label_1=imagePath_1.split(os.sep)[-2]
image_pred = cv2.imread(imagePath)
image_pred = cv2.cvtColor(image_pred, cv2.COLOR_BGR2RGB)
img_pred = cv2.resize(image_pred, (224, 224))
img_pred = np.array(img_pred) / 255.0



rslt = model.predict(img_pred.reshape(1,224,224,3))
#decode_predictions(rslt)

Я использую приведенный выше код для классификации изображений с использованием керас и тензорного потока, но мне сложно разобраться с метками для прогноза, так как я сделал для них одно горячее кодирование, а теперь, когда я на самом деле предсказываю одну Изображение это показывает массив двух вероятностей. После использования функции argmax я получаю 0 или 1 и не могу понять, что это означает.

In [209]: rslt
Out[209]: array([[0.9550967 , 0.04490325]], dtype=float32)

rslt = np.argmax(rslt)
Out[219]: 0

Буду признателен, если кто-нибудь покажет способ, с помощью которого я могу увидеть, какая метка класса имеет значение «0» / «1» во время кодирования на этапе обработки данных и какие метки класса были присутствует во время проверки (testY) и метка класса изображения, когда я предсказываю одно изображение.

С уважением,

Subhra

1 Ответ

2 голосов
/ 26 марта 2020

Функция Softmax выводит числа, которые представляют вероятности, значение каждого числа находится в диапазоне от 0 до 1 допустимого диапазона значений вероятностей. Диапазон обозначается как [0,1]. Числа равны нулю или положительны. Весь выходной вектор соответствует сумме 1.

argmax Возвращает индексы максимальных значений вдоль оси.

Так что напечатайте свои этикетки и поймите что представляют собой ваш первый и второй индексы?

Поскольку вы использовали softmax в своем последнем слое, он дает вероятность того, что изображение принадлежит различным классам. В вашем случае это 2 класса, поэтому он показывает вероятность изображения, принадлежащего этим двум классам. Если вы суммируете свои вероятности 0,9550967 и 0,04490325, сумма будет равна 1.

0.9550967 + 0.04490325 = 1

np.argmax(rslt) возвращает индексы, имеющие максимальное значение.

Вот пример (1 ) - Распечатайте этикетки и поймите, что представляют собой первый и второй индексы -

import numpy as np
from sklearn.preprocessing import LabelBinarizer
from tensorflow.keras.utils import to_categorical

# define example
data = ['dog', 'dog', 'cat', 'dog', 'cat', 'cat', 'dog', 'cat', 'dog', 'dog']

values = np.array(data)

#Binary encode
lb = LabelBinarizer()

labels = lb.fit_transform(values)
labels = to_categorical(labels)
print("which position represents for cat and dog?:")
print("Data is:",data)
print(labels)

Вывод будет - Здесь первый индекс для кошки, а второй для собаки.

which position represents for cat and dog?:
Data is: ['dog', 'dog', 'cat', 'dog', 'cat', 'cat', 'dog', 'cat', 'dog', 'dog']
[[0. 1.]
 [0. 1.]
 [1. 0.]
 [0. 1.]
 [1. 0.]
 [1. 0.]
 [0. 1.]
 [1. 0.]
 [0. 1.]
 [0. 1.]]

Теперь давайте разберем argmax с вашими значениями softmax array([[0.9550967 , 0.04490325]]

Пример (2): Будет принимать ваш вывод softmax как это.

import numpy as np
rslt = np.array([[0.9550967,0.04490325]])
rslt = np.argmax(rslt)
print(rslt)

Выходные данные должны давать 0, поскольку первый индекс имеет более высокое значение. Таким образом, его Cat в соответствии с приведенным выше примером (1).

0

Пример (3): Поменяет ваш выход softmax.

import numpy as np
rslt = np.array([[0.04490325,0.9550967]])
rslt = np.argmax(rslt)
print(rslt)

Выходные данные должны давать 1, поскольку второй индекс имеет более высокое значение. То есть его Собака в соответствии с вышеприведенным примером (1).

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