【问题标题】:Training loss is not reduced in DNNDNN 中的训练损失没有减少
【发布时间】:2018-06-26 01:48:37
【问题描述】:

我想训练一个模型来学习形状为 (1,3751) 的特征和形状为 (1,1) 的标签之间的关系。

它看起来很简单,所以我只使用了两个密集层 DNN 作为模型类型,并希望经过训练的模型可以帮助我做出足够好的预测。然而,预测值相差甚远,我注意到训练期间的损失根本没有减少。

我尝试了不同的方法,例如更改学习率或增加模型中的隐藏层,但都没有奏效。

以下是我的代码:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import with_statement

import argparse
import sys
import numpy as np
import pandas as pd
import tensorflow as tf

LEARNING_RATE = 0.0001

def model_fn(features, labels, mode, params):
  """Model function for Estimator."""

  input_layer = tf.reshape(features["x"], [1,3751])

  first_hidden_layer = tf.layers.dense(input_layer, 1000, activation=tf.nn.relu)
  second_hidden_layer = tf.layers.dense(first_hidden_layer, 100, activation=tf.nn.relu)
  third_hidden_layer = tf.layers.dense(second_hidden_layer,10, activation=tf.nn.relu)
  predictions = tf.layers.dense(third_hidden_layer, 1)


  # Provide an estimator spec for `ModeKeys.PREDICT`.
  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(
        mode=mode,
        predictions={"ages": predictions})


  labels_first_row = tf.reshape(labels[1], [1,-1])
  loss = tf.losses.mean_squared_error(labels_first_row, predictions)

  optimizer = tf.train.GradientDescentOptimizer(
      learning_rate=params["learning_rate"])
  train_op = optimizer.minimize( 
      loss=loss, global_step=tf.train.get_global_step())

  # Calculate root mean squared error as additional eval metric
  eval_metric_ops = {
      "rmse": tf.metrics.root_mean_squared_error(
          tf.cast(labels_first_row, tf.float32), predictions)
  }

  return tf.estimator.EstimatorSpec(
      mode=mode,
      loss=loss,
      train_op=train_op,
      eval_metric_ops=eval_metric_ops)


def main(unused_argv):
  train_file = "training_data.csv"
  test_file = "test_data.csv"

  train_features_interim = pd.read_csv(train_file, usecols=['current'])
  train_features_numpy = np.asarray(train_features_interim, dtype=np.float32)
  train_labels_interim = pd.read_csv(train_file, usecols=['plo_tox'])
  train_labels_numpy = np.asarray(train_labels_interim, dtype=np.float32)

  model_params = {"learning_rate": LEARNING_RATE}

  # Instantiate Estimator
  nn = tf.estimator.Estimator(model_fn=model_fn, params=model_params, 
  model_dir='/tmp/nmos_self_define')

  train_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={"x": train_features_numpy},
      y=train_labels_numpy,
      batch_size = 3751,
      num_epochs= None,
      shuffle=False)

  # Train
  nn.train(input_fn=train_input_fn, steps=10000)

  test_features_interim = pd.read_csv(test_file, usecols = ['current'])
  test_features_numpy = np.asarray(test_features_interim, dtype=np.float32)
  test_labels_interim = pd.read_csv(test_file, usecols=['plo_tox'])
  test_labels_numpy = np.asarray(test_labels_interim, dtype=np.float32)

  # Score accuracy
  test_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={"x": test_features_numpy},
      y=test_labels_numpy,
      batch_size = 3751,
      num_epochs= None,
      shuffle=False)

  ev = nn.evaluate(input_fn=test_input_fn, steps = 500)
  print("Loss: %s" % ev["loss"])
  print("Root Mean Squared Error: %s" % ev["rmse"])

  prediction_file = "Tensorflow_prediction_data.csv"

  predict_features_interim = pd.read_csv(prediction_file, usecols=['current'])
  predict_features_numpy = np.asarray(predict_features_interim, dtype=np.float32)

  # Print out predictions
  predict_input_fn = tf.estimator.inputs.numpy_input_fn(
      x= {"x": predict_features_numpy},
      num_epochs=1,
      batch_size = 3751,
      shuffle=False)

  predictions = nn.predict(input_fn=predict_input_fn)
  for i, p in enumerate(predictions):
    print("Prediction %s: %s" % (i + 1, p["ages"]))


