简体   繁体   中英

Error in training NN with TensorFlow: TypeError: 'Series' objects are mutable, thus they cannot be hashed

Yes, I missed to transform the target feature. I tried to write my code differently and transform the features in integer just after importing the dataset. Here the code:

import math
import tensorflow as tf
import numpy as np
import pandas as pd
from sklearn import preprocessing
from sklearn import metrics
from tensorflow.python.data import Dataset

FEATURES = ["cap-shape", "cap-surface", "cap-color", "bruises", "odor", "gill-attachment",
                              "gill-spacing", "gill-size", "gill-color", "stalk-shape", "stalk-root",
                              "stalk-surface-above-ring", "stalk-surface-below-ring", "stalk-color-above-ring",
                              "stalk-color-below-ring", "veil-type", "veil-color", "ring-number", "ring-type",
                              "spore-print-color", "population", "habitat"]


def preprocess_features(data):
    selected_features = data[["cap-shape", "cap-surface", "cap-color", "bruises", "odor", "gill-attachment",
                              "gill-spacing", "gill-size", "gill-color", "stalk-shape", "stalk-root",
                              "stalk-surface-above-ring", "stalk-surface-below-ring", "stalk-color-above-ring",
                              "stalk-color-below-ring", "veil-type", "veil-color", "ring-number", "ring-type",
                              "spore-print-color", "population", "habitat"]]
    processed_features = selected_features.copy()
    return processed_features


def preprocess_targets(data):
    output_targets = pd.DataFrame()
    output_targets["class"] = data["class"]
    return output_targets


def construct_feature_columns(features):
    return {tf.feature_column.numeric_column(my_feature) for my_feature in features}


def input_fn(features, targets, batch_size=1, num_epochs=None):
    features = {key: np.array(value) for key, value in dict(features).items()}

    ds = Dataset.from_tensor_slices((features, targets))
    ds = ds.batch(batch_size).repeat(num_epochs)

    features, labels = ds.make_one_shot_iterator().get_next()
    return features, labels


def train_nn_classifier_model(learning_rate, steps, batch_size, hidden_units, training_examples, training_targets,
                              validation_examples, validation_targets):
    global validation_root_mean_squared_error, training_root_mean_squared_error
    periods = 10
    steps_per_period = steps / periods

    my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
    my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
    train_dnn_classifier = tf.estimator.DNNClassifier(feature_columns=construct_feature_columns(training_examples),
                                                      hidden_units=hidden_units, optimizer=my_optimizer)

    training_input_fn = lambda: input_fn(training_examples, training_targets, batch_size)
    predict_training_input_fn = lambda: input_fn(training_examples, training_targets, num_epochs=1)
    predict_validation_input_fn = lambda: input_fn(validation_examples, validation_targets, num_epochs=1)

    print "Training model..."
    # Error array
    training_rmse = []
    validation_rmse = []
    for period in xrange(0, periods):
        train_dnn_classifier.train(input_fn=training_input_fn(), steps=steps_per_period)

        training_predictions = train_dnn_classifier.predict(input_fn=predict_training_input_fn)
        training_predictions = np.array([it['predictions'][0] for it in training_predictions])

        validation_predictions = train_dnn_classifier.predict(input_fn=predict_validation_input_fn)
        validation_predictions = np.array([it['predictions'][0] for it in validation_predictions])

        training_root_mean_squared_error = math.sqrt(metrics.mean_squared_error(training_predictions, training_targets))
        validation_root_mean_squared_error = math.sqrt(metrics.mean_squared_error(validation_predictions,
                                                                                  validation_targets))
        print "  period %02d : %0.2f" % (period, training_root_mean_squared_error)
        training_rmse.append(training_root_mean_squared_error)
        validation_rmse.append(validation_root_mean_squared_error)
    print "Model training finished."

    print "Final RMSE (on training data):   {:0.2f}".format(training_root_mean_squared_error)
    print "Final RMSE (on validation data): {:0.2f}".format(validation_root_mean_squared_error)

    return train_dnn_classifier


# Train & test set
data_set = pd.read_csv("mushrooms.csv")
for i in range(len(FEATURES)):
    encoder = preprocessing.LabelEncoder()
    encoder.fit(data_set[FEATURES[i]])
    data_set[FEATURES[i]] = encoder.transform(data_set[FEATURES[i]])

msk = np.random.rand(len(data_set)) < 0.8
train_set = data_set[msk]
test_set = data_set[~msk]

# Prepare training and validation on it
training = preprocess_features(train_set)
validation = preprocess_features(train_set)

training_targets = preprocess_targets(train_set)
validation_targets = preprocess_targets(train_set)

# Prepare test
test = preprocess_features(test_set)
test_targets = preprocess_targets(test_set)

dnn_classifier = train_nn_classifier_model(learning_rate=0.001, steps=100, batch_size=100, hidden_units=[10, 10],
                                           training_examples=training, training_targets=training_targets,
                                           validation_examples=validation, validation_targets=validation_targets)

predict_testing_input_fn = lambda: input_fn(test, test_targets, num_epochs=1)

test_predictions = dnn_classifier.predict(input_fn=predict_testing_input_fn)
test_predictions = np.array([item['predictions'][0] for item in test_predictions])

