我正在为二进制图像分类构建TensorFlow模型。我有两个标签:“好”和“坏” 我希望模型应该为数据集中的每个图像输出图像,无论该图像是好是坏,并且以什么概率
例如,如果我提交1.jpg并假设它是“好”图像。然后,模型应预测1.jpg的概率为100%,好,概率为0%,则不好。
到目前为止,我已经能够提出以下建议
start = "2020-08-02T00:00:00Z";
month = moment(start).format("MMMM");
console.log(month) // <- August
上述模型的输出形状为1 x1。但是我认为这不会达到我的目的。
我正在以这种方式编译模型
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')
])
非常感谢您的帮助。
答案 0 :(得分:1)
您不必使模型输出“好”和“差”作为标签,而是可以分别输出每个概率,换句话说,图像的概率为图像不好。使最后一层的输出大小为2。因此,您的模型现在将输出一个二维矢量,使得[1.0,0.0]表示100%良好和0%不良,而[0.0,1.0]表示0%良好和100%糟糕。使用二元交叉熵作为训练的损失函数。当然,您必须类似地标记训练数据,因此,如果您有一个好的训练示例,则将其标记为[1.0,0.0],因为您100%确信它是好的,而如果您有一个不良的训练示例,则将其标记为[1.0,0.0] [0.0,1.0],因为您也100%确信这是一个不好的例子。
我告诉您使用二元交叉熵作为损失函数的原因是,该模型将学习输出2维矢量输出分量的相反概率。因此,如果图像质量好,则第一个成分会变高,第二个成分会变低,反之亦然。另外,经过训练后,进行预测时,您只会采用两者中的最高概率,如果较高的概率是第一个,则它是“好”图像,并且您仅使用该概率。
答案 1 :(得分:1)
万一有人在寻找答案,下面是用于模型生成的python代码
这里要注意的一些要点是
请注意#2,#3和#4,即使我试图提出二进制图像分类模型。我的最终目标是将该模型转换为TensorFlow Lite版本,并在Android应用程序中使用TensorFlow Lite模型。
更早之前,当我在最后一层使用“ Sigmoid”并将“ binary_crossentropy”用作损失函数时,最后一层的输出形状不能大于1。
结果是,当我在Android应用程序中使用从该TensorFlow模型生成的Lite模型时,出现了下面提到的错误
“找不到要标记的轴。要标记的有效轴应具有尺寸 大于1“
通过#2,#3和#4中提到的更改,生成的Lite模型可以在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)