技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

行列操作周りのメモ

ニューラルネットワーク周りが行列だらけなので。
そして僕は数式では理解できず、コードで理解する人なのでメモ(汗

スカラー

といっても、基本的には単独の値を意味する

a = 1
b = 1.5
c = 1.2e5

ベクトル(一次テンソル)

スカラを直線状に並べたもの≒一次元配列

f:id:white-azalea:20210209235234p:plain

import numpy as np

a = np.array([1, 2, 3])
b = np.array([-1.1, 1.8e2, 3.14])

行列(二次テンソル

つってもこれも有名すぎるでしょう。

f:id:white-azalea:20210209235313p:plain

c = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

多次元テンソル

複数次元のテンソルのことです

d = np.array([
    [
        [1, 2, 3],
        [4, 5, 6]
    ],
    [
        [7, 8, 9],
        [10, 11, 12]
    ]
])

テンソルの次元変更を reshape

ソース

simple = np.array([i for i in range(24)])
reshaped = simple.reshape(4, 6)
print(reshaped)
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]

ソース

print(simple.reshape(2, 2, 2, 3))
[[[[ 0  1  2]
   [ 3  4  5]]

  [[ 6  7  8]
   [ 9 10 11]]]


 [[[12 13 14]
   [15 16 17]]

  [[18 19 20]
   [21 22 23]]]]

ソース

print(simple.reshape(2, 3, 4))
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

軸の変更

transposeテンソルの軸を変更できる。
インデックスを指定するので、順番に並べると何も変わらない

simple = np.array([
    [1, 2, 3, 4],
    [2, 0, 0, 0],
    [3, 0, 0, 0]
])
print(simple.transpose(0, 1))
[[1 2 3 4]
 [2 0 0 0]
 [3 0 0 0]]

入れ替えると転置する

print(simple.transpose(1, 0))
[[1 2 3]
 [2 0 0]
 [3 0 0]
 [4 0 0]]

もうちょい複雑なものだと

simple = np.array([
    [
        [1, 2, 3, 4],
        [2, 0, 0, 0],
        [3, 0, 0, 0]
    ],
    [
        [2, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
])

print(simple.transpose(0, 2, 1))
[[[1 2 3]
  [2 0 0]
  [3 0 0]
  [4 0 0]]

 [[2 0 0]
  [0 0 0]
  [0 0 0]
  [0 0 0]]]

他にも

print(simple.transpose(1, 0, 2))
[[[1 2 3 4]
  [2 0 0 0]]

 [[2 0 0 0]
  [0 0 0 0]]

 [[3 0 0 0]
  [0 0 0 0]]]

行列のスカラ倍

つってもこれは基本過ぎるか…
全要素に特定倍

a = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
])
print(a * 2)
[[ 2  4  6  8]
 [10 12 14 16]
 [18 20 22 24]]

行列の各要素の積

アダマール積とか言うらしい。
同じ座標同士の掛け算

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])
b = np.array([
    [0, 1, 2],
    [3, 4, 5]
])
print(a * b)
[[ 0  2  6]
 [12 20 30]]

行列積

ドット積とかいうやつ。 高校位の数学で習う行列の掛け算はこんな感じ

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])
b = np.array([
    [0, 1],
    [2, 3],
    [4, 5]
])
print(a.dot(b))
[[16 22]
 [34 49]]

転置行列

つってもこれは馴染みがありすぎるか…

a = np.array([
    [1, 2, 3],
    [6, 7, 8]
])
print(a.T)
[[1 6]
 [2 7]
 [3 8]]