【问题标题】:What is wrong with my neural networks prediction code? All predictions are returning the same class name for every image我的神经网络预测代码有什么问题?所有预测都为每个图像返回相同的类名
【发布时间】:2021-02-28 11:05:46
【问题描述】:

这是我的训练代码:

def train():


#START

img_input = layers.Input(shape=(150, 150, 3))

x = layers.Conv2D(16, 3, activation='relu')(img_input)
x = layers.MaxPooling2D(2)(x)

x = layers.Conv2D(32, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)

x = layers.Conv2D(64, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)

x = layers.Flatten()(x)
x = layers.Dense(512, activation='relu')(x)


output = layers.Dense(1, activation='sigmoid')(x)

model = Model(img_input, output)

model.compile(loss='binary_crossentropy',
          optimizer=RMSprop(lr=0.001),
          metrics=['acc'])
 
#END

# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)
bs = 20
# Flow training images in batches of 20 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
        train_dir,  # This is the source directory for training images
        target_size=(150, 150),  # All images will be resized to 150x150
        batch_size=bs,
        # Since we use binary_crossentropy loss, we need binary labels
        class_mode='binary')

# Flow validation images in batches of 20 using val_datagen generator
validation_generator = val_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=bs,
        class_mode='binary')
        

  history = model.fit(
  train_generator,
  steps_per_epoch=train_steps, 
  epochs=4,
  validation_data=validation_generator,
  validation_steps=val_steps,  
  verbose=1)     
  
  
  
model.save_weights("trained_weights.h5")

这是我的预测代码:

def evaluate(imgpath):
if not os.path.isfile(imgpath):
    print("No such file: {}".format(imgpath))
    sys.exit(-1)


# START
img_input = layers.Input(shape=(150, 150, 3))


x = layers.Conv2D(16, 3, activation='relu')(img_input)
x = layers.MaxPooling2D(2)(x)

x = layers.Conv2D(32, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)

x = layers.Conv2D(64, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)


x = layers.Flatten()(x)
x = layers.Dense(512, activation='relu')(x)

output = layers.Dense(1, activation='sigmoid')(x)

model = Model(img_input, output)

model.compile(loss='binary_crossentropy',
          optimizer=RMSprop(lr=0.001),
          metrics=['acc'])
 
# END

model.load_weights("trained_weights.h5")

img = image.load_img(path=imgpath,grayscale=False,target_size=(150,150),color_mode='rgb')
img_arr = image.img_to_array(img)
test_img = np.expand_dims(img_arr, axis=0)
y_prob = model.predict(test_img)


classname = y_prob.argmax(axis=-1)
print("Class: ",classname)
return classname  

我感觉错误出现在评估函数的最后 5-6 行,我正在加载图像。 问题是每当我对任何图像运行评估函数时,我的输出都是 [0]。尽管训练进行得很顺利,如下图所示。
enter image description here

我是不是在某个地方犯了一些愚蠢的错误?

【问题讨论】:

  • 你的错误在classname = y_prob.argmax(axis=-1)。我认为,that 应该回答你的问题。
  • 还有一个问题是您没有对新图像进行规范化,请参阅您在生成器中使用的 rescale=1.0/255.0。
  • test_img = np.expand_dims(img_arr, axis=0)/255

标签: tensorflow keras neural-network


【解决方案1】:

因为你有一个神经元作为顶层,所以当你做预测时,你会得到一个预测。由于您使用 argmax 进行单个预测将始终返回 0。例如,您需要为预测设置阈值

if yprob>=.5:
    klass=1 
else:
    klass=0

正如 Snoopy 博士所指出的,您应该将图像重新缩放 1/255。

【讨论】:

  • 好吧,我忘记了 argmax 返回索引而不是值。但是,当我打印 y_prob 时,结果始终是 [[1.]] 或 [[0.]] 并且从来没有介于两者之间,即使我考虑了一些与我的分类模型无关的随机图片。 “您应该将图像重新缩放 1/255”- 在 predict() 函数中?我在哪里做这个?
猜你喜欢
  • 1970-01-01
  • 2017-09-01
  • 2015-07-05
  • 2021-11-08
  • 1970-01-01
  • 2019-01-06
  • 2013-05-12
  • 2020-12-17
  • 1970-01-01
相关资源
最近更新 更多