我在3-D数据上训练了完整的CNN,但训练损失却得到了NaN

时间:2019-01-21 01:35:27

标签: python tensorflow machine-learning keras deep-learning

我正在尝试在3D数据上训练完整的CNN(我使用conv3D)。首先,要了解一些背景。输入是一个3D矩阵,表示蛋白质的密度图,输出是一个3D矩阵,其中C-alpha的位置标记为1,其余的标记为0。导致大量数据失衡。因此,我实现了一个自定义的交叉熵代价函数,该函数将模型集中在class = 1上,如下所示:  custom cost function 这些地图往往很大,因此训练时间往往会随着地图尺寸的稍微增加而呈指数增长,或者如果我使网络更深的话。除此之外,地图的很大一部分是空白空间,但是我必须保留它以保持C-alpha的不同位置之间的真实距离。要变通解决此问题,我将每个地图拆分为较小的尺寸为(5,5,5)的盒子。这种方法的好处是我可以忽略空白空间,因为空白空间大大减少了训练所需的内存和计算量。 现在的问题是,我在训练损​​失中得到了NaN,并且训练终止,如下所示: Network training behavior

这是我正在使用的网络:

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')  

任何人都可以帮助我,我已经在这个问题上工作了很多周了

致谢

1 个答案:

答案 0 :(得分:0)

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

简短答案:

学习率太高。

长答案:

这里我详细说明了如何解决。如果在前100次迭代中获得NaN,则直接表明问题是高学习率。但是,如果在前100次迭代后得到它,那么问题可能是两件事之一:

  1. 如果您使用的是RCNN,则必须使用gradient.clip
  2. 如果您有一个自定义图层(我有一个自定义成本函数),则可能是原因。现在,需要牢记的重要一点是,正确的实现与稳定的实现之间存在区别。您可以正确实现自定义层,但是,您需要添加一些技巧来使其稳定,这是我的自定义层所缺少的。