【问题标题】:Why do I get high prediction score for an image of untrained category?为什么我对未经训练的类别的图像获得高预测分数?
【发布时间】:2018-10-26 12:59:22
【问题描述】:

我使用 tensorflow 进行图像分类,用于 5 个类别(5 个汽车零件)。在训练了 100 个 epoch 之后,在预测期间,当我测试一张图像(它甚至看起来不像我训练的任何图像类别)时,它与得分超过 98% 的 5 个类别中的一个匹配。 (我每个类别有 1200 个训练图像) (例如,我用轮子、镜子、车门、转向、前照灯训练了我的模型。我的测试图像是百合花。我的输出是 99% 的轮子)为什么? 参考我代码中的参数。

def imagerecog(features,labels,mode,params):
input_layer = features["images"]
assert input_layer.shape[1:] == params['input_shape']
convs = []
pools = []
for i in range(params["conv_layers"]):
    if i == 0:
        convs.append(tf.layers.conv2d(inputs=input_layer,filters=params['filters'][i],
                                      kernel_size=params['kernel_size'],strides=[1,1],
                                      activation=tf.nn.relu,padding="same",name = "conv%d"%i))
    else:
        convs.append(tf.layers.conv2d(inputs=pools[i-1],filters=params['filters'][i],
                                      kernel_size=params['kernel_size'],strides=[1,1],
                                      activation=tf.nn.relu,padding="same",name = "conv%d"%i))
    pools.append(tf.layers.max_pooling2d(inputs=convs[i], pool_size=[2,2], strides=[2,2]))
flat = tf.layers.flatten(pools[-1])
dense1 = tf.layers.dense(inputs=flat, units=params["hidden_units"], name="dense1", activation=tf.nn.relu)
dropout = tf.layers.dropout(inputs=dense1, rate=params["drop_rate"] ,training=mode==tf.estimator.ModeKeys.TRAIN,
                            name="dropout")
logits = tf.layers.dense(inputs=dropout, units=params["n_classes"], name="logits")
probs = tf.nn.sigmoid(logits, name="probs")
top_5_scores, top_5_class = tf.nn.top_k(probs,  k=2, name="scores")

if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions={"classes":top_5_class, "scores": top_5_scores})

loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

if mode == tf.estimator.ModeKeys.EVAL:
    acc = tf.metrics.accuracy(labels=labels,predictions=top_5_class[:,0])
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops={"accuracy": acc})

opt = tf.train.AdamOptimizer().minimize(loss, global_step=tf.train.get_global_step())

return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=opt)

def inp_fn(folder,image_size):
classes = os.listdir(folder)
def fn():
    images = []
    labels = []
    for i,cls in enumerate(classes):
        imgs = os.listdir(folder+"/"+cls)
        print(cls,i)
        for img in imgs:
            img = tf.image.decode_jpeg(tf.read_file(folder+"/"+cls+"/"+img),3,name="jpeg_decode")
            img = tf.image.rgb_to_grayscale(img)
            img = tf.image.resize_images(img,image_size)
            images.append(img)
            labels.append(i)
    return tf.data.Dataset.from_tensor_slices(({"images":images},labels)).batch(100)
return fn


params = {"input_shape":[200,300,1],
      "conv_layers": 3,
      "filters":[20,20,20],
      "kernel_size":[5,5],
      "hidden_units": 9000,
      "drop_rate":0.4,
      "n_classes":5}

epoch=100
for a in range(epoch):
print("Epoch=",a)
estim.train(inp_fn("train",params['input_shape'][:-1]))


def pred_inp_fn(folder,image_size):
def fn():
    files = os.listdir(folder)
    images = []
    for file in files:
        img = tf.image.decode_jpeg(tf.read_file(folder+"/"+file),3)
        img = tf.image.rgb_to_grayscale(img)
        img = tf.image.resize_images(img,image_size)
        images.append(img)
        return tf.data.Dataset.from_tensor_slices({"images":images}).batch(100)
return fn


results = estim.predict(pred_inp_fn("predict",params['input_shape'][:-1]))


for res in results:
print(res)

【问题讨论】:

    标签: tensorflow deep-learning conv-neural-network image-recognition convolutional-neural-network


    【解决方案1】:

    好吧,因为您没有针对该类别进行培训。这是神经网络(和其他一些 ML 技术)一直存在的问题,模型对看不见的输入类别(在分类的情况下)的响应不是“默认”的均匀概率分布,而是不可预测的,并且经常对其中一类(可能是最常见的一类,但不一定)产生强烈反应。如果你仔细想想,你所有的训练样例都 100% 属于一个类,所以模型会倾向于给出分数集中在一个类中的答案。我写了another answer to a similar question 有几个替代方案来模拟“非其他”类,您可能可以查找更多关于该主题的文献。如果它们更适合您的需求,您还可以查看其他类型的模型,例如 object detection API。关键是你不能期望你的模型表现出没有明确训练过的行为。

    【讨论】:

      【解决方案2】:

      您仅在 5 个类上训练了您的模型。所以你的模型就像一个婴儿,他认为世界上只有五个物体,并试图将任何事物与其中一个物体联系起来:它认为最相似的那个物体。

      一种解决方案是在 6 个类而不是 5 个类上训练您的模型,其中第 6 个类是“未知”类,其中包括世界上的任何其他对象(五个类除外)。

      您可以轻松地收集第 6 类的训练数据(它可以是除其他 5 类之外的任何图像)并训练您的模型。

      【讨论】:

        猜你喜欢
        • 2016-06-14
        • 2020-01-24
        • 2017-08-29
        • 2016-07-23
        • 2021-04-03
        • 1970-01-01
        • 1970-01-01
        • 2019-06-19
        • 2018-11-03
        相关资源
        最近更新 更多