我正在训练一个网络来进行到达方向预测,但我遇到的问题是,无论我的网络是什么(ResNet 18 - 101、CRNN、CNN 等),我的结果都倾向于一个小范围如下图所示的值
这显然会导致以下错误:
我试图“等待”直到我的网络最终学习,但我的验证损失几乎立即分歧。下面可以看到一个例子。
奇怪的是,即使我的训练损失也没有达到 0。我认为如果我的网络过度拟合,它只会完美地学习我的数据集,但这不会发生,不管我的模型有多复杂。我唯一能想到的是我的特征表示完全是荒谬的,或者我在训练功能的某个地方有错字,并且正在发生一些奇怪的事情。
我尝试过使用损失函数,在网络末端尝试了不同的激活函数,例如 Tanh、sigmoid、ReLU,但根本没有激活函数。目前我已经尽可能地简化了我的训练数据,并且正在使用一个 8 通道 1s 长的啁啾信号,可以在这里找到(至少是暂时的):https ://file.re/2021/06/20 /啁啾/
如上所述,我尝试了各种尺寸的标准 ResNet,以及各种不同的特征表示,最近的一次是采用所有 8 个通道的复杂 STFT,垂直堆叠幅度并将角度信息添加到 X 轴,如下所示:
如果有人有任何想法,我很乐意尝试。目前,我正在使用具有垂直卷积且没有池化操作的 CNN,以尝试保存时间信息。
我的主要训练方法如下:
def train(self):
steps, losses, metrics = TrainingUtilities.get_training_variables(self.parameters)
patience_counter = 0
best_epoch_data = None
best_epoch_validation_loss = 999
best_epoch = 0
exit_training = False
try:
for epoch in range(steps, self.epoch_count):
epoch_metrics = TrainingUtilities.initialize_metrics(self.mode)
if exit_training:
break
for idx, phase in enumerate(['train', 'val']):
if phase == 'train':
self.model.train()
else:
self.model.eval()
for _, data in tqdm(enumerate(self.data_loaders[idx])):
self.optimizer.zero_grad()
inputs, labels = data
outputs = self.model(inputs.to(self.device))
# labels = azi_class.squeeze_().to(self.device)
loss = self.criterion(outputs.squeeze(), labels.to(self.device))
epoch_metrics = TrainingUtilities.get_epoch_metrics(
outputs, labels, loss, epoch_metrics, phase, self.mode)
if phase == 'train':
loss.backward()
self.optimizer.step()
TrainingUtilities.report_metrics(self.writer, epoch_metrics, epoch, phase, self.parameters, self.mode)
if phase == "val":
TrainingUtilities.step_scheduler(
self.scheduler, np.mean(epoch_metrics[0][phase]), self.parameters)
losses.append(epoch_metrics[0])
metrics.append(epoch_metrics)
if epoch % self.epoch_save_count == 0:
TrainingUtilities.save_checkpoint(self.model, losses, metrics, self.training_dir, epoch, self.mode, self.model_name, self.size)
steps += 1
except (KeyboardInterrupt, RuntimeError) as error:
print(f"Error: {error}")
TrainingUtilities.save_checkpoint(self.model, losses, metrics, self.training_dir, steps, self.mode, self.model_name, self.size)
我很可能错过了一些东西,但主要思想是,我认为很简单。由于使用不同的数据集测试了许多不同的模型,并且希望在分类和回归之间轻松切换,我已经抽象了很多东西。