不,您必须完全匹配相同的输入形状。
您的模型代码(model = Sequential([... 行)应与您保存的模型完全对应,并且您的输入数据(y_pred = new_model.predict(X) 行中的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
而且您几乎可以肯定,您的 NN 在不同形状的输入上仍然会产生良好的结果。
然后你只需像这样在右边用额外的零填充第一个不匹配的图像:
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 数字的输入进行训练的 NN 对于 42 数据的任何填充都会给出完全错误的结果,那么唯一的方法是针对 42 输入重新训练您的 NN 并再次保存模型。
但是你必须考虑到 keras 库中的 input_shape = (44,) 实际上意味着输入到 model.predict(X) 的最终数据 X 应该是二维形状,如 (10, 44)(其中 10 是您的NN要识别的不同对象的数量),keras隐藏了第0维,即所谓的批量维。批次 (0-th) 维度实际上可以变化,您可以输入 5 个对象(即形状数组 (5, 44))或 7 个(形状 (7, 44))或任何其他数量的对象。批处理仅意味着 keras 在一次调用中并行处理多个对象,只是为了快速/高效。但是每个单个对象都是形状为(44,) 的一维子数组。可能您对数据如何馈送到网络和表示的方式有误解。 44 不是数据集的大小(对象数),它是单个对象的特征数,例如如果网络识别/分类一个人,那么 44 可能意味着只有一个人的 44 个特征,例如年龄、性别、身高、体重、出生月份、种族、肤色、每天的呼叫次数、月收入、月支出、薪水、等共 44 个不同的固定特征的 1 个人体对象。他们可能不会改变。但是,如果您获得的其他数据仅具有 42 或 36 特征,而您只需将 0 恰好放置在 44 中缺失的特征位置,则用零填充是不正确的在右侧或左侧,您必须将0s 准确地放置在44 中缺少的位置。
但是您的 44 和 42 和 36 可能意味着不同输入对象的数量,每个对象都只有 1 特征。想象一个任务,当你有一个 50 人类的数据集(表)只有两列数据 salary 和 country 然后你可能想要构建 NN 猜测 country 由 salary 然后你会有input_shape = (1,)(对应于 1 个数字的一维数组 - salary),但绝对不是 input_shape = (50,)(表中的人数)。 input_shape 仅表示 1 个物体的形状,1 个人类。 50 是对象(人)的数量,它是用于预测的 numpy 数组中的批次(第 0 个)维度,因此 model.predict(X) 的 X 数组的形状为 (50, 1),但 @987654371 @在模型中。基本上 keras 省略(隐藏)第 0 个批次维度。如果 44 在您的情况下实际上是指数据集大小(对象数),那么您错误地训练了 NN,应该使用 input_shape = (1,) 重新训练它,44 作为批处理维度,而这个 44 可能会有所不同关于训练或测试数据集的大小。
如果你要重新训练你的网络,那么整个训练/评估过程的简单形式如下:
-
假设您在 CSV 文件 data.csv 中有一个数据集。例如,您总共有 126 行和 17 列。
-
以某种方式读入您的数据,例如通过np.loadtxt 或pd.read_csv 或通过标准python 的csv.reader()。将数据转换为数字(浮点数)。
-
将您的数据按行随机分成两部分training/evaluation,大致对应行的大小90%/10%,例如110 行用于训练,16 行用于评估(总共 126 行)。
-
确定要预测数据中的哪些列,您可以预测任意数量的列,假设我们要预测两列,第 16 列和第 17 列。现在您的数据列分为两部分 X(15 列,编号 1-15)和 Y(2 列,编号 16-17)。
-
在您的网络层代码中,在第一层设置input_shape = (15,)(15 是X 中的列数),在最后一层设置Dense(2)(2 是Y 中的列数)。
-
使用model.fit(X, Y, epochs = 1000, ...) 方法在训练数据集上训练您的网络。
-
通过model.save(...)将训练好的网络保存到模型文件到net.h5这样的文件中。
-
通过model.load(...)加载您的网络。
-
通过predicted_Y = model.predict(testing_X)测试网络质量,与testing_Y比较,如果网络模型选择正确,那么testing_Y应该接近predicted_Y,例如80% 正确(这个比例叫做准确率)。
-
我们为什么要将数据集拆分为训练/测试部分。因为训练阶段只看到训练数据集子部分。网络训练的任务是很好地记住整个训练数据,并通过在X 和Y 之间找到一些隐藏的依赖关系来泛化预测。因此,如果在训练数据上调用model.predict(...) 应该接近100% 准确度,因为网络会看到所有这些训练数据并记住它。但是它根本看不到测试数据,因此需要聪明并真正通过 X 预测测试 Y,因此测试的准确性较低,例如80%.
-
如果测试结果的质量不是很好,你必须改进你的网络架构并从头开始重新运行整个训练过程。
-
如果您需要预测部分数据,例如当您的X 数据中只有 15 个可能的列中的 12 个时,然后用零填充缺失的列值,例如如果您缺少第 7 列和第 11 列,则在第 7 和第 11 位插入零。这样总列数又是 15。您的网络将仅支持在 model.predict() 的输入中与训练时使用的列数完全相同,即 15,此数字在 input_shape = (15,) 中提供。