为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用经过训练和保存的前馈神经网络来预测新数据

如何使用经过训练和保存的前馈神经网络来预测新数据

慕侠2389804 2023-09-12 17:26:59
我正在尝试使用经过训练和保存的模型对新数据进行预测。我的新数据与用于构建已保存模型的数据形状不同。我尝试过使用 model.save() 和 model.save_weights(),因为我仍然想保留训练配置,但它们都会产生相同的错误。即使形状不同,有没有办法在新数据上使用保存的模型?from tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Activation, Densemodel = Sequential([    Dense(units=11, activation='relu', input_shape = (42,), kernel_regularizer=keras.regularizers.l2(0.001)),    Dense(units=1, activation='sigmoid')])new_model.load_weights('Fin_weights.h5')y_pred = new_model.predict(X)ValueError: Error when checking input: expected dense_6_input to have shape (44,) but got array with shape (42,)
查看完整描述

1 回答

?
繁星淼淼

TA贡献1775条经验 获得超11个赞

不,您必须完全匹配相同的输入形状。


您的模型代码(model = Sequential([...行)应与您保存的模型完全对应,并且您的输入数据(X行y_pred = new_model.predict(X))应与保存的模型()中的形状相同'Fin_weights.h5'。


您唯一能做的就是以某种方式用例如零填充新数据。但只有当其余值对应相同的特征或信号时,这才有帮助。


例如,假设您正在训练 NN 来识别形状 (2, 3) 的灰度图像,如下所示:


1 2 3

4 5 6

然后您训练了模型并将其保存以供以后使用。之后,您决定将神经网络用于更小或更大尺寸的图像,如下所示


1 2

3 4

或这个


1  2  3  4

5  6  7  8

9 10 11 12

而且您几乎可以肯定,您的神经网络仍然会在不同形状的输入上给出良好的结果。


然后,您只需在右侧填充第一个不匹配的图像,并在右侧添加额外的零,如下所示:


1 2 0

3 4 0

或另一种填充方式,在左侧


0 1 2

0 3 4

第二张图片你剪了一点


1  2  3

5  6  7

(或从另一边剪掉)。


只有这样,您才能将神经网络应用到经过处理的输入图像。


与您的情况相同,您必须添加两个零。但仅限于编码输入信号或特征的序列几乎相同的情况。


如果您的预测数据大小错误,请执行以下操作:


y_pred = new_model.predict(

    np.pad(X, ((0, 0), (0, 2)))

)

这会在右侧填充您的数据的两个零,尽管您可能希望将其填充在左侧((2, 0)而不是(0, 2))或两侧((1, 1)而不是(0, 2))。


如果您保存的权重具有不同的形状,则模型的代码会在模型代码中执行此操作(更改42 --> 44):


model = Sequential([

    Dense(units=11, activation='relu', input_shape = (44,), kernel_regularizer=keras.regularizers.l2(0.001)),

    Dense(units=1, activation='sigmoid')

])

您可能应该执行上述两件事,以匹配您保存的模型/权重。


如果针对44数字输入训练的神经网络对于任何数据填充都会给出完全错误的结果42,那么唯一的方法是重新训练神经网络的42输入并再次保存模型。


但是你必须考虑到这样一个事实,input_shape = (44,)在 keras 库中实际上意味着X输入的最终数据model.predict(X)应该是二维形状(10, 44)(其中 10 是你的神经网络要识别的不同对象的数量),keras 隐藏第 0 维,即所谓的批量维度。批次(第 0 个)维度实际上可能会有所不同,您可以提供 5 个对象(即 shape 数组(5, 44))或 7 个对象(形状 (7, 44))或任何其他数量的对象。批处理仅意味着 keras 在一次调用中并行处理多个对象,只是为了快速/高效。但每个单个对象都是形状的一维子数组(44,)。您可能误解了数据如何输入网络并表示的一些内容。44 不是数据集的大小(对象数量),而是单个对象的特征数量,例如,如果网络识别/分类一个人,那么 44 可以表示一个人的 44 个特征,例如年龄、性别、身高、体重,出生月份,种族,肤色,每天卡路里,月收入,月支出,工资等总共1个人类对象的44个不同的固定特征。他们可能不会改变。但是,如果您获得了一些仅具有42或36特征的其他数据,而您只需要0精确地将其放置在 中缺少的特征位置44,则在右侧或左侧填充零是不正确的,您必须放置0s 正好位于 中缺失的那些位置44。


但是你的 44 和 42 和 36 可能意味着不同输入对象的数量,每个对象都只有1特征。想象一个任务,当你有一个50只有两列数据的人类数据集(表) salary,country然后你可能想要构建猜测country到salary那时你将拥有的神经网络input_shape = (1,)(对应于 1 个数字的一维数组 - salary),但绝对是不是input_shape = (50,)(表中的人数)。input_shape只讲述 1 个物体、1 个人的形状。50 是对象(人类)的数量,它是 numpy 数组中用于预测的批量(第 0 个)维度,因此您的X数组model.predict(X)的形状为(50, 1),但input_shape = (1,)在模型中。基本上 keras 省略(隐藏)第 0 个批次维度。如果44在您的情况下,实际上意味着数据集大小(对象数量),那么您错误地训练了 NN,应该使用 ,input_shape = (1,)作为44批量维度进行重新训练,这44可能会根据训练或测试数据集的大小而有所不同。

如果您要重新训练您的网络,那么整个训练/评估过程的简单形式如下:

  1. 假设您有一个 CSV 文件格式的数据集data.csv。例如,总共有 126 行和 17 列。

  2. 以某种方式读入您的数据,例如通过np.loadtxt或通过pd.read_csv或通过标准 python 的csv.reader()。将数据转换为数字(浮点数)。

  3. 按行将数据随机分成两部分training/evaluation大约相应的大小90%/10%行,例如 110 行用于训练,16 行用于评估(总共 126 行)。

  4. 决定将预测数据中的哪些列,您可以预测任意数量的列,假设我们要预测两列,即第 16 列和第 17 列。现在,您的数据列被分为两部分X(15 列,编号为 1-15)和Y(2 列,编号为 16-17)。

  5. 在网络层的代码中,第一层设置input_shape = (15,)(15 是 中的列数X),Dense(2)最后一层(2 是 中的列数Y)。

  6. 使用model.fit(X, Y, epochs = 1000, ...)方法在训练数据集上训练网络。

  7. 将经过训练的网络保存到模型文件model.save(...)net.h5.

  8. 通过 加载您的网络model.load(...)

  9. 通过 测试网络质量predicted_Y = model.predict(testing_X),与 进行比较testing_Y,如果网络模型选择正确,则testing_Y应该接近predicted_Y,例如80%正确(这个比率称为准确性)。

  10. 为什么我们将数据集分成训练/测试部分。因为训练阶段只看到训练数据集子部分。网络训练的任务是很好地记住整个训练数据,并通过找到X和之间的一些隐藏依赖关系来概括预测Y。因此,如果调用model.predict(...)训练数据,应该给出接近的100%准确性,因为网络会看到所有这些训练数据并记住它。但测试数据它根本看不到,因此需要聪明并真正预测通过 X 测试 Y,因此测试的准确性较低,例如80%

  11. 如果测试结果的质量不好,您必须改进网络架构并从头开始重新运行整个训练过程。

  12. 如果您需要预测部分数据,例如,当您的X数据中只有 15 列中的 12 列时,则用零填充缺失的列值,例如,如果您缺少第 7 列和第 11 列,则将零插入到第 7 列和第 11 位。这样总列数又是 15。您的网络将仅支持 model.predict() 的输入,即训练时使用的列数,即 15,该数字在 中提供input_shape = (15,)


查看完整回答
反对 回复 2023-09-12
  • 1 回答
  • 0 关注
  • 57 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信