UNPKG

@tensorflow/tfjs-core

Version:

Hardware-accelerated JavaScript library for machine intelligence

190 lines 8.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tf = require("../index"); var test_util_1 = require("../test_util"); var jasmine_util_1 = require("../jasmine_util"); jasmine_util_1.describeWithFlags('softmax', test_util_1.ALL_ENVS, function () { it('regular test', function () { var y = tf.softmax(tf.tensor1d([2, 1, 3])); test_util_1.expectArraysClose(y, [0.24472847, 0.09003057, 0.66524095]); test_util_1.expectNumbersClose(y.get(0) + y.get(1) + y.get(2), 1); }); it('overflow', function () { var y = tf.softmax(tf.tensor1d([1000, 1000])); test_util_1.expectArraysClose(y, [0.5, 0.5]); }); it('underflow', function () { var y = tf.softmax(tf.tensor1d([-1000, -1000])); test_util_1.expectArraysClose(y, [0.5, 0.5]); }); it('Huge difference between probabilities', function () { var y = tf.softmax(tf.tensor1d([-1000, +1000])); test_util_1.expectArraysClose(y, [0, 1]); }); it('Propagates NaNs', function () { var a = tf.tensor1d([2, 1, NaN]); var y = tf.softmax(a); test_util_1.expectArraysClose(y, [NaN, NaN, NaN]); }); it('2D, dim=1', function () { var y = tf.softmax(tf.tensor2d([[2, 1, 3], [1, 3, 2]], [2, 3]), 1); var expected = [ 0.24472847, 0.09003057, 0.66524095, 0.09003057, 0.66524095, 0.24472847 ]; expect(y.rank).toBe(2); test_util_1.expectArraysClose(y, expected); }); it('2D, implicit dim=1', function () { var y = tf.softmax(tf.tensor2d([[2, 1, 3], [1, 3, 2]], [2, 3])); var expected = [ 0.24472847, 0.09003057, 0.66524095, 0.09003057, 0.66524095, 0.24472847 ]; expect(y.rank).toBe(2); test_util_1.expectArraysClose(y, expected); }); it('2D, dim=0 throws error', function () { var f = function () { tf.softmax(tf.tensor2d([[2, 1, 3], [1, 3, 2]], [2, 3]), 0); }; expect(f).toThrowError(); }); it('1D gradient', function () { var x = tf.tensor1d([10, 0, -1]); var y = tf.softmax(x); var dy = tf.tensor1d([1, 2, 3]); var dx = tf.grad(function (x) { return x.softmax(); })(x, dy); var totalSum = tf.sum(tf.mul(dy, y)); expect(dx.shape).toEqual(x.shape); test_util_1.expectArraysClose(dx, [ (dy.get(0) - totalSum.get()) * y.get(0), (dy.get(1) - totalSum.get()) * y.get(1), (dy.get(2) - totalSum.get()) * y.get(2) ]); }); it('2D gradient', function () { var x = tf.tensor2d([10, 0, -1, 5, 4, 3], [2, 3]); var y = tf.softmax(x); var dy = tf.tensor2d([3, 2, 1, 1, 2, 3], [2, 3]); var dx = tf.grad(function (x) { return x.softmax(); })(x, dy); var axis = -1; var totalSum = tf.sum(tf.mulStrict(dy, y), axis); expect(dx.shape).toEqual(x.shape); test_util_1.expectArraysClose(dx, [ (dy.get(0, 0) - totalSum.get(0)) * y.get(0, 0), (dy.get(0, 1) - totalSum.get(0)) * y.get(0, 1), (dy.get(0, 2) - totalSum.get(0)) * y.get(0, 2), (dy.get(1, 0) - totalSum.get(1)) * y.get(1, 0), (dy.get(1, 1) - totalSum.get(1)) * y.get(1, 1), (dy.get(1, 2) - totalSum.get(1)) * y.get(1, 2) ]); }); it('throws when passed a non-tensor', function () { expect(function () { return tf.softmax({}); }) .toThrowError(/Argument 'logits' passed to 'softmax' must be a Tensor/); }); }); jasmine_util_1.describeWithFlags('softmaxCrossEntropy', test_util_1.ALL_ENVS, function () { it('1D', function () { var logits = tf.tensor1d([1, 2, 3]); var label = tf.tensor1d([0.3, 0.6, 0.1]); var softmaxLogits = tf.softmax(logits); var y = tf.losses.softmaxCrossEntropy(label, logits); expect(y.shape).toEqual([]); test_util_1.expectNumbersClose(y.get(), -Math.log(softmaxLogits.get(0)) * label.get(0) + -Math.log(softmaxLogits.get(1)) * label.get(1) + -Math.log(softmaxLogits.get(2)) * label.get(2)); }); it('2D implicit dim', function () { var logits = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3]); var label = tf.tensor2d([0.3, 0.6, 0.1, 0.2, 0.3, 0.5], [2, 3]); var softmaxLogits = tf.softmax(logits); var y = tf.losses.softmaxCrossEntropy(label, logits); expect(y.shape).toEqual([2]); test_util_1.expectArraysClose(y, [ -Math.log(softmaxLogits.get(0, 0)) * label.get(0, 0) + -Math.log(softmaxLogits.get(0, 1)) * label.get(0, 1) + -Math.log(softmaxLogits.get(0, 2)) * label.get(0, 2), -Math.log(softmaxLogits.get(1, 0)) * label.get(1, 0) + -Math.log(softmaxLogits.get(1, 1)) * label.get(1, 1) + -Math.log(softmaxLogits.get(1, 2)) * label.get(1, 2) ]); }); it('2D, dim=1', function () { var logits = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3]); var label = tf.tensor2d([0.3, 0.6, 0.1, 0.2, 0.3, 0.5], [2, 3]); var dim = 1; var softmaxLogits = tf.softmax(logits, dim); var y = tf.losses.softmaxCrossEntropy(label, logits, dim); expect(y.shape).toEqual([2]); test_util_1.expectArraysClose(y, [ -Math.log(softmaxLogits.get(0, 0)) * label.get(0, 0) + -Math.log(softmaxLogits.get(0, 1)) * label.get(0, 1) + -Math.log(softmaxLogits.get(0, 2)) * label.get(0, 2), -Math.log(softmaxLogits.get(1, 0)) * label.get(1, 0) + -Math.log(softmaxLogits.get(1, 1)) * label.get(1, 1) + -Math.log(softmaxLogits.get(1, 2)) * label.get(1, 2) ]); }); it('2D, dim=0 throws error', function () { var logits = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3]); var label = tf.tensor2d([0.3, 0.6, 0.1, 0.2, 0.3, 0.5], [2, 3]); var dim = 0; expect(function () { return tf.losses.softmaxCrossEntropy(label, logits, dim); }) .toThrowError(); }); it('Propagates NaNs', function () { var logits = tf.tensor1d([1, 2, NaN]); var label = tf.tensor1d([0.3, 0.6, 0.1]); var y = tf.losses.softmaxCrossEntropy(label, logits); expect(y.shape).toEqual([]); test_util_1.expectArraysClose(y, [NaN]); }); it('1D gradient', function () { var logits = tf.tensor1d([1, 2, 3]); var labels = tf.tensor1d([0.3, 0.6, 0.1]); var softmaxLogits = tf.softmax(logits); var dy = tf.scalar(2); var grads = tf.grads(function (labels, logits) { return tf.losses.softmaxCrossEntropy(labels, logits); }); var _a = grads([labels, logits], dy), dlabels = _a[0], dlogits = _a[1]; expect(dlogits.shape).toEqual(logits.shape); test_util_1.expectArraysClose(dlogits, [ dy.get() * (softmaxLogits.get(0) - labels.get(0)), dy.get() * (softmaxLogits.get(1) - labels.get(1)), dy.get() * (softmaxLogits.get(2) - labels.get(2)) ]); expect(dlabels.shape).toEqual(labels.shape); test_util_1.expectArraysClose(dlabels, [ dy.get() * (labels.get(0) - softmaxLogits.get(0)), dy.get() * (labels.get(1) - softmaxLogits.get(1)), dy.get() * (labels.get(2) - softmaxLogits.get(2)) ]); }); it('2D gradient', function () { var logits = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3]); var labels = tf.tensor2d([0.3, 0.6, 0.1, .2, .3, .5], [2, 3]); var softmaxLogits = tf.softmax(logits); var dy = tf.tensor1d([2, 4]); var dlogits = tf.grad(function (logits) { return tf.losses.softmaxCrossEntropy(labels, logits); })(logits, dy); expect(dlogits.shape).toEqual(logits.shape); test_util_1.expectArraysClose(dlogits, [ dy.get(0) * (softmaxLogits.get(0, 0) - labels.get(0, 0)), dy.get(0) * (softmaxLogits.get(0, 1) - labels.get(0, 1)), dy.get(0) * (softmaxLogits.get(0, 2) - labels.get(0, 2)), dy.get(1) * (softmaxLogits.get(1, 0) - labels.get(1, 0)), dy.get(1) * (softmaxLogits.get(1, 1) - labels.get(1, 1)), dy.get(1) * (softmaxLogits.get(1, 2) - labels.get(1, 2)) ]); }); it('throws when passed labels as a non-tensor', function () { var e = /Argument 'labels' passed to 'softmaxCrossEntropy' must be a Tensor/; expect(function () { return tf.losses.softmaxCrossEntropy({}, tf.tensor1d([ 1 ])); }).toThrowError(e); }); it('throws when passed logits as a non-tensor', function () { var e = /Argument 'logits' passed to 'softmaxCrossEntropy' must be a Tensor/; expect(function () { return tf.losses.softmaxCrossEntropy(tf.tensor1d([1]), {}); }) .toThrowError(e); }); }); //# sourceMappingURL=softmax_test.js.map