模型训练后的 Keras 预测
Keras prediction after the model is trained
我训练了一个 Keras 模型并将模型和权重保存到两个单独的文件中。我的训练数据和验证数据分为两个 class 像这样:
training_data/
positive/
negative
validation_data/
positive/
negative/
两个训练数据目录各包含 900k 个样本,验证数据目录各包含 20k 个样本。所有样本都是43x43px.
我的模型和学习过程是这样定义的:
def get_model(img_width, img_height):
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(img_width, img_height, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
return model
model = get_model(43, 43)
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
history = model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size)
model.save(os.path.join('model.h5'))
model.save_weights(os.path.join('weights.h5'))
save_model_info(params)
20 个 epoch、1024 个批量、1.800.000 个训练样本和 40.000 个验证样本的训练过程耗时约 5 小时。 history
对象在这里是因为我也在保存准确率和学习图。
现在,我试图让这个模型预测在给定的测试样本中存在两个经过训练的 classed 中的哪一个。因此,我创建了模型,加载了权重并尝试 运行 预测。
model = get_model(43, 43)
model.load_weights(args.weights_file)
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])
result = []
files = os.listdir(input_dir)
for file in files:
image = load_img(file)
image = np.asarray(image)
image = np.expand_dims(image, axis=0)
result.append(model.predict(image))
print(result)
它正在运行,但不是我想要的方式。输出是这样的:
[array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32)]
这是我的问题。我需要它为每个给定的文件做出像
这样的预测
{'negative': 0.925, 'positive': 0.0725}
格式与此处无关。我的观点是,如何获得每个 class 已训练的概率?我想我尝试使用所有模型预测方法,但其中 none 给了我我需要的东西。我是在代码中做错了什么还是需要以某种不同的方式完成?
让我尝试提供一种方法,既可以追查问题的根本原因,也可以让 SO 的受访者更轻松地帮助您...
首先,正如我在评论中所说,SO 中的代码应该是 minimal,即足以重现问题;由于我们无权访问您的数据,因此根本没有必要包含您的 training_generator
、validation_generator
、目录结构或 [...] 等详细信息,这些信息对受访者和只是分散注意力(它们只有在您使用公开可用的数据集(如 MNIST 或 CIFAR)的情况下才有用):
Minimal
The more code there is to go through, the less likely people can find
your problem.
可以说,同样的原则也适用于问题中的 text...
其次,尝试预测一些您知道的精选样本是阳性(我假设0是您的阴性),即应该给出接近 1 的输出;据我所知,根据您提供的信息,可能没有任何问题,只是您尝试过的(少数)测试样本恰好给出概率 0(负)- 可能不太可能,但并非不可能, 你最好明确检查一下。
澄清最后一点:由于你的最后一层只有一个节点,你的输出将是 [0,1] 中的 单个 数字,这通常是要采取的作为你的 类 之一的概率 p
(另一个的概率在二进制分类中只是 1-p
);所以,至少你输出的格式一点都不奇怪。
第三,尝试在保存模型之前做出一些预测,因为已经报告了模型保存和加载(google)的几个问题,并比较他们从加载的模型中获得相同的预测;如果存在差异,则说明您已经大大缩小了对原因的搜索范围。
希望这对您有所帮助;希望 如果 确实有问题,按照这些步骤将帮助您自己解决问题,或者将它缩小到一个特定的点,您可以打开一个新的,更集中的在这里提问。在这种情况下,遵循 How to create a Minimal, Complete, and Verifiable example 上的 SO 指南将显着提高您从某人那里获得有用答案的机会...
我设法解决了这个问题,它正在运行。问题是我在训练模型时在 ImageGenerator 中添加了 rescale
参数:
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2)
而且我在运行宁预测时没有添加这个:
for file in files:
image = load_img(file)
image = np.asarray(image)
image = np.expand_dims(image, axis=0)
result.append(model.predict(image))
我改这条线
image = np.expand_dims(image, axis=0)
现在看起来像这样
img = np.expand_dims(img / 255, axis=0)
我还更新了加载模型,更改了那里的行(但只是为了预测,而不是训练):
model = get_model(43, 43)
model.load_weights(args.weights_file)
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])
进入这个:
model = load_model(args.model_file)
我 运行 用我的所有样本进行预测,并用结果填充一个 numpy 数组,然后将该数组更改为图像,它就可以工作了。感谢大家的帮助,再次对代码量感到抱歉。
我训练了一个 Keras 模型并将模型和权重保存到两个单独的文件中。我的训练数据和验证数据分为两个 class 像这样:
training_data/
positive/
negative
validation_data/
positive/
negative/
两个训练数据目录各包含 900k 个样本,验证数据目录各包含 20k 个样本。所有样本都是43x43px.
我的模型和学习过程是这样定义的:
def get_model(img_width, img_height):
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(img_width, img_height, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
return model
model = get_model(43, 43)
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
history = model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size)
model.save(os.path.join('model.h5'))
model.save_weights(os.path.join('weights.h5'))
save_model_info(params)
20 个 epoch、1024 个批量、1.800.000 个训练样本和 40.000 个验证样本的训练过程耗时约 5 小时。 history
对象在这里是因为我也在保存准确率和学习图。
现在,我试图让这个模型预测在给定的测试样本中存在两个经过训练的 classed 中的哪一个。因此,我创建了模型,加载了权重并尝试 运行 预测。
model = get_model(43, 43)
model.load_weights(args.weights_file)
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])
result = []
files = os.listdir(input_dir)
for file in files:
image = load_img(file)
image = np.asarray(image)
image = np.expand_dims(image, axis=0)
result.append(model.predict(image))
print(result)
它正在运行,但不是我想要的方式。输出是这样的:
[array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32)]
这是我的问题。我需要它为每个给定的文件做出像
这样的预测{'negative': 0.925, 'positive': 0.0725}
格式与此处无关。我的观点是,如何获得每个 class 已训练的概率?我想我尝试使用所有模型预测方法,但其中 none 给了我我需要的东西。我是在代码中做错了什么还是需要以某种不同的方式完成?
让我尝试提供一种方法,既可以追查问题的根本原因,也可以让 SO 的受访者更轻松地帮助您...
首先,正如我在评论中所说,SO 中的代码应该是 minimal,即足以重现问题;由于我们无权访问您的数据,因此根本没有必要包含您的 training_generator
、validation_generator
、目录结构或 [...] 等详细信息,这些信息对受访者和只是分散注意力(它们只有在您使用公开可用的数据集(如 MNIST 或 CIFAR)的情况下才有用):
Minimal
The more code there is to go through, the less likely people can find your problem.
可以说,同样的原则也适用于问题中的 text...
其次,尝试预测一些您知道的精选样本是阳性(我假设0是您的阴性),即应该给出接近 1 的输出;据我所知,根据您提供的信息,可能没有任何问题,只是您尝试过的(少数)测试样本恰好给出概率 0(负)- 可能不太可能,但并非不可能, 你最好明确检查一下。
澄清最后一点:由于你的最后一层只有一个节点,你的输出将是 [0,1] 中的 单个 数字,这通常是要采取的作为你的 类 之一的概率 p
(另一个的概率在二进制分类中只是 1-p
);所以,至少你输出的格式一点都不奇怪。
第三,尝试在保存模型之前做出一些预测,因为已经报告了模型保存和加载(google)的几个问题,并比较他们从加载的模型中获得相同的预测;如果存在差异,则说明您已经大大缩小了对原因的搜索范围。
希望这对您有所帮助;希望 如果 确实有问题,按照这些步骤将帮助您自己解决问题,或者将它缩小到一个特定的点,您可以打开一个新的,更集中的在这里提问。在这种情况下,遵循 How to create a Minimal, Complete, and Verifiable example 上的 SO 指南将显着提高您从某人那里获得有用答案的机会...
我设法解决了这个问题,它正在运行。问题是我在训练模型时在 ImageGenerator 中添加了 rescale
参数:
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2)
而且我在运行宁预测时没有添加这个:
for file in files:
image = load_img(file)
image = np.asarray(image)
image = np.expand_dims(image, axis=0)
result.append(model.predict(image))
我改这条线
image = np.expand_dims(image, axis=0)
现在看起来像这样
img = np.expand_dims(img / 255, axis=0)
我还更新了加载模型,更改了那里的行(但只是为了预测,而不是训练):
model = get_model(43, 43)
model.load_weights(args.weights_file)
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])
进入这个:
model = load_model(args.model_file)
我 运行 用我的所有样本进行预测,并用结果填充一个 numpy 数组,然后将该数组更改为图像,它就可以工作了。感谢大家的帮助,再次对代码量感到抱歉。