【发布时间】:2018-04-15 12:13:39
【问题描述】:
我已经训练了一个 Keras 模型并将模型和权重保存到两个单独的文件中。我的训练数据和验证数据分为这样的两类:
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 对象在这里,因为我还保存了准确性和学习图。
现在,我试图让这个模型预测给定的测试样本中存在经过训练的两个类别中的哪一个。因此,我创建了模型,加载了权重并尝试运行预测。
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}
这里的格式不相关。我的观点是,如何获得已训练的每个班级的概率?我想我尝试使用所有的模型预测方法,但没有一个能满足我的需要。我在代码中做错了什么还是需要以某种不同的方式完成?
【问题讨论】:
-
1) 你提供了一堆不相关的信息(批量大小、数据集大小等),但你没有提供最基本的信息——你的模型到底是做什么的?二进制分类还是其他? 2) 忘记
for file in files和文件附加等(此处的代码应该是minimal),请发布singlemodel.predict()命令的结果 -
@desertnaut 这是二元分类(正/负),抱歉没有这么说,我发布了
predict结果列表,单个结果将是array([[ 0.]], dtype=float32) -
有几个可能的原因。旧版本的 Keras IIRC 区分了 predict_proba(预测概率)和 predict(用于类,即 0/1 预测)。新版本使用 predict/predict_classes,但也许您使用的是旧版本。所以尝试 predict_proba 而不是 predict。接下来,尝试在小批量上只运行一个 epoch,以检查您是否以某种方式过度训练,并且您的网络不只是收敛于零。最后,可能是您的输出类型错误,但快速查看二进制分类看起来不错。想知道你是怎么过的。
标签: machine-learning keras neural-network conv-neural-network prediction