我正在使用Keras来创建预测模型。但是,当我试图获得预测时,我会得到一个ValueError,指示输入不兼容。下面是一个正在重现问题的最小代码:
import tensorflow as tf
from tensorflow.keras.callbacks import TensorBoard
import random
import time
import numpy as np
import pickle
#Bring data:
Name = "Predict-{}".format(int(time.time()))
tensorboard = TensorBoard(log_dir='logs/{}'.format(Name))
pickle_in = open("training_data.pickle","rb")
training_data = pickle.load(pickle_in)
random.shuffle(training_data)
X=[]
y=[]
for file_data, categ in training_data :
X.append(file_data)
y.append(categ)
X=np.array(X)
y=np.array(y)
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(172,activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(2,activation=tf.nn.softmax))
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
model.fit(X,y,epochs=10, batch_size=128,validation_split=0.25, callbacks=[tensorboard])
#New input Xnew, with len(Xnew)=172
Xnew = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]
ynew = model.predict(Xnew)
这是我得到的错误:
ValueError: Input 0 of layer dense_107 is incompatible with the layer: expected axis -1 of input shape to have value 172 but received input with shape [None, 1]
模型摘要:
Model: "sequential_53"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten_53 (Flatten) (None, 172) 0
_________________________________________________________________
dense_109 (Dense) (None, 172) 29756
_________________________________________________________________
dense_110 (Dense) (None, 2) 346
=================================================================
Total params: 30,102
Trainable params: 30,102
Non-trainable params: 0
_________________________________________________________________
我也不明白为什么形状是(None,172(而不是172。
错误在于您为预测而提供给网络的对象。它期望一个数组为(batch, data)
,而您给出的是(,data)
。
你所能做的只是对网络说";这里我有一批";
Xnew = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0])
ynew = model.predict(np.expand_dims(Xnew, axis=0))
expand_dims添加一个维度(在这种情况下在形状前面(
对于最后一部分,你得到(None, 172)
None意味着我们不知道摘要中的批次数量(如果你愿意,你可以指定它(,网络期望(X,172(,其中X可以是一切(32,64…(
模型中不需要压平层,因为您的数据已经处于Dense层的正确形状。
所以你可以这样重写模型,
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(input_shape=(172,), units=172, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(2,activation=tf.nn.softmax))
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
请注意第一个密集层中的input_shape参数。它告诉模型期望的尺寸。
模型摘要如下
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_4 (Dense) (None, 172) 29756
_________________________________________________________________
dense_5 (Dense) (None, 2) 346
=================================================================
Total params: 30,102
Trainable params: 30,102
Non-trainable params: 0
_________________________________________________________________
使用与您的数据形状相同的随机数据的训练模型,
X = np.random.rand(*(602, 172))
y = np.random.rand(*(602, 2))
model.fit(X, y, epochs=100, batch_size=32)
Epoch 1/100
19/19 [==============================] - 0s 2ms/step - loss: 0.6006 - accuracy: 0.9934
Epoch 2/100
19/19 [==============================] - 0s 5ms/step - loss: 0.6006 - accuracy: 0.9900
Epoch 3/100
19/19 [==============================] - 0s 1ms/step - loss: 0.6006 - accuracy: 0.9983
关于输出形状中的"无","无"表示此维度是可变的。
keras模型中的第一个维度始终是批量大小。您不需要固定的批量大小,除非在非常特殊的情况下(例如,当使用stateful=True LSTM层时(。