Skip to content

Commit 2ba9be2

Browse files
committed
Merge pull request #1209 from lamblin/micklat-fix_mlp_softmax_misclass_rebased
Fix mlp softmax misclass and cost_from_X when the top layer is Softmax with binary_target_dim
2 parents ac445f5 + 54b0ee2 commit 2ba9be2

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

pylearn2/models/mlp.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ def cost_from_X_data_specs(self):
11311131
This is useful if cost_from_X is used in a MethodCost.
11321132
"""
11331133
space = CompositeSpace((self.get_input_space(),
1134-
self.get_output_space()))
1134+
self.get_target_space()))
11351135
source = (self.get_input_source(), self.get_target_source())
11361136
return (space, source)
11371137

@@ -1315,7 +1315,8 @@ def get_layer_monitoring_channels(self, state_below=None,
13151315

13161316
if targets is not None:
13171317
y_hat = T.argmax(state, axis=1)
1318-
y = T.argmax(targets, axis=1)
1318+
y = (targets.reshape(y_hat.shape) if self._has_binary_target
1319+
else T.argmax(targets, axis=1))
13191320
misclass = T.neq(y, y_hat).mean()
13201321
misclass = T.cast(misclass, config.floatX)
13211322
rval['misclass'] = misclass

pylearn2/models/tests/test_mlp.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,46 @@ def test_softmax_binary_targets():
400400
np.testing.assert_allclose(cost_bin(X_data, y_bin_data),
401401
cost_vec(X_data, y_vec_data))
402402

403+
def test_softmax_bin_targets_channels(seed=0):
404+
"""
405+
Constructs softmax layers with binary target and with vector targets
406+
to check that they give the same 'misclass' channel value.
407+
"""
408+
np.random.seed(seed)
409+
num_classes = 2
410+
batch_size = 5
411+
mlp_bin = MLP(
412+
layers=[Softmax(num_classes, 's1', irange=0.1,
413+
binary_target_dim=1)],
414+
nvis=100
415+
)
416+
mlp_vec = MLP(
417+
layers=[Softmax(num_classes, 's1', irange=0.1)],
418+
nvis=100
419+
)
420+
421+
X = mlp_bin.get_input_space().make_theano_batch()
422+
y_bin = mlp_bin.get_target_space().make_theano_batch()
423+
y_vec = mlp_vec.get_target_space().make_theano_batch()
424+
425+
X_data = np.random.random(size=(batch_size, 100))
426+
X_data = X_data.astype(theano.config.floatX)
427+
y_bin_data = np.random.randint(low=0, high=num_classes,
428+
size=(batch_size, 1))
429+
y_vec_data = np.zeros((batch_size, num_classes), dtype=theano.config.floatX)
430+
y_vec_data[np.arange(batch_size),y_bin_data.flatten()] = 1
431+
432+
def channel_value(channel_name, model, y, y_data):
433+
chans = model.get_monitoring_channels((X,y))
434+
f_channel = theano.function([X,y], chans['s1_'+channel_name])
435+
return f_channel(X_data, y_data)
436+
437+
for channel_name in ['misclass', 'nll']:
438+
vec_val = channel_value(channel_name, mlp_vec, y_vec, y_vec_data)
439+
bin_val = channel_value(channel_name, mlp_bin, y_bin, y_bin_data)
440+
print channel_name, vec_val, bin_val
441+
np.testing.assert_allclose(vec_val, bin_val)
442+
403443
def test_set_get_weights_Softmax():
404444
"""
405445
Tests setting and getting weights for Softmax layer.

0 commit comments

Comments
 (0)