python - 使用 CNN 超参数优化进行多目标回归时出错
问题描述
我正在尝试使用 CNN 解决多目标回归问题。为了优化超参数,我使用了 Talos 库,但最终出现错误:
检查输入时出错:预期 conv1d_1_input 有 3 个维度,但得到了形状为 (280000, 70) 的数组
数据集描述:X有70个特征,Y有32个目标时间序列长度:509760个时间点
Shape of Dataset:
Train Data size: (400000, 70),
Train Target size: (400000, 32),
Test Data size: (109760, 70),
Test Target size: (109760, 32),
代码:
tf.keras.backend.clear_session()
def model(x_train, y_train, x_val, y_val, params):
n_timesteps, n_features, n_outputs = x_train.shape[0], x_train.shape[1], y_train.shape[1]
model = Sequential()
model.add(Conv1D(filters=params['conv1_filter'], kernel_size=(3), activation=params['activation'], input_shape=(n_timesteps,n_features)))
model.add(Conv1D(filters=params['conv2_filter'], kernel_size=(3), activation=params['activation']))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(params['dropout']))
model.add(Conv1D(filters=8, kernel_size=3, activation=params['activation']))
model.add(MaxPooling1D(pool_size=2))
model.add(Dense(100, activation=params['activation']))
model.add(Dense(n_outputs))
model.add(Flatten())
model.compile(loss='mse',optimizer=params['optimizer'](),metrics=['acc', fmeasure_acc])
out = model.fit(x_train, y_train, validation_data=[x_val, y_val], batch_size=params['batch_size'], epochs=params['epochs'],verbose=1,shuffle=True)
return out, model
p = {'conv1_filter':[32],
'conv2_filter':[32],
'optimizer': [Nadam],
'batch_size': [1000],
'epochs': [5],
'dropout': [0.5],
'activation':[relu]}
# and run the experiment
t = ta.Scan(x=x_train,y=y_train,model=model,params=p,experiment_no='1')
错误如下:
168 # input parameters section ends
169
--> 170 self._null = self.runtime()
171
172 def runtime(self):
/anaconda3/lib/python3.7/site-packages/talos/scan/Scan.py in runtime(self)
173
174 self = scan_prepare(self)
--> 175 self = scan_run(self)
/anaconda3/lib/python3.7/site-packages/talos/scan/scan_run.py in scan_run(self)
16 disable=self.disable_progress_bar)
17 while len(self.param_log) != 0:
---> 18 self = scan_round(self)
19 self.pbar.update(1)
20 self.pbar.close()
/anaconda3/lib/python3.7/site-packages/talos/scan/scan_round.py in scan_round(self)
30 # fit the model
31 try:
---> 32 _hr_out, self.keras_model = ingest_model(self)
33 except TypeError as err:
34 if err.args[0] == "unsupported operand type(s) for +: 'int' and 'numpy.str_'":
/anaconda3/lib/python3.7/site-packages/talos/model/ingest_model.py in ingest_model(self)
8 self.x_val,
9 self.y_val,
---> 10 self.round_params)
<ipython-input-9-b33b869928ed> in model(x_train, y_train, x_val, y_val, params)
20
21
---> 22 out = model.fit(x_train, y_train, validation_data=[x_val, y_val], batch_size=params['batch_size'], epochs=params['epochs'],verbose=1,shuffle=True)
23
24
/anaconda3/lib/python3.7/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
950 sample_weight=sample_weight,
951 class_weight=class_weight,
--> 952 batch_size=batch_size)
953 # Prepare validation data.
954 do_validation = False
/anaconda3/lib/python3.7/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
749 feed_input_shapes,
750 check_batch_axis=False, # Don't enforce the batch size.
--> 751 exception_prefix='input')
752
753 if y is not None:
/anaconda3/lib/python3.7/site-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
126 ': expected ' + names[i] + ' to have ' +
127 str(len(shape)) + ' dimensions, but got array '
--> 128 'with shape ' + str(data_shape))
129 if not check_batch_axis:
130 data_shape = data_shape[1:]
ValueError: Error when checking input: expected conv1d_1_input to have 3 dimensions, but got array with shape (280000, 70)
解决方案
我又看了一遍,您的代码中需要更改一些内容。我测试了它,它现在应该可以工作了:
首先,模型本身有几个问题。
也就是说,模型的输入应该是(n_features, 1)
而不是(n_timesteps,n_features)
. Keras 内部认为您在给出输入形状时忽略了批量维度。所以当它注册为一个形状时(batch_size, n_features, 1)
。最后一个维度是必需的,以便与Conv1D
.
它应该是这样的:
model.add(Conv1D(filters=params['conv1_filter'], kernel_size=(3), activation=params['activation'], input_shape=(n_features, 1)))
其次,模型不应该以Flatten()
层结束。相反,该层应该在该Dense()
层之前(以便它看到 2D 输入而不是 3D 输入)。两次更改后,模型应如下所示:
model = Sequential()
model.add(Conv1D(filters=params['conv1_filter'], kernel_size=(3), activation=params['activation'], input_shape=(n_features,1)))
model.add(Conv1D(filters=params['conv2_filter'], kernel_size=(3), activation=params['activation']))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(params['dropout']))
model.add(Conv1D(filters=8, kernel_size=3, activation=params['activation']))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(100, activation=params['activation']))
model.add(Dense(n_outputs))
因为我们改变了input_shape
模型,所以我们需要改变数据的形状。需要做的是更改(400000, 70)
为(400000, 70, 1)
和。这可以使用以下命令完成:(109760, 70)
(109760, 70, 1)
x_train = np.expand_dims(x_train, axis=-1)
x_val = np.expand_dims(x_val, axis=-1)
我没有在 Talos 上测试它,但 keras 部分工作得很好。
推荐阅读
- html - 当没有祖先指定高度时垂直居中 div
- javascript - JS:For循环创建空对象而不是直接跳过它们
- python - 为通过整个文件夹循环运行 python 脚本创建一个 BAT 文件
- android - Android Studio - 没有 Android 核心库的源代码/javadocs
- python - 从 one-hot 表示到标签
- intellij-idea - 如何确定我使用 JavaFX 编写的游戏是否使用了足够的系统资源?
- unit-testing - Xamarin.Forms - 对使用 Autofac 中的 ServiceLocator 的方法进行单元测试
- javascript - VB.NET TCP 客户端与 NODE-RED TCP 侦听器进行双向通信
- java - 用于下载 jar 文件的 Maven 依赖项
- c# - 错误 CS1503:参数 1:无法从“字符串”转换为“System.IFormatProvider”