Почему я получаю высокий балл прогноза для изображения неподготовленной категории? - PullRequest
0 голосов
/ 16 мая 2018

Я использую тензор потока для классификации изображений, для 5 категорий (5 автозапчастей). После обучения в течение 100 эпох, во время предсказания, когда я тестировал изображение (которое даже не похоже ни на одну из моих обученных категорий изображений), оно соответствует одной из этих пяти категорий с показателем более 98%. (у меня есть 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)

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Вы тренировали свою модель только в 5 классах.Таким образом, ваша модель похожа на ребенка, который думает, что в мире всего пять объектов и пытается связать что-либо с одним из этих объектов: тот, который он считает наиболее похожим.

Одним из решений было бытренируйте свою модель на 6 классах вместо 5, где 6-й класс - это «неизвестный» класс, который включает в себя любой другой объект в мире (кроме пяти классов).

Вы можете легко собрать данные обучения для 6-го класса (это может быть изображение чего угодно, кроме 5 других классов) и обучить свою модель.

0 голосов
/ 16 мая 2018

Ну, потому что вы не тренировались для этой категории.Это постоянная проблема с нейронными сетями (и некоторыми другими методами ML), реакция модели на невидимые классы входных данных (в случае классификации) - это не равномерное распределение вероятностей «по умолчанию», а что-то непредсказуемое,и часто сильный ответ для одного из классов (возможно, самый частый, но не обязательно).Если вы подумаете об этом, все ваши учебные примеры на 100% принадлежат одному классу, поэтому модель будет давать ответы с оценкой, сосредоточенной в одной категории.Я написал еще один ответ на похожий вопрос с парой альтернатив для моделирования класса "не от других", и вы, вероятно, можете найти больше литературы по этой теме.Вы также можете посмотреть на другие виды моделей, например API обнаружения объектов , если они лучше соответствуют вашим потребностям.Дело в том, что вы не можете ожидать, что ваша модель будет демонстрировать поведение, для которого она не была специально обучена.

...