我使用tensorflow进行图像分类,适用于5个类别(5个汽车部件)。在100个时期的训练之后,在预测期间,当我测试图像(其甚至看起来不像我训练的任何类别的图像)时,它与那5个类别中的一个匹配,得分超过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)
答案 0 :(得分:1)
好吧,因为你没有为那个类别训练。这是神经网络(以及一些其他ML技术)一直存在的问题,模型对看不见的输入类别(在分类的情况下)的响应不是偶数概率分布"默认情况下" ,但有些不可预测,并且经常对其中一个类(可能是最常见的一个,但不一定是)有强烈的反应。如果你考虑一下,你所有的训练样例都属于100%的单一课程,所以模型倾向于给出答案,分数集中在一个类别中。我用another answer to a similar question写了几个替代方案来模拟一个"非另一个"上课,你可以查阅更多关于这个主题的文献。如果它们更适合您的需求,您还可以查看其他类型的模型,例如object detection API。关键是你不能指望你的模型展示出没有明确训练过的行为。
答案 1 :(得分:0)
您仅在5个班级训练您的模型。所以你的模型就像一个婴儿,他认为世界上只有五个物体,并试图将任何物体与其中一个物体联系起来:它认为是最相似的物体。
一个解决方案是在6个班级而不是5个班级训练你的模型,其中第6个班级是"未知"包含世界上任何其他对象的类(除了五个类)。
您可以轻松收集第6课的训练数据(它可以是除了其他5个班级之外的任何图像)并训练您的模型。