如何使用经过训练和保存的前馈神经网络预测新数据 [英] How to predict on new data using a trained and saved Feedforward NN

查看:53
本文介绍了如何使用经过训练和保存的前馈神经网络预测新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用经过训练并保存的模型对新数据进行预测.我的新数据与用于构建保存的模型的数据的形状不同.

I am trying to make predictions on new data, using a trained and saved model. My new data does not have the same shape as the data used to build the saved model.

我尝试使用model.save()和model.save_weights(),因为我仍然想保留训练配置,但是它们都产生相同的错误.

I have tried using model.save() as well as model.save_weights(), as I still want to keep the training configurations, but they both produce the same error.

即使形状不同,有没有办法在新数据上使用保存的模型?

Is there a way to use ones saved model on new data even if the shape is not the same?

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Activation, Dense

model = 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,)

推荐答案

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

No, you have to exactly match same input shape.

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

Both your model's code (model = Sequential([... lines) should correspond exactly to your saved model and your input data (X in y_pred = new_model.predict(X) line) should be of same shape as in saved model ('Fin_weights.h5').

您唯一可以做的就是以某种方式填充新数据,例如零.但这仅在其余值对应于相同的功能或信号时才有帮助.

Only thing you can do is to somehow pad your new data with e.g. zeros. But this can help only if the rest of values correspond to same features or signals.

例如,假设您正在训练神经网络识别形状为 (2, 3) 的灰色图像,如下所示:

Lets for example imagine that you were training NN to recognize gray images of shape (2, 3), like below:

1 2 3
4 5 6

然后您训练模型并保存以备后用.之后,您决定要像这样在较小或较大尺寸的图像上使用NN

Then you trained model and saved it for later use. Afterwards you decided that you want to use your NN on images of smaller or bigger size, like this

1 2
3 4

或这个

1  2  3  4
5  6  7  8
9 10 11 12

而且您几乎可以确定,您的NN在形状不同的输​​入中仍然可以提供良好的结果.

And you're almost sure that your NN will still give good results on differently shaped input.

然后,您只需将第一个不匹配的图像填充在右侧,像这样:

Then you just pad first unmatching image with extra zeros on the right like this:

1 2 0
3 4 0

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

or another way of padding, on the left side

0 1 2
0 3 4

第二张图片剪了一点

1  2  3
5  6  7

(或从其他侧面切割).

(or cut it from other sides).

只有这样,您才能将NN应用于此已处理的输入图像.

Only then you can apply your NN to this processed input images.

与您的情况相同,您必须添加两个零.但是只有在编码输入信号或特征序列几乎相同的情况下.

Same in your case, you have to add two zeros. But only in case if it is almost same sequence of encoded input signals or features.

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

In case if your data for prediction is of wrong size, do this:

y_pred = new_model.predict(
    np.pad(X, ((0, 0), (0, 2)))
)

尽管您可能想在左侧填充两个零((2,0)而不是(0,2))或两侧((1,1)而不是(0,2)).

this pads your data with two zeros on right side, although you might want to pad it on left side ((2, 0) instead of (0, 2)), or on both sides ((1, 1) instead of (0, 2)).

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

In case if your saved weights are of different shape that model's code do this in code for model (change 42 --> 44):

model = Sequential([
    Dense(units=11, activation='relu', input_shape = (44,), kernel_regularizer=keras.regularizers.l2(0.001)),
    Dense(units=1, activation='sigmoid')
])

您可能应该同时执行上述两项操作,以匹配保存的模型/重量.

You should probably do both things above, to match your saved model/weights.

如果为输入 44 数字而训练的NN对 42 数据的任何填充都会给出完全错误的结果,那么唯一的方法是为 42重新训练您的NN> 42 输入并再次保存模型.

If NN trained for input of 44 numbers would give totally wrong results for any padding of 42 data then the only way is to re-train your NN for 42 input and save model again.

但是您必须考虑以下事实:keras库中的 input_shape =(44,)实际上意味着将最终数据 X 馈入model.predict(X)应该是二维形状,例如(10,44)(其中10是您的NN可以识别的不同对象的数量),keras隐藏0尺寸,即所谓的批量尺寸.批次(第0个)维度实际上可以变化,您可以喂入5个对象(即形状为(5,44)的数组)或7个对象(形状为(7,44)的数组)或任何其他数量的对象.批处理仅表示keras在一次调用中并行处理多个对象,只是为了快速/高效.但是每个对象都是形状为(44,)的一维子数组.您可能错过了有关如何将数据馈送到网络和表示数据的某些知识.44不是数据集的大小(对象数),而是单个对象的特征数,例如如果网络可以识别/分类一个人,则44可以表示一个人的44个特征,例如年龄,性别,身高,体重,出生月份,种族,肤色,每天的书法,每月收入,每月支出,工资,等共计1个人类对象的44种不同的固定特征.他们可能不会改变.但是,如果您得到的其他数据仅具有 42 36 特征,则仅需要将 0 准确地放置在缺失的特征位置的 44 ,在右边或左边用零填充是不正确的,您必须将 0 准确地放置在 44之外的那些位置.

