Python 我训练了一个完整的CNN的3D数据,我在训练中得到了NaN

Python 我训练了一个完整的CNN的3D数据,我在训练中得到了NaN,python,tensorflow,machine-learning,keras,deep-learning,Python,Tensorflow,Machine Learning,Keras,Deep Learning,我正在尝试训练一个完整的CNN的3D数据(我使用conv3D)。首先,要了解一些上下文。输入是一个表示蛋白质密度图的三维矩阵,输出是一个三维矩阵,其中C-α的位置标记为1,其余的标记为0。正如预期的那样,这导致了大量数据的不平衡。因此,我实现了一个定制的交叉熵成本函数,该函数将模型的重点放在class=1上,如下所示: 这些地图往往很大,因此训练时间往往会随着地图维度的略微增加而呈指数增长,或者如果我让我的网络更深一点的话。除此之外,地图的很大一部分是空白,但我必须保留它以保持C-alpha不同

我正在尝试训练一个完整的CNN的3D数据(我使用conv3D)。首先,要了解一些上下文。输入是一个表示蛋白质密度图的三维矩阵,输出是一个三维矩阵,其中C-α的位置标记为1,其余的标记为0。正如预期的那样,这导致了大量数据的不平衡。因此,我实现了一个定制的交叉熵成本函数,该函数将模型的重点放在class=1上,如下所示: 这些地图往往很大,因此训练时间往往会随着地图维度的略微增加而呈指数增长,或者如果我让我的网络更深一点的话。除此之外,地图的很大一部分是空白,但我必须保留它以保持C-alpha不同位置之间的真实距离。为了解决这个问题,我将每个地图拆分为更小的维度框(5,5,5)。这种方法的好处是我可以忽略空白,这大大减少了训练所需的内存和计算量。 我现在的问题是,我在培训损失中得到NaN,培训终止,如下所示:

这是我正在使用的网络:

model = Sequential()
model.add(Conv3D(15, kernel_size=(3,3,3), activation='relu', input_shape=(5,5,5,1), padding='same'))
model.add(Conv3D(30, kernel_size=(3,3,3), activation='relu', padding='same'))
model.add(Conv3D(60, kernel_size=(3,3,3), activation='relu', padding='same'))
model.add(Conv3D(30, kernel_size=(3,3,3), activation='relu', padding='same'))
model.add(Conv3D(15, kernel_size=(3,3,3), activation='relu', padding='same'))
model.add(Conv3D(1, kernel_size=(3,3,3), activation='sigmoid', padding='same'))
model.compile(loss=weighted_cross_entropp_loss, optimizer='nadam',metrics=['accuracy'])

############# model training ######################################
model.fit(x_train, y_train, batch_size=32, epochs=epochs, verbose=1,validation_split=0.2,shuffle=True,callbacks=[stop_immediately,save_best_model,stop_here_please])
model.save('my_map_model_weighted_custom_box_5.h5')  
谁能帮帮我吗?我已经研究这个问题好几个星期了


关于

所以不久前我问了这个问题,从那时起我一直在努力寻找解决方案。我想我找到了它,所以我想我应该分享它。但在我这么做之前,我想说我读到的东西,我认为它指向了我问题的核心。俗话说“如果超参数对其他人有效,它不一定对你有效。如果你试图用新的体系结构解决一个新问题,那么你需要新的超参数”,或者类似的东西。 可悲的是,在Keras中(如果在预期的域中使用,这是一个很好的工具),它指出优化器参数应该保持原样,这是错误的,现在到了解决方案中

简单的回答是: 学习率太高了

答案很长: 这里我详细介绍了如何解决这个问题。如果在前100次迭代中得到一个NaN,这直接表明问题在于学习率高。但是,如果在前100次迭代后得到它,那么问题可能是以下两种情况之一:

  • 如果使用RCNN,则必须使用gradient.clip
  • 如果您有一个自定义图层(我有一个自定义的成本函数),那么这可能就是原因。现在,需要记住的一件重要事情是,正确的实现和稳定的实现是有区别的。您可以正确地实现自定义层,但是,需要添加一些技巧以使其稳定,这是我的自定义层中缺少的
    您是否检查了数据以确保输入是正确的?GitHub上的这个人有一个类似的问题:我的输入在仍然是一个大地图(80,80,80)或更多的时候被规范化。然后,当我取小盒子(5,5,5)时,我首先通过计算盒子的总和来检查盒子是否为空,如果总和大于0,那么盒子不是空的,所以我保留它,否则,如果它为空,我丢弃它。因此,不应该有任何空的或空的箱子。我取消了早期停止条件,并将class1的重量设置为1。现在,我的训练损失在减少,验证损失在增加。我认为这是一个过度拟合的迹象,所以我正试图缩小网络的规模,看看会发生什么