простой пример пользовательского оценщика tensorflow

#tensorflow

#tensorflow

Вопрос:

Как мне написать простой рабочий пример пользовательского оценщика tensorflow, используя некоторые макетные тестовые данные? Я планирую протестировать что-то с eval_ops в режиме оценки, но мне чего-то не хватает в настройке. Этот код

 import unittest
import numpy as np
import tensorflow as tf


NFEATS = 5


def model_fn(features, labels, mode):
    inputs = tf.keras.Input(shape=NFEATS)
    outputs = tf.keras.layers.Dense(1)(inputs)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    logits = model(features['dense_input'])
    loss = tf.losses.mean_squared_error(y_true=labels, y_pred=logits)
    return tf.estimator.EstimatorSpec(
        mode=mode, loss=loss, eval_metric_ops=None, evaluation_hooks=None
    )


class TestEstimator(unittest.TestCase):
    def setUp(self) -> None:
        self.N = 1000
        self.batch_size = 100
        self.X = np.random.rand(self.N, NFEATS)
        self.Y = np.random.rand(self.N, 1)

    def test_estimator(self):
        def input_fn():
            data = {
                'X': self.X,
                'Y': self.Y
            }

            def map_fn(dd):
                return ({'dense_input': dd['X']}, dd['Y'])

            dset = tf.data.Dataset.from_tensor_slices(data) 
                     .map(map_fn).repeat(1).batch(self.batch_size)
            return dset

        estimator = tf.estimator.Estimator(model_fn=model_fn)
        estimator.evaluate(input_fn=input_fn, steps=3)


if __name__ == '__main__':
    unittest.main()
  

создает длинную трассировку стека, в результате чего он пытается преобразовать размер моего пакета 100 в нечто размером 1

 ======================================================================
ERROR: test_estimator (test.test_wis_total_label.TestEstimator)
----------------------------------------------------------------------
Traceback (most recent call last):
...
tensorflow.python.framework.errors_impl.InvalidArgumentError: Input to reshape is a tensor with 100 values, but the requested shape has 1
     [[{{node Reshape}}]]

During handling of the above exception, another exception occurred:

----------------------------------------------------------------------
Ran 1 test in 0.316s

FAILED (errors=1)
  

Ответ №1:

В tensorflow 2.1

 import unittest
import numpy as np
import tensorflow as tf


NFEATS = 5
BATCH_SIZE = 100


def model_fn(features, labels, mode):
    inputs = tf.keras.Input(shape=(NFEATS,), batch_size=BATCH_SIZE)
    outputs = tf.keras.layers.Dense(1)(inputs)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    logits = model(features['dense_input'])
    loss = tf.reduce_mean(tf.losses.mean_squared_error(y_true=labels, y_pred=logits))
    return tf.estimator.EstimatorSpec(
        mode=mode, loss=loss, eval_metric_ops=None, evaluation_hooks=None
    )


class TestEstimator(unittest.TestCase):
    def setUp(self) -> None:
        self.N = 1000
        self.X = np.random.rand(self.N, NFEATS)
        self.Y = np.random.rand(self.N, 1)

    def test_estimator(self):
        def input_fn():
            data = {
                'X': self.X,
                'Y': self.Y
            }

            def map_fn(dd):
                return ({'dense_input': dd['X']}, dd['Y'])

            dset = tf.data.Dataset.from_tensor_slices(data) 
                     .map(map_fn).repeat(1).batch(BATCH_SIZE)
            return dset

        estimator = tf.estimator.Estimator(model_fn=model_fn)
        estimator.evaluate(input_fn=input_fn, steps=3)


if __name__ == '__main__':
    unittest.main()
  

Добавьте размер пакета в tf.keras.Введите и уменьшите среднее значение потерь.

Комментарии:

1. Мне не нужно было добавлять размер пакета, просто выполнив loss = tf.reduce_mean(tf.losses.mean_squared_error(y_true= метки, y_pred= логиты)) сработало, спасибо!

Ответ №2:

Я вижу, у меня неправильная форма для тензоров, входящих в среднеквадратичную потерю ошибки, это работает, если я делаю

     loss = tf.losses.mean_squared_error(y_true=tf.reshape(labels, [-1]), y_pred=tf.reshape(logits, [-1]))
  

Определенно открыт для более простых примеров 🙂

Ответ №3:

Я протестировал ваш код на своем компьютере, который использует Tensorflow 1.14, и ваш тест прошел после одного небольшого изменения с:

 loss = tf.losses.mean_squared_error(y_true=labels, y_pred=logits)
  

Для:

 loss = tf.losses.mean_squared_error(labels, logits)