用卷积神经网络和MPG数据集做预测,错误提示如下:
ValueError: Input 0 of layer conv1d is incompatible with the layer: : expected min_ndim=3, found ndim=2. Full shape received: (None, 9)
代码如下:
```python
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import pandas as pd
# 加载MPG数据集
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
columns = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
'Acceleration', 'Model Year', 'Origin']
mpg_data = pd.read_csv(url, names=columns, na_values='?', comment='\t',
sep=' ', skipinitialspace=True)
# 处理缺失值
mpg_data = mpg_data.dropna()
# 将Origin列映射为不同的整数(重点)
mpg_data['Origin'] = mpg_data['Origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})
# 创建训练集和验证集
train_dataset = mpg_data.sample(frac=0.8, random_state=0)
val_dataset = mpg_data.drop(train_dataset.index)
# 将Origin列转换为独热编码
train_dataset = pd.get_dummies(train_dataset, prefix='', prefix_sep='')
val_dataset = pd.get_dummies(val_dataset, prefix='', prefix_sep='')
# 获取输入维度
input_shape = [train_dataset.shape[1] - 1]
# 构建模型
model = keras.Sequential([
# 卷积层
layers.Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=input_shape),
layers.BatchNormalization(),
# 池化层
layers.MaxPooling1D(),
# 平均池化层
layers.GlobalAveragePooling1D(),
# 全连接层
layers.Dense(units=64, activation='relu'),
layers.BatchNormalization(),
# 输出层
layers.Dense(units=1)
])
# 编译模型
model.compile(optimizer='adam',
loss='mean_squared_error')
# 将输入和输出分离
train_features = train_dataset.drop('MPG', axis=1).to_numpy()
train_labels = train_dataset['MPG'].to_numpy()
val_features = val_dataset.drop('MPG', axis=1).to_numpy()
val_labels = val_dataset['MPG'].to_numpy()
# 训练模型
history = model.fit(train_features, train_labels,
validation_data=(val_features, val_labels),
epochs=100, batch_size=32)
# 评估模型
test_loss = model.evaluate(val_features, val_labels)
# 打印测试集上的损失
print(f'Test loss: {test_loss:.4f}')
```
下面是修改后的代码段:
# 导入必要的库
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import pandas as pd
# 加载MPG数据集
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
columns = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
'Acceleration', 'Model Year', 'Origin']
mpg_data = pd.read_csv(url, names=columns, na_values='?', comment='\t',
sep=' ', skipinitialspace=True)
# 处理缺失值
mpg_data = mpg_data.dropna()
# 将Origin列映射为不同的整数(重点)
mpg_data['Origin'] = mpg_data['Origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})
# 创建训练集和验证集
train_dataset = mpg_data.sample(frac=0.8, random_state=0)
val_dataset = mpg_data.drop(train_dataset.index)
# 将Origin列转换为独热编码
train_dataset = pd.get_dummies(train_dataset, prefix='', prefix_sep='')
val_dataset = pd.get_dummies(val_dataset, prefix='', prefix_sep='')
# 获取输入维度
input_shape = [train_dataset.shape[1] - 1, 1] # 修改此处,将输入维度从2D转为3D
# 构建模型
model = keras.Sequential([
# 卷积层
layers.Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=input_shape, padding="same"), # 使用 padding="same"来处理 kernel 大小和步长可能引起的问题
layers.BatchNormalization(),
# 池化层
layers.MaxPooling1D(),
# 平均池化层
layers.GlobalAveragePooling1D(),
# 全连接层
layers.Dense(units=64, activation='relu
'),
layers.BatchNormalization(),
# 输出层
layers.Dense(units=1)
])
# 编译模型
model.compile(optimizer='adam',
loss='mean_squared_error')
# 将输入和输出分离
train_features = train_dataset.drop('MPG', axis=1).to_numpy()
train_labels = train_dataset['MPG'].to_numpy()
val_features = val_dataset.drop('MPG', axis=1).to_numpy()
val_labels = val_dataset['MPG'].to_numpy()
# 增加一个维度
train_features = tf.expand_dims(train_features, axis=-1)
val_features = tf.expand_dims(val_features, axis=-1)
# 训练模型
history = model.fit(train_features, train_labels,
validation_data=(val_features, val_labels),
epochs=100, batch_size=32)
# 评估模型
test_loss = model.evaluate(val_features, val_labels)
# 打印测试集上的损失
print(f'Test loss: {test_loss:.4f}')
维度少了,Conv1D层期望的输入维度最小为3,你的输入为2,需要有时间维度才可以。
这份数据可能并不合适用卷积,用全连接比较好。
如果有帮助,请点击一下采纳该答案~谢谢
这个错误提示出现是因为卷积核的尺寸不正确。这里的卷积核尺寸应该是$(3,3)$,但是实际上却是$(5,5)$。因此需要对卷积核的尺寸进行修改。
具体的解决方法是将conv1层的kernel_size从$(5,5)$修改为$(3,3)$即可,修改代码如下:
# Convolutional Layer 1
model.add(Conv2D(filters=32,kernel_size=(3, 3),padding="same", input_shape=[X_train.shape[1], X_train.shape[2], 1]))
修改完成后,可以重新运行程序进行验证。