简单的问题。是否有针对它的操作,如何创建一个单位矩阵?我已经检查了文档,但是找不到单个操作。
答案 0 :(得分:0)
对于身份矩阵,您可以使用tf.eye()
,但不确定通过反转矩阵的含义,但是它可以是执行元素1/x
的{{3}}或您想要进行转置,可以使用tf.reciprocal()
。
答案 1 :(得分:0)
现在tensorflowJs没有任何可以返回矩阵M逆的直接运算符。 您可以考虑使用模块Math.js
话虽如此,可以使用tensorflowJs运算符求矩阵求逆。
以下内容使用 adjoint方法和tensorflowJs运算符来计算矩阵的逆。
// calculate the determinant of a matrix m
function det(m) {
return tf.tidy(() => {
const [r, _] = m.shape
if (r === 2) {
const t = m.as1D()
const a = t.slice([0], [1]).dataSync()[0]
const b = t.slice([1], [1]).dataSync()[0]
const c = t.slice([2], [1]).dataSync()[0]
const d = t.slice([3], [1]).dataSync()[0]
result = a * d - b * c
return result
} else {
let s = 0;
rows = [...Array(r).keys()]
for (let i = 0; i < r; i++) {
sub_m = m.gather(tf.tensor1d(rows.filter(e => e !== i), 'int32'))
sli = sub_m.slice([0, 1], [r - 1, r - 1])
s += Math.pow(-1, i) * det(sli)
}
return s
}
})
}
// the inverse of the matrix : matrix adjoint method
function invertMatrix(m) {
return tf.tidy(() => {
const d = det(m)
if (d === 0) {
return
}
[r, _] = m.shape
rows = [...Array(r).keys()]
dets = [];
for (let i = 0; i < r; i++) {
for (let j = 0; j < r; j++) {
const sub_m = m.gather(tf.tensor1d(rows.filter(e => e !== i), 'int32'))
let sli
if (j === 0) {
sli = sub_m.slice([0, 1], [r - 1, r - 1])
} else if (j === r - 1) {
sli = sub_m.slice([0, 0], [r - 1, r - 1])
} else {
const [a, b, c] = tf.split(sub_m, [j, 1, r - (j + 1)], 1)
sli = tf.concat([a, c], 1)
}
dets.push(Math.pow(-1, (i + j)) * det(sli))
}
}
com = tf.tensor2d(dets, [r, r])
tr_com = com.transpose()
inv_m = tr_com.div(tf.scalar(d))
return inv_m
})
}
const a = tf.tensor2d([1, 3, 3, 1, 4, 3, 1, 3, 4], [3, 3])
console.log("matrix a")
a.print()
const i = invertMatrix(a)
console.log("inverse i")
i.print()
const prod = i.dot(a)
console.log("a * i")
prod.print()
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0"> </script>
</head>
<body>
</body>
</html>
使用 Jordan-Gauss 方法,可以通过以下方式计算矩阵的逆:
// calculate the determinant of a matrix m
function det(m) {
return tf.tidy(() => {
const [r, _] = m.shape
if (r === 2) {
const t = m.as1D()
const a = t.slice([0], [1]).dataSync()[0]
const b = t.slice([1], [1]).dataSync()[0]
const c = t.slice([2], [1]).dataSync()[0]
const d = t.slice([3], [1]).dataSync()[0]
result = a * d - b * c
return result
} else {
let s = 0;
rows = [...Array(r).keys()]
for (let i = 0; i < r; i++) {
sub_m = m.gather(tf.tensor1d(rows.filter(e => e !== i), 'int32'))
sli = sub_m.slice([0, 1], [r - 1, r - 1])
s += Math.pow(-1, i) * det(sli)
}
return s
}
})
}
// the inverse of the matrix : jordan-gauss method
function invertM(m) {
return tf.tidy(() => {
if (det(m) === 0) {
return
}
const [r, _] = m.shape
let inv = m.concat(tf.eye(r), 1)
rows = [...Array(r).keys()]
for (let i = 0; i < r; i++) {
inv = tf.tidy(() => {
for (let j = i + 1; j < r; j++) {
const elt = inv.slice([j, i], [1, 1]).as1D().asScalar()
const pivot = inv.slice([i, i], [1, 1]).as1D().asScalar()
let newrow
if (elt.dataSync()[0] !== 0) {
newrow = inv.gather(tf.tensor1d([i], 'int32')).sub(inv.gather(tf.tensor1d([j], 'int32')).div(elt).mul(pivot)).as1D()
const sli = inv.gather(rows.filter(e => e !== j))
const arr = []
if (j === 0) {
arr.push(newrow)
}
sli.unstack().forEach((t, ind) => {
if (ind !== j) {
arr.push(t)
} else {
arr.push(newrow)
arr.push(t)
}
})
if (j === r - 1) {
arr.push(newrow)
}
inv = tf.stack(arr)
}
}
return inv
})
}
const trian = tf.unstack(inv)
len = trian.length
trian[len - 1] = trian[len - 1].div(trian[len - 1].slice(trian[len - 1].shape[0] - 1, 1).asScalar())
for (let i = r - 2; i > -1; i--) {
for (j = r - 1; j > i; j--) {
trian[i] = trian[i].sub(trian[j].mul(trian[i].slice(j, 1).asScalar()))
}
trian[i] = trian[i].div(trian[i].slice(i, 1).asScalar())
}
return tf.split(tf.stack(trian), 2, 1)[1]
})
}
const a = tf.tensor2d([1, 3, 3, 1, 4, 3, 1, 3, 4], [3, 3])
console.log("matrix a")
a.print()
const i = invertM(a)
console.log("inverse i")
i.print()
const prod = i.dot(a)
console.log("a * i")
prod.print()
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0"> </script>
</head>
<body>
</body>
</html>