具有顺序数据的 Keras conv1D 的输入形状

k_t*_*der 1 python keras

我想使用 Conv1D 将扩张卷积网络制作为顺序数据集。
所以我尝试使用 Boston 数据集进行 Conv1D。

from tensorflow.python.keras.layers import Conv1D, MaxPooling2D
from tensorflow.python.keras.layers import Activation, Dropout, Flatten, Input, Dense
from tensorflow.python.keras.models import Model
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

boston = load_boston()
df = pd.DataFrame(boston.data,columns=boston.feature_names)
df['target']= boston.target
y = df['target']
X = df.drop(columns=['target'])
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=2)

def NN_model(data= X_train):
  #data = np.expand_dims(data, axis=2)
  inputs = Input(((data.shape)))
  x = Conv1D(2,2,dilation_rate=2,padding="same", activation="relu")(inputs)
  x = Flatten()(x)
  x = Dense(2048, activation="relu")(x)
  predictions = Dense(1)(x)
  model = Model(inputs=inputs, outputs=predictions)
  model.compile(optimizer="adam",loss='mean_squared_error')
  model.summary()
  return model
nn_model = NN_model(X_train)
Run Code Online (Sandbox Code Playgroud)

该模型没有错误,但是当我尝试时

nn_model.fit(X_train,y_train)
Run Code Online (Sandbox Code Playgroud)

它出现了一个错误

ValueError: Error when checking input: expected input_1 to have 3 dimensions, but got array with shape (404, 13)
Run Code Online (Sandbox Code Playgroud)

我在函数 NN_model 中添加了这一新行:

def NN_model(data= X_train):
  data = np.expand_dims(data, axis=2)
Run Code Online (Sandbox Code Playgroud)

或者

def NN_model(data= X_train):
  data = np.reshape(X_train.values, (-1, data[1], 1))

Run Code Online (Sandbox Code Playgroud)

但它在模型中引发了一个错误

ValueError: Input 0 of layer conv1d_1 is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [None, 404, 13, 1]
Run Code Online (Sandbox Code Playgroud)

我应该怎么办?

小智 5

问题在于如何定义输入形状。来自 keras 文档:

shape:形状元组(整数),不包括批量大小

这意味着输入层中的形状应该定义单个数据的形状,而不是整个训练数据集的形状。inputs = Input(((data.shape)))为您提供整个数据集大小,在本例中为 (404,13)。然而,您的每个样本实际上只是一个 13 长度的向量,因此您想要的形状是 (13,1)。

要获得所需的输入形状,您可以使用类似inputs = Input(((data.shape[1],1))). 这会忽略第一个维度(它给出样本数)。

您在重塑数据时尝试的修复实际上是您在训练之前需要采取的步骤。您需要 model.fit 的输入具有形状(样本数,13, 1),因此您需要重塑数据以匹配该形状,就像在示例中所做的那样:

X_train = np.expand_dims(X_train, axis=2)
nn_model.fit(X_train,y_train)
Run Code Online (Sandbox Code Playgroud)

供将来参考,您遇到的第二个错误:

ValueError:层 conv1d_1 的输入 0 与该层不兼容:预期 ndim=3,发现 ndim=4。收到完整形状:[无、404、13、1]

告诉您您的输入大小不适合使用 Conv1D 层。这是因为 Conv1D 层需要 3 维输入。假设您使用的是通道最后格式(相对于通道在前),这将是(批次、步骤、通道)。即,第一个维度是批量大小,第二个维度是时间步数(在本例中为 13),第三个维度是通道数(在本例中为 1)。