如何使用我的分类网络检测多个对象?

问题描述 投票:3回答:1

我用keras创建了一个简单的卷积网络,其中包含了tensorflow。我训练了模型,准确性看起来不错。

我已经在10个不同的班级培训了网络。网络能够区分10个类中的每个类,精度为0.93

现在,很可能同一图像中有多个类。有没有办法可以使用我训练过的网络来检测同一图像中的多个对象?最好的方法是在检测到的对象周围获取坐标/边界框,以便更容易测试/可视化。

这是我写网络的方式:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.BatchNormalization(input_shape=x_train.shape[1:]))
model.add(tf.keras.layers.Conv2D(64, (5, 5), padding='same', activation='elu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2,2)))
model.add(tf.keras.layers.Dropout(0.25))

model.add(tf.keras.layers.BatchNormalization(input_shape=x_train.shape[1:]))
model.add(tf.keras.layers.Conv2D(128, (5, 5), padding='same', activation='elu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Dropout(0.25))

model.add(tf.keras.layers.BatchNormalization(input_shape=x_train.shape[1:]))
model.add(tf.keras.layers.Conv2D(256, (5, 5), padding='same', activation='elu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2,2)))
model.add(tf.keras.layers.Dropout(0.25))

model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(256))
model.add(tf.keras.layers.Activation('elu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(10))
model.add(tf.keras.layers.Activation('softmax'))

model.compile(
    optimizer=tf.train.AdamOptimizer(learning_rate=1e-3, ),
    loss=tf.keras.losses.sparse_categorical_crossentropy,
    metrics=['sparse_categorical_accuracy']
)

def train_gen(batch_size):
 while True:
    offset = np.random.randint(0, x_train.shape[0] - batch_size)
    yield x_train[offset:offset+batch_size], y_train[offset:offset + batch_size]


model.fit_generator(
    train_gen(512),
    epochs=15,
    steps_per_epoch=100,
    validation_data=(x_valid, y_valid)
)

这很好用。我如何使用这个网络来检测10个类中的多个对象?我会在某种程度上重新训练网络吗?

python tensorflow keras computer-vision conv-neural-network
1个回答
0
投票

为了教您的模型为每个图像检测多个类,您需要对模型和数据执行一些更改,然后重新训练它。

  • 您的最终激活现在需要是一个sigmoid,因为您不再预测单个类概率分布。现在,您希望每个输出神经元预测0到1之间的值,其中多个神经元可能具有接近1的值。
  • 您的损失函数现在应该是binary_crossentropy,因为您将每个输出神经元视为独立预测,您将与真实标签进行比较。
  • 我认为你一直在使用sparse_categorical_crossentropy,我认为你的标签是整数。您现在需要将标签编码更改为单热门样式,每个标签的len等于num_classes,并且仅在图像具有该类别的那些位置具有1,其余为0。

通过这些更改,您现在可以重新训练模型,以学习预测每个图像不止一个类。

至于预测对象周围的边界框,这是一个非常不同且更具挑战性的任务。诸如YOLO或CRNN等高级模型可以做到这一点,但它们的结构要复杂得多。

© www.soinside.com 2019 - 2024. All rights reserved.