root_mean_squared_error = math.sqrt(metrics.mean_squared_error(test_predictions, test_targets))

print "Final RMSE (on test data): {0.2f}".format(root_mean_squared_error)

The specific part is

for i in range(len(FEATURES)):
    encoder = preprocessing.LabelEncoder()
    encoder.fit(data_set[FEATURES[i]])
    data_set[FEATURES[i]] = encoder.transform(data_set[FEATURES[i]])

The rest should work because I followed this tutorial from Google https://colab.research.google.com/notebooks/mlcc/intro_to_neural_nets.ipynb?utm_source=mlcc&utm_campaign=colab-external&utm_medium=referral&utm_content=introneuralnets-colab&hl=it#scrollTo=zvCqgNdzpaFg but I receive this error and I don't know how to fix it. Can you help me again?

Traceback (most recent call last):
  File "/Users/.../individual_task_3.py", line 112, in <module>
    validation_examples=validation, validation_targets=validation_targets)
  File "/Users/.../individual_task_3.py", line 66, in train_nn_classifier_model
    train_dnn_classifier.train(input_fn=training_input_fn(), steps=steps_per_period)
  File "/Users/.../venv/lib/python2.7/site-packages/tensorflow/python/estimator/estimator.py", line 352, in train
    loss = self._train_model(input_fn, hooks, saving_listeners)
  File "/Users/.../venv/lib/python2.7/site-packages/tensorflow/python/estimator/estimator.py", line 809, in _train_model
    input_fn, model_fn_lib.ModeKeys.TRAIN))
  File "/Users/.../venv/lib/python2.7/site-packages/tensorflow/python/estimator/estimator.py", line 668, in _get_features_and_labels_from_input_fn
    result = self._call_input_fn(input_fn, mode)
  File "/Users/.../venv/lib/python2.7/site-packages/tensorflow/python/estimator/estimator.py", line 751, in _call_input_fn
    input_fn_args = util.fn_args(input_fn)
  File "/Users/.../venv/lib/python2.7/site-packages/tensorflow/python/estimator/util.py", line 53, in fn_args
    args = tf_inspect.getfullargspec(fn).args
  File "/Users/.../venv/lib/python2.7/site-packages/tensorflow/python/util/tf_inspect.py", line 65, in getfullargspec
    if d.decorator_argspec is not None), spec_fn(target))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 816, in getargspec
    raise TypeError('{!r} is not a Python function'.format(func))
TypeError: ({'habitat': <tf.Tensor 'IteratorGetNext:8' shape=(?,) dtype=int64>, 'cap-surface': <tf.Tensor 'IteratorGetNext:3' shape=(?,) dtype=int64>, 'cap-shape': <tf.Tensor 'IteratorGetNext:2' shape=(?,) dtype=int64>, 'cap-color': <tf.Tensor 'IteratorGetNext:1' shape=(?,) dtype=int64>, 'stalk-color-above-ring': <tf.Tensor 'IteratorGetNext:14' shape=(?,) dtype=int64>, 'stalk-shape': <tf.Tensor 'IteratorGetNext:17' shape=(?,) dtype=int64>, 'ring-number': <tf.Tensor 'IteratorGetNext:11' shape=(?,) dtype=int64>, 'odor': <tf.Tensor 'IteratorGetNext:9' shape=(?,) dtype=int64>, 'gill-attachment': <tf.Tensor 'IteratorGetNext:4' shape=(?,) dtype=int64>, 'stalk-color-below-ring': <tf.Tensor 'IteratorGetNext:15' shape=(?,) dtype=int64>, 'stalk-surface-below-ring': <tf.Tensor 'IteratorGetNext:19' shape=(?,) dtype=int64>, 'gill-spacing': <tf.Tensor 'IteratorGetNext:7' shape=(?,) dtype=int64>, 'spore-print-color': <tf.Tensor 'IteratorGetNext:13' shape=(?,) dtype=int64>, 'gill-color': <tf.Tensor 'IteratorGetNext:5' shape=(?,) dtype=int64>, 'population': <tf.Tensor 'IteratorGetNext:10' shape=(?,) dtype=int64>, 'veil-color': <tf.Tensor 'IteratorGetNext:20' shape=(?,) dtype=int64>, 'ring-type': <tf.Tensor 'IteratorGetNext:12' shape=(?,) dtype=int64>, 'bruises': <tf.Tensor 'IteratorGetNext:0' shape=(?,) dtype=int64>, 'stalk-surface-above-ring': <tf.Tensor 'IteratorGetNext:18' shape=(?,) dtype=int64>, 'veil-type': <tf.Tensor 'IteratorGetNext:21' shape=(?,) dtype=int64>, 'stalk-root': <tf.Tensor 'IteratorGetNext:16' shape=(?,) dtype=int64>, 'gill-size': <tf.Tensor 'IteratorGetNext:6' shape=(?,) dtype=int64>}, <tf.Tensor 'IteratorGetNext:22' shape=(?, 1) dtype=string>) is not a Python function

The problem is that you're trying to create a set (using the set syntax {...} ) whose elements are panda.Series, which are not hashable, and hence cannot be put in sets or be used as keys to a dictionary, and tensorflow uses column names as keys in a dictionary.

It seems like if instead of passing Series objects you pass strings as the feature column names your code should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM