2021/01/06 00:56 更新
リサイズする整数(Convolution)
40 いいね ブックマーク
目次

前提知識

$5/7=0.714...$ うーん割り切れんなあ。

$0.714... + 0.714... + 0.714... + 0.714... + 0.714... + 0.714... + 0.714... = 4.998...$

割り算の各要素も、整数にならんかなあ。(←何?)
小数が ぜんぶ 整数 に代わってくれたら 丸め によるロスが無くなりそうだなあ。

本文

torch.nn.ConvTransposeの可視化 という記事を一目見て面白かったので メモ書き をする。

.png画像 をこのブログに貼り付けるのが めんどくさいので テキストでやる。

a= $■■■■■$

b= $■■■■■■■$

長さ5のテープを、長さ7のテープに合わせようと思うと、
a のテープのタイル(?)、あるいは タケノコの節のようなものの長さを
7つに等分割し、タイル1つを $5/7$ にするのが 割り算 というものだった。

各要素を整数にするためなら、等分割の方を捨てたらいいんじゃないの?

以下、Convolution(畳み込み)の説明。
例えば、 机の上に置かれた以下の 5つの饅頭(まんじゅう) を、

a= $●●●●●$

7つのまんじゅう だということにする ルールを これから勝手に作る。
黒い丸では説明が難しいので、数を割り当てる。

a = $11111$ (1+1+1+1+1=5)

にするところ、まだ説明が難しいので いったん 5倍(?)し、

a * 5 = $55555$ (5+5+5+5+5=25)

以下のように合計だけ保って、当分割を崩し 数がバラけるように調整する。

a * 5 = $13579$ (1+3+5+7+9=25)

.png画像を このブログに貼りつけるのが めんどくさい ので数をバラけさせただけで、
深い意味はない。
この5桁の数字列が、7桁の数字列に代わってくれればいい。

手順1

前後に 都合よく パディング(詰め物) または 番兵(Centinel) を置く。

a * 5 = $**13579**$

手順2

都合よく 横幅を 3 と決めて、先頭から1つずつ進みながら拾っていく。

b1 = $**1$
b2 = $*13$
b3 = $135$
b4 = $357$
b5 = $579$
b6 = $79*$
b7 = $9**$

手順3

深く考えず、拾った数は 足して1つにする。 パディングは 0 とする。

b1 = $1$
b2 = $4$
b3 = $9$
b4 = $15$
b5 = $21$
b6 = $16$
b7 = $9$

2桁になっているのが気に入らなかったら、アルファベットも使う。

b1 = $1$
b2 = $4$
b3 = $9$
b4 = $F$ (10=A, 11=B, 12=C, 13=D, 14=E, 15=F)
b5 = $L$ (16=G, 17=H, 18=I, 19=J, 20=K, 21=L)
b6 = $G$
b7 = $9$

手順4

1本のテープに戻す。

b = $149FLG9$ (21進数)

これは何なのか? 合計は 75 (10進数) で 3倍に拡大されている。
1つずつ切り取るときの 横幅を 3 にしたからだろうか?

ということは。

こういうことか

a * 5 = $******55555******$

b1 = $******5$
b2 = $*****55$
b3 = $****555$
b4 = $***5555$
b5 = $**55555$
b6 = $*555555$
b7 = $5555555$
b8 = $555555*$
b9 = $55555**$
b10 = $5555***$
b11 = $555****$
b12 = $55*****$
b13 = $5******$

b = $(5)(10)(15)(20)(25)(30)(35)(30)(25)(20)(15)(10)(5)$

さらに

c1 = $(5)(10)$
c2 = $(15)(20)$
c3 = $(25)(30)$
c4 = $(35)(30)$
c5 = $(25)(20)$
c6 = $(15)(10)$
c7 = $(5)*$

c1 = $15$
c2 = $35$
c3 = $55$
c4 = $65$
c5 = $45$
c6 = $25$
c7 = $5$

c = $(15)(35)(55)(65)(45)(25)(5)$

a * 5 と比較すると

a * 5 = $(5)(5)(5)(5)(5)$ …長さが5で、合計25。
c = $(15)(35)(55)(65)(45)(25)(5)$ …長さが7で、合計 245。

合計が 9.8 倍になっているのを どう考えればいいのか分からないが、
$(7^2/5^2)/2 = 0.98$ と何か関係があるのだろうか。

中間結論

Convolution 使えるやつだな。

1つずつ等幅で切り取るところでも、重ね合わさる部分があってもいいのでは

今まで愚直に各桁を 足し算 をしていたが、ここで ずらして 足すというテクニックがあってもいいのでは。(←何のために?)

例えば、1つ前の要素の後ろ半分と、1つ後ろの要素の前半分を 巻き込んで足す のをアリとしたなら。

c1 = $(5)(10)$
c2 = $(15)(20)$
c3 = $(25)(30)$
c4 = $(35)(30)$
c5 = $(25)(20)$
c6 = $(15)(10)$
c7 = $(5)*$

は、

c1' = $(*)(5)(10)(15)$
c2' = $(10)(15)(20)(25)$
c3' = $(20)(25)(30)(35)$
c4' = $(30)(35)(30)(25)$
c5' = $(30)(25)(20)(15)$
c6' = $(20)(15)(10)(5)$
c7' = $(10)(5)(*)(*)$

c1' = $(30)$
c2' = $(70)$
c3' = $(110)$
c4' = $(120)$
c5' = $(90)$
c6' = $(50)$
c7' = $(15)$

となって、山は なだらかになった。
こういうテクニックは サンプリング畳み込み で検索すると いろいろあるようだ。