如何在 training/testing 期间和在 keras 中进行预测后的一次热编码后查看 class 标签

How to view class labels after one hot encoding during training/testing and after the prediction in keras

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)

我正在使用上面的代码使用 keras 和 tensorflow classify 图像,但是我很难理解预测的标签,因为我已经对它们进行了一次热编码,现在我正在实际上预测单个图像它显示了两个概率的数组。使用 argmax 函数后,我得到 0 或 1,无法理解它的含义。

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

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

如果有人可以展示一种方法,我可以看到在数据处理阶段的编码过程中哪个 class 标签将变为“0”/“1”,哪个 [=22] =] 标签在验证 (testY) 期间出现,并且当我预测单个图像时图像的 class 标签出现。

此致,

苏布拉

Softmax函数输出代表概率的数字,每个数字的值都在概率的有效值范围0到1之间。范围表示为 [0,1] 。数字为零或正数。 整个输出向量总和为 1。

argmax Returns 沿轴的最大值索引。

所以打印你的标签并了解你的第一个和第二个索引代表什么?

由于您在最后一层使用了 softmax,它给出了图像属于不同 类 的概率。在您的情况下,它是 2 类,因此它显示图像属于这两个 类 的概率。如果将概率 0.9550967 和 0.04490325 相加,则总和为 1。

0.9550967 + 0.04490325 = 1

np.argmax(rslt) returns 具有最大值的指数。

这是一个例子 (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.]]

现在让我们用你的 softmax array([[0.9550967 , 0.04490325]]

来理解 argmax

示例 (2): 将按原样采用您的 softmax 输出。

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

输出应为 0,因为第一个索引具有更高的值。 所以它的猫按照上面的例子(1)。

0

示例 (3): 将交换您的 softmax 输出。

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

输出应为 1,因为第二个索引具有更高的值。 所以它的狗按照上面的例子(1)。

1