Skip to content

Commit

Permalink
Fixes "Shapes are incompatibe" error in DNNClassifier #4715 and adds …
Browse files Browse the repository at this point in the history
…tests.

Change: 135814833
  • Loading branch information
tensorflower-gardener committed Oct 11, 2016
1 parent 2c262c0 commit b718fd6
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 1 deletion.
14 changes: 14 additions & 0 deletions tensorflow/contrib/learn/python/learn/estimators/dnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ def _get_weight_tensor(features, weight_column_name):
shape=(-1,))


def _reshape_targets(targets):
""""Reshapes targets into [batch_size, 1] to be compatible with logits."""
check_shape_op = control_flow_ops.Assert(
math_ops.less_equal(array_ops.rank(targets), 2),
["targets shape should be either [batch_size, 1] or [batch_size]"])
with ops.control_dependencies([check_shape_op]):
targets = array_ops.reshape(targets,
shape=[array_ops.shape(targets)[0], 1])

return targets


def _rescale_eval_loss(loss, weights):
"""Rescales evaluation loss according to the given weights.
Expand Down Expand Up @@ -254,6 +266,7 @@ def _dnn_classifier_model_fn(features, targets, mode, params):
logits = nn.bias_add(logits, _centered_bias(num_label_columns))

if mode == estimator.ModeKeys.TRAIN:
targets = _reshape_targets(targets)
loss = loss_fn(logits, targets,
weight=_get_weight_tensor(features, weight_column_name))

Expand All @@ -269,6 +282,7 @@ def _dnn_classifier_model_fn(features, targets, mode, params):
elif mode == estimator.ModeKeys.EVAL:
predictions = _predictions(logits=logits, n_classes=n_classes)

targets = _reshape_targets(targets)
weight = _get_weight_tensor(features, weight_column_name)
training_loss = loss_fn(logits, targets, weight=weight)
loss = _rescale_eval_loss(training_loss, weight)
Expand Down
107 changes: 107 additions & 0 deletions tensorflow/contrib/learn/python/learn/estimators/dnn_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,41 @@ def testLogisticRegression_MatrixData(self):
self.assertGreater(scores['accuracy'], 0.9)
self.assertLess(scores['loss'], 0.3)

def testLogisticRegression_MatrixData_Target1D(self):
"""Same as the last test, but target shape is [100] instead of [100, 1]."""
def _input_fn():
iris = _prepare_iris_data_for_logistic_regression()
return {
'feature': tf.constant(iris.data, dtype=tf.float32)
}, tf.constant(iris.target, shape=[100], dtype=tf.int32)

cont_features = [
tf.contrib.layers.real_valued_column('feature', dimension=4)]

classifier = tf.contrib.learn.DNNClassifier(
feature_columns=cont_features,
hidden_units=[3, 3],
config=tf.contrib.learn.RunConfig(tf_random_seed=1))

classifier.fit(input_fn=_input_fn, steps=100)
scores = classifier.evaluate(input_fn=_input_fn, steps=1)
self.assertGreater(scores['accuracy'], 0.9)

def testLogisticRegression_NpMatrixData(self):
"""Tests binary classification using numpy matrix data as input."""
iris = _prepare_iris_data_for_logistic_regression()
train_x = iris.data
train_y = iris.target
feature_columns = [tf.contrib.layers.real_valued_column('', dimension=4)]
classifier = tf.contrib.learn.DNNClassifier(
feature_columns=feature_columns,
hidden_units=[3, 3],
config=tf.contrib.learn.RunConfig(tf_random_seed=1))

classifier.fit(x=train_x, y=train_y, steps=100)
scores = classifier.evaluate(x=train_x, y=train_y, steps=1)
self.assertGreater(scores['accuracy'], 0.8)

def testLogisticRegression_TensorData(self):
"""Tests binary classification using tensor data as input."""
def _input_fn(num_epochs=None):
Expand Down Expand Up @@ -166,6 +201,43 @@ def testMultiClass_MatrixData(self):
self.assertGreater(scores['accuracy'], 0.8)
self.assertLess(scores['loss'], 0.3)

def testMultiClass_MatrixData_Target1D(self):
"""Same as the last test, but target shape is [150] instead of [150, 1]."""
def _input_fn():
iris = tf.contrib.learn.datasets.load_iris()
return {
'feature': tf.constant(iris.data, dtype=tf.float32)
}, tf.constant(iris.target, shape=[150], dtype=tf.int32)

cont_features = [
tf.contrib.layers.real_valued_column('feature', dimension=4)]

classifier = tf.contrib.learn.DNNClassifier(
n_classes=3,
feature_columns=cont_features,
hidden_units=[3, 3],
config=tf.contrib.learn.RunConfig(tf_random_seed=1))

classifier.fit(input_fn=_input_fn, steps=200)
scores = classifier.evaluate(input_fn=_input_fn, steps=1)
self.assertGreater(scores['accuracy'], 0.8)

def testMultiClass_NpMatrixData(self):
"""Tests multi-class classification using numpy matrix data as input."""
iris = tf.contrib.learn.datasets.load_iris()
train_x = iris.data
train_y = iris.target
feature_columns = [tf.contrib.layers.real_valued_column('', dimension=4)]
classifier = tf.contrib.learn.DNNClassifier(
n_classes=3,
feature_columns=feature_columns,
hidden_units=[3, 3],
config=tf.contrib.learn.RunConfig(tf_random_seed=3))

classifier.fit(x=train_x, y=train_y, steps=200)
scores = classifier.evaluate(x=train_x, y=train_y, steps=1)
self.assertGreater(scores['accuracy'], 0.8)

def testLoss(self):
"""Tests loss calculation."""

Expand Down Expand Up @@ -525,6 +597,41 @@ def testRegression_MatrixData(self):
scores = regressor.evaluate(input_fn=_iris_input_logistic_fn, steps=1)
self.assertLess(scores['loss'], 0.3)

def testRegression_MatrixData_Target1D(self):
"""Same as the last test, but target shape is [100] instead of [100, 1]."""
def _input_fn():
iris = _prepare_iris_data_for_logistic_regression()
return {
'feature': tf.constant(iris.data, dtype=tf.float32)
}, tf.constant(iris.target, shape=[100], dtype=tf.int32)

cont_features = [
tf.contrib.layers.real_valued_column('feature', dimension=4)]

regressor = tf.contrib.learn.DNNRegressor(
feature_columns=cont_features,
hidden_units=[3, 3],
config=tf.contrib.learn.RunConfig(tf_random_seed=1))

regressor.fit(input_fn=_input_fn, steps=200)
scores = regressor.evaluate(input_fn=_input_fn, steps=1)
self.assertLess(scores['loss'], 0.3)

def testRegression_NpMatrixData(self):
"""Tests binary classification using numpy matrix data as input."""
iris = _prepare_iris_data_for_logistic_regression()
train_x = iris.data
train_y = iris.target
feature_columns = [tf.contrib.layers.real_valued_column('', dimension=4)]
regressor = tf.contrib.learn.DNNRegressor(
feature_columns=feature_columns,
hidden_units=[3, 3],
config=tf.contrib.learn.RunConfig(tf_random_seed=1))

regressor.fit(x=train_x, y=train_y, steps=200)
scores = regressor.evaluate(x=train_x, y=train_y, steps=1)
self.assertLess(scores['loss'], 0.3)

def testRegression_TensorData(self):
"""Tests regression using tensor data as input."""
def _input_fn(num_epochs=None):
Expand Down
93 changes: 92 additions & 1 deletion tensorflow/contrib/learn/python/learn/estimators/linear_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@
from tensorflow.contrib.learn.python.learn.metric_spec import MetricSpec


def _prepare_iris_data_for_logistic_regression():
# Converts iris data to a logistic regression problem.
iris = tf.contrib.learn.datasets.load_iris()
ids = np.where((iris.target == 0) | (iris.target == 1))
iris = tf.contrib.learn.datasets.base.Dataset(data=iris.data[ids],
target=iris.target[ids])
return iris


def _iris_input_fn():
iris = tf.contrib.learn.datasets.load_iris()
return {
Expand Down Expand Up @@ -92,7 +101,7 @@ def input_fn():
self.assertLess(loss2, 0.01)
self.assertTrue('centered_bias_weight' in classifier.get_variable_names())

def testMultiClass(self):
def testMultiClass_MatrixData(self):
"""Tests multi-class classification using matrix data as input."""
feature_column = tf.contrib.layers.real_valued_column('feature',
dimension=4)
Expand All @@ -105,6 +114,88 @@ def testMultiClass(self):
scores = classifier.evaluate(input_fn=_iris_input_fn, steps=100)
self.assertGreater(scores['accuracy'], 0.9)

def testMultiClass_MatrixData_Target1D(self):
"""Same as the last test, but target shape is [150] instead of [150, 1]."""
def _input_fn():
iris = tf.contrib.learn.datasets.load_iris()
return {
'feature': tf.constant(iris.data, dtype=tf.float32)
}, tf.constant(iris.target, shape=[150], dtype=tf.int32)

feature_column = tf.contrib.layers.real_valued_column('feature',
dimension=4)

classifier = tf.contrib.learn.LinearClassifier(
n_classes=3,
feature_columns=[feature_column])

classifier.fit(input_fn=_input_fn, steps=100)
scores = classifier.evaluate(input_fn=_input_fn, steps=1)
self.assertGreater(scores['accuracy'], 0.9)

def testMultiClass_NpMatrixData(self):
"""Tests multi-class classification using numpy matrix data as input."""
iris = tf.contrib.learn.datasets.load_iris()
train_x = iris.data
train_y = iris.target
feature_column = tf.contrib.layers.real_valued_column('', dimension=4)
classifier = tf.contrib.learn.LinearClassifier(
n_classes=3,
feature_columns=[feature_column])

classifier.fit(x=train_x, y=train_y, steps=100)
scores = classifier.evaluate(x=train_x, y=train_y, steps=1)
self.assertGreater(scores['accuracy'], 0.9)

def testLogisticRegression_MatrixData(self):
"""Tests binary classification using matrix data as input."""
def _input_fn():
iris = _prepare_iris_data_for_logistic_regression()
return {
'feature': tf.constant(iris.data, dtype=tf.float32)
}, tf.constant(iris.target, shape=[100, 1], dtype=tf.int32)

feature_column = tf.contrib.layers.real_valued_column('feature',
dimension=4)

classifier = tf.contrib.learn.LinearClassifier(
feature_columns=[feature_column])

classifier.fit(input_fn=_input_fn, steps=100)
scores = classifier.evaluate(input_fn=_input_fn, steps=1)
self.assertGreater(scores['accuracy'], 0.9)

def testLogisticRegression_MatrixData_Target1D(self):
"""Same as the last test, but target shape is [100] instead of [100, 1]."""
def _input_fn():
iris = _prepare_iris_data_for_logistic_regression()
return {
'feature': tf.constant(iris.data, dtype=tf.float32)
}, tf.constant(iris.target, shape=[100], dtype=tf.int32)

feature_column = tf.contrib.layers.real_valued_column('feature',
dimension=4)

classifier = tf.contrib.learn.LinearClassifier(
feature_columns=[feature_column])

classifier.fit(input_fn=_input_fn, steps=100)
scores = classifier.evaluate(input_fn=_input_fn, steps=1)
self.assertGreater(scores['accuracy'], 0.9)

def testLogisticRegression_NpMatrixData(self):
"""Tests binary classification using numpy matrix data as input."""
iris = _prepare_iris_data_for_logistic_regression()
train_x = iris.data
train_y = iris.target
feature_columns = [tf.contrib.layers.real_valued_column('', dimension=4)]
classifier = tf.contrib.learn.LinearClassifier(
feature_columns=feature_columns)

classifier.fit(x=train_x, y=train_y, steps=100)
scores = classifier.evaluate(x=train_x, y=train_y, steps=1)
self.assertGreater(scores['accuracy'], 0.9)

def testWeightAndBiasNames(self):
"""Tests that weight and bias names haven't changed."""
feature_column = tf.contrib.layers.real_valued_column('feature',
Expand Down

0 comments on commit b718fd6

Please sign in to comment.