/
softargmax.js
62 lines (57 loc) · 1.33 KB
/
softargmax.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import Layer from './base.js'
import Matrix from '../../../util/matrix.js'
/**
* Softargmax layer
*/
export default class SoftargmaxLayer extends Layer {
/**
* @param {object} config config
* @param {number} [config.beta] beta
*/
constructor({ beta = 10000, ...rest }) {
super(rest)
this._beta = beta
}
calc(x) {
this._i = x
this._o = Matrix.map(this._i, v => this._beta * v)
this._o.sub(this._o.max(1))
this._o.map(Math.exp)
this._o.div(this._o.sum(1))
const idx = Matrix.zeros(1, this._o.cols)
for (let i = 0; i < idx.cols; i++) {
idx.set(0, i, i)
}
return Matrix.mult(this._o, idx).sum(1)
}
grad(bo) {
this._bo = new Matrix(this._o.rows, this._o.cols)
for (let j = 0; j < this._o.cols; j++) {
this._bo.set(0, j, Matrix.mult(bo, j))
}
const o = this._i.copy()
o.sub(o.max(1))
o.map(Math.exp)
o.div(o.sum(1))
this._bi = new Matrix(this._o.rows, this._o.cols)
for (let k = 0; k < this._bo.rows; k++) {
for (let i = 0; i < this._bo.cols; i++) {
const oki = o.at(k, i)
let bki = 0
for (let j = 0; j < this._bo.cols; j++) {
const v = i === j ? 1 - oki : -oki
bki += o.at(k, j) * v * this._bo.at(k, j)
}
this._bi.set(k, i, bki)
}
}
return this._bi
}
toObject() {
return {
type: 'softargmax',
beta: this._beta,
}
}
}
SoftargmaxLayer.registLayer()