繁体   English   中英

TensorFlow 二值图像分类:预测数据集中每个图像的每个 class 的概率

[英]TensorFlow Binary Image Classification: Predict Probability of each class for each image in data set

我正在构建一个 TensorFlow model 用于二进制图像分类。 我有两个“好”和“坏”标签

例如,如果我提交 1.jpg 并假设它是“好”图像。 那么 model 应该以 100% 的概率预测 1.jpg 是好的,以 0% 的概率预测是坏的。

到目前为止,我已经能够想出以下

model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(input_shape, input_shape, 3)),
  tf.keras.layers.MaxPool2D(2,2),
  #
  tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
  tf.keras.layers.MaxPool2D(2,2),
  #
  tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
  tf.keras.layers.MaxPool2D(2,2),
  ##
  tf.keras.layers.Flatten(),
  ##
  tf.keras.layers.Dense(512, activation='relu'),
  ##
  tf.keras.layers.Dense(1, activation='sigmoid')
])

上面 model 的 output 的形状是 1 x 1。但我认为这不符合我的目的。

我正在以这种方式编译 model

 model.compile(loss='binary_crossentropy',
          optimizer=RMSprop(lr=0.001),
          metrics=['accuracy'])
 model_fit = model.fit(train_dataset,
                  steps_per_epoch=3,
                  epochs=30,
                  validation_data=validation_dataset)

任何帮助是极大的赞赏。

您不必将 model output“好”和“坏”作为标签,相反,您可以 output 的概率是每个图像的坏图像的概率,并且每个图像的概率是坏图像的概率, . Make the size of the output of your last layer to be 2. So your model will now output a 2-dimensional vector such that [1.0, 0.0] means 100% good and 0% bad and [0.0, 1.0] means 0% good和100%的坏。 使用二元交叉熵作为损失 function 进行训练。 当然,你必须 label 你的训练数据类似,所以如果你有一个很好的训练示例,label 它为 [1.0, 0.0] 因为你 100% 确定它是好的,如果你有一个不好的训练示例 ZD431ZBA20E96DABAE78 [0.0, 1.0] 因为您也 100% 确定这是一个坏例子。

The reason I told you to use binary-cross entropy as a loss function is so that the model will learn to output opposing probabilities for the components of the 2-d vector output. 因此,如果它是一个好的图像,第一个分量会很高,而第二个分量会很低,反之亦然,如果它是一个坏图像。 另外,在训练之后,在进行预测时,你只取两者中最高的概率,如果更高的概率是第一个,那么它就是一个“好”的图像,你只使用那个概率。

如果有人正在寻找答案,下面是 model 生成的 python 代码

这里需要注意的一些要点是

  1. 输入图像形状为 360x360x3
  2. 最后一层的激活 Function 是“ softmax ”而不是“ sigmoid
  3. 损失 function 是“ sparse_categorical_crossentropy ”而不是“ binary_crossentropy
  4. output 的形状是 2 而不是 1

请注意 #2、#3 和 #4,即使我正在尝试提出用于二进制图像分类的 model。 My ultimate aim was to convert this model to TensorFlow Lite version and use TensorFlow Lite model in Android Application.

早些时候,当我对最后一层使用“sigmoid”并使用“binary_crossentropy”作为损失 function 时,最后一层的 output 形状不能大于 1。

As a result when I was using the Lite model generated out of that TensorFlow Model in Android application, I was getting an error which is mentioned below

“找不到 label 的轴。label 的有效轴的大小应大于 1”

通过 #2、#3 和 #4 中提到的更改,生成的 Lite Model 在 Android 中运行良好。

import tensorflow as tf
import matplotlib.pyplot as plt
import cv2
import os
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing import image
from tensorflow.keras.optimizers import RMSprop


print("version")
print(tf.__version__)

train = ImageDataGenerator(rescale=1/255)
validation = ImageDataGenerator(rescale=1/255)

input_shape = 360
train_dataset = train.flow_from_directory('container_images/train/',
                                          target_size=(input_shape,input_shape),
                                          batch_size=3,
                                          classes=['good', 'bad'],
                                          class_mode='binary')

validation_dataset = train.flow_from_directory('container_images/validation/',
                                          target_size=(input_shape,input_shape),
                                          batch_size=3,
                                          classes=['good', 'bad'],
                                          class_mode='binary')

print(train_dataset.class_indices)
model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(input_shape, input_shape, 3)),
    tf.keras.layers.MaxPool2D(2,2),
    #
    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    tf.keras.layers.MaxPool2D(2,2),
    #
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPool2D(2,2),
    ##
    tf.keras.layers.Flatten(),
    ##
    tf.keras.layers.Dense(512, activation='relu'),
    ##
    tf.keras.layers.Dense(2, activation='softmax')
])

model.compile(loss='sparse_categorical_crossentropy',
              optimizer=RMSprop(lr=0.001),
              metrics=['accuracy'])
model_fit = model.fit(train_dataset,
                      steps_per_epoch=3,
                      epochs=30,
                      validation_data=validation_dataset)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM