首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模型训练后的Keras预测

模型训练后的Keras预测
EN

Stack Overflow用户
提问于 2017-11-02 20:43:59
回答 2查看 1.3K关注 0票数 1

我训练了一个Keras模型,并将模型和权重保存到两个单独的文件中。我的培训数据和验证数据分为以下两个类:

代码语言:javascript
复制
training_data/
    positive/
    negative
validation_data/
    positive/
    negative/

两个培训数据目录每个包含900 k样本,验证数据目录每个包含20k样本。所有样品均为43x43px。

我的模型和学习过程定义如下:

代码语言:javascript
复制
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次,批量1024次,训练样本1.800.000次,验证样本40.000次,耗时约5h。history对象在这里,因为我还保存了准确性和学习图表。

现在,我试图让这个模型预测在给定的测试样本中,训练的两个类别中哪一个是存在的。因此,我创建了模型,加载权重,并试图运行预测。

代码语言:javascript
复制
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)

它正在起作用,但不是我所希望的那样。输出如下:

代码语言:javascript
复制
[array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32)]

这是我的问题。我需要它为每个给定的文件做预测,如

代码语言:javascript
复制
{'negative': 0.925, 'positive': 0.0725}

这种格式在这里不相关。我想说的是,如何才能得到每一堂课被训练过的概率?我想我试过使用所有的模型预测方法,但它们都没有给我所需要的。我是在代码中做错了什么,还是需要做一些不同的事情?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-03 13:03:53

让我试着提供一种方法,既可以找出问题的根源,也可以让这里的被访者更容易地帮助你……

首先,正如我在评论中所说的那样,SO中的代码应该是minimal,也就是足以重现问题的代码;由于我们无法访问您的数据,所以根本没有必要包括您的training_generatorvalidation_generator、目录结构或.等细节,因为这些细节对应答者毫无用处,只会分散注意力(只有在您使用公开可用的数据集(如MNIST或CIFAR)时,它们才可能有用):

极小 代码越多,就越不可能找到您的问题

可以说,同样的原则也适用于问题中的案文.

第二,尝试预测一些你知道是阳性的手工挑选的样本(我假设0是你的负数),也就是说,这应该给出接近1的输出;据我所知,根据你提供的信息,可能没有什么问题,只是你尝试过的(少数几个)测试样本碰巧给出了概率0(负)--可能不太可能,但也不是不可能,你最好清楚地检查一下。

澄清最后一点:由于最后一层只有一个节点,所以输出将是0,1中的单个数字,通常被视为一个类的概率p (另一个类的概率仅为二进制分类中的1-p );因此,至少输出的格式一点也不奇怪。

第三,在保存模型之前尝试做一些预测,因为在模型保存和加载(google it)中已经报告了几个问题,并将它们与加载模型中的相同预测进行比较;如果存在差异,您已经大大缩小了对原因的搜索范围。

希望这会有所帮助;希望如果确实有什么问题,遵循这些步骤将有助于您自己解决问题,或者将问题缩小到一个特定的点,您可以在这里提出一个新的、更有重点的问题。在这种情况下,遵循关于How to create a Minimal, Complete, and Verifiable example的SO准则将大大提高您从某人那里得到有用答案的可能性。

票数 0
EN

Stack Overflow用户

发布于 2017-11-15 19:24:19

我设法解决了这个问题,它正在起作用。问题是,在训练模型时,我在ImageGenerator中添加了ImageGenerator参数:

代码语言:javascript
复制
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)

在运行预测时,我没有添加这一点:

代码语言:javascript
复制
for file in files:
    image = load_img(file)
    image = np.asarray(image)
    image = np.expand_dims(image, axis=0)
    result.append(model.predict(image))

我改变了这一行

代码语言:javascript
复制
image = np.expand_dims(image, axis=0)

现在它看起来像这样

代码语言:javascript
复制
img = np.expand_dims(img / 255, axis=0)

我还更新了加载模型,在那里更改了行(但只是为了预测,而不是训练):

代码语言:javascript
复制
model = get_model(43, 43)
model.load_weights(args.weights_file)
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
          metrics=['accuracy'])

这方面:

代码语言:javascript
复制
model = load_model(args.model_file)

我用我所有的样本运行预测,并用结果填充一个numpy数组,然后将该数组更改为图像,它就可以工作了。谢谢大家的帮助,再次为代码的数量感到抱歉。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47084316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档