Python 神经网络产生的错误结果接近输出的平均值 我正在做一个神经网络系统,作为西澳大利亚大学学生项目的一部分。

Python 神经网络产生的错误结果接近输出的平均值 我正在做一个神经网络系统,作为西澳大利亚大学学生项目的一部分。,python,machine-learning,neural-network,keras,Python,Machine Learning,Neural Network,Keras,我创建了一套大约20000次的SED拟合程序,称为。每次运行都有我们感兴趣的42个输入值和32个输出值(系统有更多输出,但我们不需要它们) 我一直在试验Keras神经网络包,以便创建一个网络来学习这个函数 我目前的网络设计使用4个隐藏层,完全互连,每层之间有30个连接。每一层都使用TanH激活函数。我还有一个42维的输入层和32维的输出层,它们都使用TanH激活,总共有6层 model = Sequential() loss = 'mse' optimiser = SGD(lr=0.01, mo

我创建了一套大约20000次的SED拟合程序,称为。每次运行都有我们感兴趣的42个输入值和32个输出值(系统有更多输出,但我们不需要它们)

我一直在试验Keras神经网络包,以便创建一个网络来学习这个函数

我目前的网络设计使用4个隐藏层,完全互连,每层之间有30个连接。每一层都使用TanH激活函数。我还有一个42维的输入层和32维的输出层,它们都使用TanH激活,总共有6层

model = Sequential()
loss = 'mse'
optimiser = SGD(lr=0.01, momentum=0.0, decay=0, nesterov=True)

model.add(Dense(output_dim=30, input_dim=42, init='glorot_uniform', activation='tanh'))

for i in range(0, 4):
    model.add(Dense(output_dim=30, input_dim=30, init='glorot_uniform', activation='tanh'))

model.add(Dense(output_dim=32, input_dim=30, init='glorot_uniform', activation='tanh'))
model.compile(loss=loss, optimizer=optimiser)
我一直在使用输入和输出数据的最小/最大归一化来压缩0到1之间的所有值。我使用了一个随机梯度下降优化工具,我已经试验过各种损失函数,比如均方误差、平均绝对误差、平均绝对百分比误差等

主要问题是,无论我如何构建我的网络,它只会生成接近所有训练输出值平均值的输出值。它看起来并不是通过网络实际正确地学习了功能,而是生成了接近平均值的值。更糟糕的是,我试验过的一些网络设计,特别是那些使用线性激活函数的网络设计,只会生成输出值的平均值,并且不会发生任何变化

示例(对于32个输出之一):

请注意,尽管这些值非常不正确,但所有输出都刚好在9.2-9.4值附近

考虑到所有这些,是什么原因导致像我这样的网络产生了这些接近平均水平的输出?


我可以尝试什么方法来解决这个问题并创建某种网络,以实际生成正确的输出?

除了CAFEBABE的评论之外,我只想就这个具体问题提出一些想法:

  • 42输入功能不是一大堆可以使用的功能。这并不是您必须要解决的问题,但这意味着您需要更宽的隐藏层(即更多节点),以帮助实现类/标签的可分性。此外,20K观测数据并不是一个大数据集。如果你能得到更多的数据,你应该。事实总是如此

  • >P>如果你有一个具体的MI/MAX规范化的理由,那么忽略这一点,但是你可以考虑对你的输入进行篡改,这有助于网络准确预测的能力。这本质上允许激活的输入发生在函数的中间,而不是末端

  • 你应该在优化方面做更多的实验。例如:

    • 你参加了几次训练?仅仅通过一次数据是不够的
    • 尝试不同的优化器,如
      rmsprop
      adam
      ,或学习率
    • 你也可以使用一个学习率调度器,比如,你可以在各个时期降低你的学习率,这样你就不会超过损失函数的极小值
  • 尝试一些不同的激活功能。最近的研究包括:ReLU、ELU、PReLU、SReLU。所有产品均以keras提供

  • 还可以尝试包括一些正则化,以避免过度拟合。调查辍学学生,或L2/L1

  • 虽然有一个更深层次的模型(即更多的层)通常会有所帮助,但将数据维度从42个特性减少到30个,可能会损害您分离数据的能力。试试更大的,比如100、500或1000

  • 您可以尝试的示例模型如下:

    # imports 
    from sklearn.cross_validation import train_test_split
    from keras.models import Sequential
    from keras.layers.core import Dense, Activation, Dropout
    from keras.layers.normalization import BatchNormalization
    from keras.layers.advanced_activations import ELU     
    
    # data shapes
    n_obs, n_feat = 20000, 42
    n_hidden = 500 # play with this, bigger tends to give better separability
    n_class = 32
    
    # instantiate model
    model = Sequential()
    
    # first layer --- input
    model.add(Dense(input_dim = n_feat, output_dim = n_hidden))
    model.add(BatchNormalization())
    model.add(ELU())
    model.add(Dropout(p=0.2)) # means that 20% of the nodes are turned off, randomly
    
    # second layer --- hidden
    model.add(Dense(input_dim = n_hidden, output_dim = n_hidden))
    model.add(BatchNormalization())
    model.add(ELU())
    model.add(Dropout(p=0.2))
    
    # third layer --- output
    model.add(Dense(input_dim = n_hidden, output_dim = n_class))
    model.add(BatchNormalization())
    model.add(Activation('softmax'))
    
    # configure optimization
    model.compile(optimizer = 'rmsprop', loss = 'categorical_crossentropy', metrics = ['accuracy'])
    
    # split your data, so you test it on validation data
    X_train, X_test, Y_train, Y_test = train_test_split(data, targets)
    
    # train your model
    model.fit(X_train, Y_train, validation_data = (X_test, Y_test))
    

    祝你好运

    这种行为的常见原因是功能没有意义。他们基本上不会解释你的数据。这其实并不罕见。然而,在大多数情况下,如果观察到,这主要是由于预处理错误。你是否尝试过更简单的方法,例如,建立一个线性模型(如果你错误地使用了神经网络库),而不是规范化数据以避免这种影响。此外,您可以尝试将输出包含在输入中。看起来它卡在了局部最小值中。当我将我的BP神经网络应用于我使用任意编码的一组数据时,我遇到了这个问题。看看这个-它可能会帮你指出正确的方向。。。(有一节是关于陷入局部极小值的)@CAFEBABE,这样网络就无法在输入和输出之间找到任何有意义的连接?据我所知,必须有一个,因为这些相同的输入可以通过MAGPHYS程序运行,以产生有效的输出。@S.Foster:当然。最简单的事情就是预处理中的错误。我有过这样的问题,通常是我自己的小问题。第二,我想到的是,行之间可能存在依赖关系(训练示例),例如,像t |->f(t-1)+t之类的东西。这需要一些经常性的结构。然而,我对SED域的理解还不够透彻。然而,对我来说,当地的米尼玛解释听起来也很合理。@CAFEBABE你能发表你的评论作为回答吗?
    # imports 
    from sklearn.cross_validation import train_test_split
    from keras.models import Sequential
    from keras.layers.core import Dense, Activation, Dropout
    from keras.layers.normalization import BatchNormalization
    from keras.layers.advanced_activations import ELU     
    
    # data shapes
    n_obs, n_feat = 20000, 42
    n_hidden = 500 # play with this, bigger tends to give better separability
    n_class = 32
    
    # instantiate model
    model = Sequential()
    
    # first layer --- input
    model.add(Dense(input_dim = n_feat, output_dim = n_hidden))
    model.add(BatchNormalization())
    model.add(ELU())
    model.add(Dropout(p=0.2)) # means that 20% of the nodes are turned off, randomly
    
    # second layer --- hidden
    model.add(Dense(input_dim = n_hidden, output_dim = n_hidden))
    model.add(BatchNormalization())
    model.add(ELU())
    model.add(Dropout(p=0.2))
    
    # third layer --- output
    model.add(Dense(input_dim = n_hidden, output_dim = n_class))
    model.add(BatchNormalization())
    model.add(Activation('softmax'))
    
    # configure optimization
    model.compile(optimizer = 'rmsprop', loss = 'categorical_crossentropy', metrics = ['accuracy'])
    
    # split your data, so you test it on validation data
    X_train, X_test, Y_train, Y_test = train_test_split(data, targets)
    
    # train your model
    model.fit(X_train, Y_train, validation_data = (X_test, Y_test))