But you have to take into account the fact that input_shape = (44,) in keras library actually means that the final data X that is fed into model.predict(X) should be of 2-dimensional shape like (10, 44) (where 10 is the number of different objects to be recognized by your NN), keras hides 0-th dimension, it is so-called batch dimension. Batch (0-th) dimension actually can vary, you may feed 5 objects (i.e. array of shape (5, 44)) or 7 (shape (7, 44)) or any other number of object. Batch only means that keras processes several object at one call in parallel, just to be fast/efficient. But each single object is 1-dimensional sub-array of shape (44,). Probably you miss-understood something in how data is fed to network and represented. 44 is not the size of dataset (number of objects), it is number of traits of single object, e.g. if network recognizes/categorizes one human, then 44 can mean 44 characteristics of just one human, like age, gender, height, weight, month of birth, race, color of skin, callories per day, monthly income, monthly spending, salary, etc totalling 44 different fixed characteristics of 1 human object. They probably don't change. But if you got some other data with just 42 or 36 characteristics than you need to place 0 only exactly in positions of characteristics that are missing out of 44, it won't be correct to pad with zeros on right or left, you must place 0s exactly in those positions that are missing out of 44.

但是您的44和42和36可能表示不同输入对象的数量,每个输入对象仅具有 1 个特征.想象一个任务,当您有一个数据集(表),该数据集是 50 个人的,只有两列数据 salary country 时,您可能想要构建NN通过 salary 猜测 country ,那么您将得到 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 可能因训练或测试数据集的大小而异.

But your 44 and 42 and 36 probably mean the number of different input object, each having just 1 characteristics. Imagine a task when you have a DataSet (table) of 50 humans with just two columns of data salary and country then you might want to build NN that guesses country by salary then you'll have input_shape = (1,) (corresponding to 1-D array of 1 number - salary), but definitely not input_shape = (50,) (number of humans in table). input_shape tells the shape of just 1 object, 1 human. 50 is the number of objects (humans), and it is the batch (0-th) dimension in numpy array which is fed for prediction, hence your X array for model.predict(X) is of shape (50, 1), but input_shape = (1,) in the model. Basically keras omits (hides) 0-th batch dimension. If 44 in your case actually meant DataSet size (number of objects) then you've trained NN wrongly and it should be retrained with input_shape = (1,), 44 goes as a batch dimension, and this 44 may vary depending on size of training or testing DataSets.

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

If you're going to re-train your network, then whole training/evaluation process in simple form is as follows:

  1. 假设您在CSV文件 data.csv 中拥有一个数据集.例如,您总共有 126 行和 17 列.

  1. Suppose you hav a dataset in CSV file data.csv. For example you have 126 rows and 17 columns there in total.

以某种方式读入您的数据,例如通过 np.loadtxt 或通过

Read-in your data somehow e.g. by np.loadtxt or by pd.read_csv or by standard python's csv.reader(). Convert data to numbers (floats).

将数据按行随机分为两部分,分别为 training / evaluation ,其大小分别为 90%/ 10%行,例如培训中共有110行,评估中有16行(总计126行).

Split your data by rows randomly into two parts training/evaluation approximately in corresponding sizes 90%/10% of rows, e.g. 110 rows for training and 16 for evaluation out of (126 in total).

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

Decide which columns in your data will be predicted, you can predict any number of columns, lets say we want to predict two columns, 16th and 17th. Now your columns of data are split into two parts X (15 columns, numbered 1-15) and Y (2 columns, numbered 16-17).

在您的网络层的代码中,将第一层设置为 input_shape =(15,)(15是 X 中的列数),然后将最后一层的密度(2)(2是 Y 中的列数).

In code of your network layers set input_shape = (15,) (15 is number of columns in X) in first layer, and Dense(2) in last layer (2 is number of columns in Y).

使用 model.fit(X,Y,纪元= 1000,...)方法.

将训练有素的网络通过 model.save(...)保存到模型文件,例如 net.h5 .

Save trained network to model file through model.save(...) to file like net.h5.

通过 model.load(...)加载网络.

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

Test network quality through predicted_Y = model.predict(testing_X), compare it to testing_Y, if network model was chosen correctly then testing_Y should be close to predicted_Y, e.g. 80% correct (this ratio is called accuracy).

为什么我们将数据集划分为训练/测试部分.因为训练阶段仅看到训练数据集的子部分.网络训练的任务是通过找到XY 之间的一些隐藏依赖来很好地记住整个训练数据并进行泛化预测.因此,如果要对训练数据调用 model.predict(...),则其准确性应接近 100%,因为网络会看到所有这些训练数据并记住它们.但是测试数据根本看不到,因此需要很聪明并且可以通过X真正预测Y的测试,因此测试的准确性较低,例如 80%.

Why do we split dataset into training/testing parts. Because training stage only sees training dataset sub-part. The task of network training is to remember whole training data well plus generalize prediction by finding some hidden dependencies between X and Y. So if to call model.predict(...) on training data is should give close to 100% accuracy, because network sees all this training data and remembers it. But testing data it doesn't see at all, hence needs to be clever and really predict testing Y by X, hence accuracy in testing is lower e.g. 80%.

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

If quality of testing results is not great, you have to improve your network architecture and re-run whole training process from start.

如果您需要预测部分数据,例如当您在 X 数据中只有15个可能的列中的12个时,然后用零填充缺失的列值,例如如果缺少第7和11列,则在第7和11位置插入零.这样一来,列总数再次为15.您的网络将仅在model.predict()的输入中支持其训练过的列数,即15,该数字在 input_shape =(15,)中提供.

If you need to predict partial data, e.g. when you have in your X data only 12 out of total 15 possible columns, then fill-in missing columns values by zeros, e.g. if you're missing column 7 and 11, then insert zeros into 7th and 11th positions. So that total number of columns is 15 again. Your network will support in input for model.predict() only exactly that number of columns that it was trained with, i.e. 15, this number is provided in input_shape = (15,).

这篇关于如何使用经过训练和保存的前馈神经网络预测新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