if __name__ == '__main__':
  tf.logging.set_verbosity(tf.logging.INFO)

  parser = argparse.ArgumentParser()
  parser.register("type", "bool", lambda v: v.lower() == "true")
  parser.add_argument(
      "--train_data", type=str, default="", help="Path to the training data.")
  parser.add_argument(
      "--test_data", type=str, default="", help="Path to the test data.")
  parser.add_argument(
      "--predict_data",
      type=str,
      default="",
      help="Path to the prediction data.")
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)

由于我只是机器学习的初学者,我认为向更了解的人征求意见可能会更好。我想我有一些旋钮需要调整,但我不太确定,请提供您认为有用的任何建议。

  1. 更改激活函数
  2. 使用正则化(请告诉我如何正确使用)
  3. 做一些特征操作
  4. 增加隐藏层和节点
  5. 增加训练集大小(现在我只有900组数据用于训练,够吗?)

我的输入数据表如下所示:

还有其他选择吗?提前感谢您提供任何想法。

【问题讨论】:

  • 你能简单描述一下你的数据吗?
  • 输入数据:900组输入组,每组3751个float32数字。输出数据:1个float32数字对应一组(3751个数字)输入数据。
  • 嗨@MohanRadhakrishnan,请参考我在帖子中关于我的数据表的新添加的数据。谢谢!

标签: python tensorflow machine-learning


【解决方案1】:

您说批量大小是 3751,而在 model_fn 中,您正在重塑您的输入特征以塑造 (1, 3751),这没有意义,因为 tf.layers.dense 期望每个批次和每个特征都在分别是第一维和第二维。

【讨论】:

  • 我在帖子中新添加了输入 Excel 表。我将“当前”列作为特征,将“plo_tox”列作为标签。正如您在图中看到的(虽然只是部分),每 3751 行“当前”对应于 1 个“plo_tox”,这就是为什么我采用 3751 的批量大小。我想一次接收 3751 行特征(当前)并针对 3751 个特征和 1 个标签之间的关系训练模型。我在批量大小方面做错了吗?
  • 谢谢。是的,model_fn 中的 tf.reshape 对我来说并不好看。您可以简单地尝试将input_layer 设置为features["x"](假设features["x"] 的形状为(3751, 1))。您的网络可能仍然无法正常工作(即,您有一个巨大的网络仅用于一个输入特征,并且“当前”的值非常小),但至少您将修复一些从我的角度来看在概念上是错误的东西。跨度>
  • 按照您的建议,我将输入数据更改为 3751 个数据作为一个输入特征集和 1 个数据作为输出标签。我一次用 1 个批次(数据形状 (1,3751))训练模型。正如您所预测的那样,即使我尝试了不同类型的激活函数,我也无法获得正确的结果。你有什么建议吗?
  • 数据的形状应该是(3751, 1)(不是(1,3751))。我认为我无法提供进一步的帮助(这在很大程度上取决于问题),但您应该尝试标准化您的数据(即让每列的平均值为 0 和标准为 1),并尝试使用更小的网络(您只需有一个输入功能)。
  • 现在我一次取 1 批。每批将有 1 行 3751 列,因此创建的特征形状为 (1, 3751)。输入特征的形状是 (1, 3751) 还是 (3751, 1) 重要吗?
猜你喜欢
  • 2019-08-18
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 2019-09-28
  • 2019-09-18
  • 2018-12-15
  • 2019-12-27
相关资源
最近更新 更多