crossEntropy

cross entropy loss (logsoftmax -> negative loglikelihood function)

crossEntropy
(
alias Storage
)
(
Variable!(float, 2, Storage) x
,
Variable!(int, 1, Storage) t
,
int ignoreIndex = -100
)

Examples

test variable.backward

1 /* pytorch equivalent
2    >>> x = torch.tensor([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], requires_grad=True)
3    >>> t = torch.tensor([1, 0, -100], dtype=torch.long)
4    >>> l = torch.nn.functional.cross_entropy(x, t)
5    >>> l
6    tensor(0.6944)
7    >>> l.backward()
8    >>> x.grad
9    tensor([[ 0.2375, -0.2375],
10            [-0.2625,  0.2625],
11            [ 0.0000,  0.0000]])
12  */
13 import std.stdio;
14 import std.typecons;
15 import mir.ndslice;
16 import grain.autograd;
17 import numir;
18 static import grain.config;
19 grain.config.backprop = true;
20 
21 auto hx = [[0.1f, 0.2f], [0.3f, 0.4f], [0.5f, 0.6f]].variable(true);
22 auto ht = [1, 0, -100].variable;
23 auto hl = crossEntropy(hx, ht);
24 hl.backward();
25 assert(approxEqual(hx.gradSliced, [[0.2375, -0.2375], [-0.2625, 0.2625],
26         [0.0000, 0.0000]].nparray));
27 
28 version (grain_cuda) {
29     auto dx = hx.to!DeviceStorage;
30     dx.grad.zero_();
31     auto dt = ht.to!DeviceStorage;
32     auto dl = crossEntropy(dx, dt);
33     assert(approxEqual(hl.sliced, dl.to!HostStorage.sliced));
34     dl.backward();
35     assert(approxEqual(dx.to!HostStorage.gradSliced, hx.gradSliced));
36 }

Meta