【问题标题】:How can I improve the speed of my simple neural network?如何提高我的简单神经网络的速度?
【发布时间】:2019-11-09 10:14:27
【问题描述】:

我刚刚开始探索 TensorFlow,但遇到了性能问题。作为一个开始的例子,我尝试实现一个模型来模拟逻辑门。假设有两个输入A 和B 和一个输出Y。假设Y 仅依赖于B 而不是A。这意味着以下是有效的示例:

[0, 0] -> 0
[1, 0] -> 0
[0, 1] -> 1
[1, 1] -> 1

我为此数据创建了训练集,并创建了一个使用DenseFeatures 层的模型,该层使用两个特征A 和B。该层馈入Dense(128, 'relu') 层,后者馈入Dense(16, 'relu') 层,最后馈入Dense(1, 'sigmoid') 层。

训练这个 NN 效果很好,预测也很完美。但是,我注意到在我的 MacBook 上,每个预测大约需要 250 毫秒。这太过分了,因为我的最终目标是使用这样的神经网络每秒测试数百个预测。

所以我将网络剥离到 DenseFeatures([A, B]) -> Dense(8, 'relu') -> Dense(1, 'sigmoid'),但是对这个 NN 的预测仍然需要大约相同的时间。我期望执行速度取决于模型的复杂性。我可以看到这里不是这种情况?我做错了什么?

另外,我读到 TensorFlow 使用浮点数学来提高准确性,但这会降低性能,如果我们将数据转换为使用整数数学,它会加快速度。但是,我不知道如何实现。

如果有人能帮助我理解为什么对如此简单的逻辑门和如此简单的 NN 进行预测需要这么长时间,我将不胜感激。以及如何加快速度。

作为参考,这是我在 python 中的代码:

  import random
  from typing import Any, List

  import numpy as np
  import tensorflow as tf
  from sklearn.model_selection import train_test_split
  from tensorflow import feature_column
  from tensorflow.keras import layers

  class Input:
    def __init__(self, data: List[int]):
      self.data = data

  class Output:
    def __init__(self, value: float):
      self.value = value

  class Item:
    def __init__(self, input: Input, output: Output):
      self.input = input
      self.output = output

  DATA: List[Item] = []
  for i in range(10000):
    x = Input([random.randint(0, 1), random.randint(0, 1)])
    y = Output(x.data[1])
    DATA.append(Item(x, y))

  BATCH_SIZE = 5
  DATA_TRAIN, DATA_TEST = train_test_split(DATA,       shuffle=True, test_size=0.2)
  DATA_TRAIN, DATA_VAL  = train_test_split(DATA_TRAIN, shuffle=True, test_size=0.2/0.8)

  def toDataSet(data: List[Item], shuffle: bool, batch_size: int):
    a = {
      'a': [x.input.data[0] for x in data],
      'b': [x.input.data[1] for x in data],
    }
    b = [x.output.value for x in data]
    return tf.data.Dataset.from_tensor_slices((a, b)).shuffle(buffer_size=len(data)).batch(BATCH_SIZE)

  DS_TRAIN = toDataSet(DATA_TRAIN, True, 5)
  DS_VAL   = toDataSet(DATA_VAL, True, 5)
  DS_TEST  = toDataSet(DATA_TEST, True, 5)

  FEATURES = []
  FEATURES.append(a)
  FEATURES.append(b)
  feature_layer = tf.keras.layers.DenseFeatures(FEATURES)
  model = tf.keras.models.load_model('MODEL.H5')
  model = tf.keras.Sequential([
    feature_layer,
    layers.Dense(8, activation='relu'),
    layers.Dense(1, activation='sigmoid')
  ])
  model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
  model.fit(DS_TRAIN, validation_data=DS_VAL, epochs=10)
  loss, accuracy = model.evaluate(DS_TEST)

  for i in range(1000):
    val = model.predict([np.array([random.randint(0, 1)]), np.array([random.randint(0, 1)])])

【问题讨论】:

    标签: python python-3.x tensorflow machine-learning tf.keras


    【解决方案1】:

    由于您只使用整数,请将模型的输入更改为使用 8 位有符号整数。您可以通过添加 dtype 参数来更改输入层中的数据类型。这将大大提高处理速度,因为您不会浪费计算。

    【讨论】:

    • 嗨!我试图调查它,但我无法弄清楚将dtype 设置为什么值。我知道我可以将其设置为'float32' 和'float64',但我无法找到代表 8 位有符号整数的字符串。另外,您能否解释一下我是否需要扩展我的输入和标签来解决这个问题?
    • 8 位有符号整数是“int8”。如果您谷歌“Tensorflow 数据类型”,您还可以获得所有可用数据类型的列表。让我知道结果如何。
    猜你喜欢
    • 2015-06-24
    • 2022-01-08
    • 2015-11-05
    • 2021-06-18
    • 2016-11-22
    • 1970-01-01
    • 2018-01-10
    • 2017-09-06
    相关资源
    最近更新 更多