Использование DNNLinearCombinedEstimator в тензорном потоке для классификации по нескольким меткам

У меня есть набор данных с несколькими метками, и я хотел бы использовать нейронную сеть шириной n и глубиной для классификации образцов.

Это очень маленький пример для тестирования:

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

tf.enable_eager_execution()

training_df: pd.DataFrame = pd.DataFrame(
    data={
        'feature1': np.random.rand(10),
        'feature2': np.random.rand(10),
        'feature3': np.random.rand(10),
        'feature4': np.random.randint(0, 3, 10),
        'feature5': np.random.randint(0, 3, 10),
        'feature6': np.random.randint(0, 3, 10),
        'target1': np.random.randint(0, 2, 10),
        'target2': np.random.randint(0, 2, 10),
        'target3': np.random.randint(0, 2, 10)
    }
)
features = ['feature1', 'feature2', 'feature3','feature4', 'feature5', 'feature6']
targets = ['target1', 'target2', 'target3']
Categorical_Cols = ['feature4', 'feature5', 'feature6']
Numerical_Cols = ['feature1', 'feature2', 'feature3']


wide_columns = [tf.feature_column.categorical_column_with_vocabulary_list(key=x, vocabulary_list=[0, 1, -1])
                                    for x in Categorical_Cols]


deep_columns = [tf.feature_column.numeric_column(x) for x in Numerical_Cols]


def wrap_dataset(df, features, labels):
  dataset = (
      tf.data.Dataset.from_tensor_slices(
          (
              tf.cast(df[features].values, tf.float32),
              tf.cast(df[labels].values, tf.int32),
          )
      )
  )

  return(dataset)

input_fn_train = wrap_dataset(training_df, features, targets)

m = tf.contrib.estimator.DNNLinearCombinedEstimator(
          head=tf.contrib.estimator.multi_label_head(n_classes=2),
          # wide settings
          linear_feature_columns=wide_columns,
          #     linear_optimizer=tf.train.FtrlOptimizer(...),
          # deep settings
          dnn_feature_columns=deep_columns,
          #     dnn_optimizer=tf.train.ProximalAdagradOptimizer(...),
          dnn_hidden_units=[10, 30, 10])

m.train(input_fn=input_fn_train)

В этом примере у нас есть 6 функций, включая:

  • 3 числовых признака: feature1, feature2 и feature3.
  • 3 категориальных функции: feature4, feature5 и feature6.

где каждый образец имеет три метки, и каждая метка имеет двоичное значение: 0 или 1.

Ошибка связана с функцией ввода, и я не могу понять, как правильно определить функцию ввода. Любая помощь по исправлению кода приветствуется.

ОБНОВЛЕНИЕ: ошибка:

TypeError: <TensorSliceDataset shapes: ((6,), (3,)), types: (tf.float32, tf.int32)> is not a callable object

person user4704857    schedule 26.01.2019    source источник
comment
Можете ли вы опубликовать, в чем ваша ошибка?   -  person kvish    schedule 27.01.2019
comment
Я просто добавил ошибку к своему вопросу.   -  person user4704857    schedule 27.01.2019


Ответы (2)


Поскольку он говорит, что это не вызываемый объект, вы можете просто добавить лямбда, и он должен работать

input_fn_train = lambda: wrap_dataset(training_df, features, targets)

Также я думаю, вам нужно разобраться, как вы передаете данные в Оценщик. Могут потребоваться словари, поскольку вы используете столбцы функций. Прямо сейчас вы передаете тензоры, а не словарь тензоров. Прочтите этот полезный пост.

person kvish    schedule 27.01.2019

Наконец, я понял, как заставить код работать. Я размещаю его здесь, чтобы помочь людям, которые хотели бы провести классификацию по нескольким меткам, используя встроенную функцию DNNLinearCombinedEstimator из пакета tensorflow версии 1.13.

import numpy as np
import pandas as pd
import tensorflow as tf
# from tensorflow import contrib
tf.enable_eager_execution()

training_df: pd.DataFrame = pd.DataFrame(
    data={
        'feature1': np.random.rand(10),
        'feature2': np.random.rand(10),
        'feature3': np.random.rand(10),
        'feature4': np.random.randint(0, 3, 10),
        'feature5': np.random.randint(0, 3, 10),
        'feature6': np.random.randint(0, 3, 10),
        'target1': np.random.randint(0, 2, 10),
        'target2': np.random.randint(0, 2, 10),
        'target3': np.random.randint(0, 2, 10)
    }
)
features = ['feature1', 'feature2', 'feature3','feature4', 'feature5', 'feature6']
targets = ['target1', 'target2', 'target3']
Categorical_Cols = ['feature4', 'feature5', 'feature6']
Numerical_Cols = ['feature1', 'feature2', 'feature3']


wide_columns = [tf.feature_column.categorical_column_with_vocabulary_list(key=x, vocabulary_list=[0, 1, -1])
                                    for x in Categorical_Cols]


deep_columns = [tf.feature_column.numeric_column(x) for x in Numerical_Cols]


def input_fn(df):
  # Creates a dictionary mapping from each continuous feature column name (k) to
  # the values of that column stored in a constant Tensor.
  continuous_cols = {k: tf.constant(df[k].values)
                     for k in Numerical_Cols}
  # Creates a dictionary mapping from each categorical feature column name (k)
  # to the values of that column stored in a tf.SparseTensor.
  categorical_cols = {k: tf.SparseTensor(
      indices=[[i, 0] for i in range(df[k].size)],
      values=df[k].values,
      dense_shape=[df[k].size, 1])
                      for k in Categorical_Cols}
  # Merges the two dictionaries into one.
  feature_cols = continuous_cols.copy()
  feature_cols.update(categorical_cols)

  labels =tf.convert_to_tensor(training_df.as_matrix(training_df[targets].columns.tolist()), dtype=tf.int32)

  return feature_cols, labels



def train_input_fn():
  return input_fn(training_df)

def eval_input_fn():
  return input_fn(training_df)



m = tf.contrib.learn.DNNLinearCombinedEstimator(
          head=tf.contrib.learn.multi_label_head(n_classes=3),
          # wide settings
          linear_feature_columns=wide_columns,
          #     linear_optimizer=tf.train.FtrlOptimizer(...),
          # deep settings
          dnn_feature_columns=deep_columns,
          #     dnn_optimizer=tf.train.ProximalAdagradOptimizer(...),
          dnn_hidden_units=[10, 10])

m.train(input_fn=train_input_fn, steps=20)
results = m.evaluate(input_fn=eval_input_fn, steps=1)
print("#########################################################")
for key in sorted(results):
    print("%s: %s" % (key, results[key]))
person user4704857    schedule 01.02.2019