Python数学シリーズ② 行列の掛け算


経緯

深層学習の本を読み進めているのですが、ひたすら文字を読んでると眠くなってしまうので、出てきた項目をpythonで実装しながら理解を深めていこうと思います。需要があるかはわかりませんが、シリーズ化していています(笑)。目次はこちらです。今回は行列の掛け算をやっていこうと思います。pythonはライブラリが豊富なので、それに頼れば何も考えずに計算できるのですが、あえて自作しています。
これはadevent calendarの自分の最後の記事です。カレンダーの最後は@bigface00さんが締めてくれます。

行列の掛け算

行列の掛け算は下のようなイメージで計算できます。参照元

簡単な実装

こちらの記事を参考にすると、numpy.dotかnumpy.matmalを使えば簡単に実装できるようです。

arr1 = np.arange(4).reshape((2, 2))
print(arr1)
# [[0 1]
#  [2 3]]

arr2 = np.arange(6).reshape((2, 3))
print(arr2)
# [[0 1 2]
#  [3 4 5]]

print(np.dot(arr1, arr2))
# [[ 3  4  5]
#  [ 9 14 19]]

print(arr1.dot(arr2))
# [[ 3  4  5]
#  [ 9 14 19]]

print(np.matmul(arr1, arr2))
# [[ 3  4  5]
#  [ 9 14 19]]

自作してみた

まずは最終的な答えの行数と列数を数えておきます。答えの行数は前の行列の行数で、答えの列数は後の行列の列数なので、それをもとにfor文を回しています。3つ目のfor文の中で、前の行列の行と、後の行列の列との計算をやっています。前の行列の列ごとの計算結果をtmp_listに入れておき、最終的にans_listに全ての計算結果を入れています。

def matrix_mlp(list1, list2):
    ans_row = len(list1)
    ans_col = len(list2[0])
    ans_list = []
    for i in range(ans_row):
        tmp_list = []
        for j in range(ans_col):
            tmp = 0
            for k in range(ans_row):
                tmp += list1[i][k] * list2[k][j]
            tmp_list.append(tmp)
        ans_list.append(tmp_list)
    return ans_list

def main():
    print("~~matrix_multiple_test~~")
    arr1 = np.arange(4).reshape((2, 2))
    arr2 = np.arange(6).reshape((2, 3))
    print("Before1  :", arr1.tolist())
    print("Before2  :", arr2.tolist())
    print("correct  :", np.dot(arr1, arr2).tolist())
    print("my_answer:", matrix_mlp(arr1.tolist(), arr2.tolist()))

このシリーズ恒例ですが、実装はさっき思いついたやつなので合っている保証はしていません(笑)。ここ違うとか、こういう方法あるよとかあれば教えてください。
こんな感じでゆる〜く読み進めてます。

間違いや質問、ご意見等ありましたらお気軽にコメントください。頑張って答えますので(笑)。