量子コンピュータで加算回路を作る
今回からは前回までの論理回路の知識を使って、実際に計算をしてみます。
まずはQuantumChalleng2020でも出題された加算回路についてです。
加算回路のベースは古典回路の半加算器と全加算器です。
加算回路ではXOR
・AND
・OR
ゲートを使って加算器を構成し、それらを最終的に量子ゲートに置き換えるということで実現が可能です。
そのため、今回の説明の大部分は古典回路の説明になります。
今回のエントリーではそのような回路を作るとどうして「1 + 1 = 2」などとコンピュータ上で計算ができるのかをご説明します。
主にこれまで論理演算や電子回路に触れてこなかった方向けの内容となります。
なお、実装はQiitaにいくつか記事が上がっています。
ここでは仕組みの理解を目指します。
対象とする読者
- 量子プログラミングに興味を持ち始めたばかりのエンジニア
- 量子計算に興味を持ち始めたばかりの高校生・大学生
- 数学・論理演算・電子回路に慣れていない方
など
対象でない読者
- 計算機科学・電子工学関連ご出身の方
など
※もちろん読んでいただける分には嬉しいですが、
特に前半部分は電子回路の授業で扱われていたり教科書にも載っている内容となりますので
いまさらと感じさせてしまうかもしれません。
前提とする知識
- 簡単な論理演算(AND, OR, NOT)が分かること
- 基本的な量子ゲート(X, CX, CCX)が分かること
バージョン情報
- Python 3.7.3
- Qiskit 0.23.1
目次
コンピュータ・計算機で足し算をするとは
量子でも古典でも、ビット
は0
か1
の2つの値を取る物体・回路部品でしかありません。
それ自身に計算する機能も数値を表現する機能もありません。
数値の表現方法や計算方法を回路という形で人間が教えてあげることで、計算が可能になります。
(今ご覧なっているようにブログなどをグラフィックに表示したりアプリケーションを構築するというのはそれぞれのビットから見たらさらに高度なことです。)
実はこういった数字そのもの以外の「もの」を使った数値の表現や計算を人間は日常的にやっています。
それがこれから説明する「指・正の字・そろばん」などです。
まずはこれらで計算を行う仕組みを振り返って、コンピュータでの計算を理解しましょう。
指・正の字・そろばんなどで数を数える
「指・正の字・そろばん」のある状態と、その状態に対応する数値・数字の組み合わせは下図の通りです。
それぞれ人間は次のようにものの状態から数値を解釈しています。
- 指は立っているその本数で数値を示します。
- 正の字は画数の合計で数値を示し、「正」の字が1つ出来上がれば「5」を示し、「正」の字が何文字出来上がったら「5 x 正の字の数」で5の倍数を示します。
- そろばんは上がっているコマの数(下の段が「1」上の段が「5」)が10進法のある桁の数値を示します。
計算機上での数の表現(2進数)
コンピュータではこれらと同様に、複数のビットを1列に並べて、何番目のビットが0
か1
かで人間が数値だと認識しています。
それが2進数と呼ばれる表記です。
これもコンピュータやビットという「もの」にとっては0
と1
が並んでいるだけです。
2進数(0
/1
表記、古典ビット(トランジスタの電圧)、量子ビット(Bloch球))と10進数は下記のように対応させ、人間が意味づけます。
計算機上で足し算をするための手順
ここまでで、「もの」の状態と人間が認識する「数値・数字」との対応を確認しました。
ではそれぞれのものの「元の状態」に「1」を足すときの手順を振り返りましょう。
- 指は指をもう一本足すこと
- 正の字はもう一画足すこと
- そろばんはコマを1つ動かすこと
コンピュータの計算と一番近いのはそろばんです。
1つずつコマを上げていきますが、それができるのは4つまで。
5つめはなく、上段の「5」のコマを上げて、下段のコマはすべて下げます。
再び1増えるごとに下段のコマを増やしますが、「9」の次のコマがまたなくなります。
そうしたら左隣の桁のコマを1つ上げ、元々の桁のコマは全て下げ「10」を表現します。
これは「10 (左の桁の単位) x 1 + 1 (右の桁の単位) x 0」ということですね。
2進数ではそれが2ずつ起きます。
(表現するのに使える文字が0
と1
の2種類しかないため。)
計算を図にするとこちらです。
この図でやっていることを手順として整理すると下記です。
- 足し算するための入力となる2つの数(
0
か1
)をビットとして2つ用意する - 計算結果の1桁目を次のルールで出力する
- 入力が両方
0
なら0
を出力:0 + 0 = 00を満たすため - 入力の片方が
1
なら1
を出力:0 + 1 = 1 + 0 = 01を満たすため - 入力が両方
1
なら0
を出力:1 + 1 = 10を満たすため
- 入力が両方
- 計算結果の2桁目を次のルールで出力する
- 入力が両方
0
なら0
を出力:0 + 0 = 00を満たすため - 入力の片方が
1
でも0
を出力:0 + 1 = 1 + 0 = 01を満たすため - 入力が両方
1
なら1
を出力:1 + 1 = 10を満たすため
- 入力が両方
- 出力は左から順に「2桁目を表現する回路の出力」「1桁目を表現する回路の出力」と並べ、人間はこの2進数表記と10進数表記を対応させて認識する。
- 2進数の
00
= 10進数の0
- 2進数の
01
= 10進数の1
- 2進数の
10
= 10進数の2
- 2進数の
11
= 10進数の3
- 2進数の
これらを満たす回路を次節で組んでいきましょう。
古典での加算回路(半加算器・全加算器)の作り方
前節の内容で「1 + 1 = 2」を計算するための手順が分かりました。
これを「半加算器」と言います。
さらに下の桁からの桁上がりを考慮して足し算する回路を半加算器を組み褪せて作ります。
これを「全加算器」と言います。
半加算器
前節の内容を真理値表で表すと下記です。
1桁目はXOR
ゲートで表せ、2桁目はAND
ゲートで表せます。
実際にそうなっているはずなので、確かめてみてください。
1桁目
入力1 | 入力2 | 出力 |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
2桁目
入力1 | 入力2 | 出力 |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
2つの入力ビットからそれぞれのゲートにつなぎ、それぞれのゲートからの出力を計算結果とします。 (下図)
一般に1桁目の計算結果であるXOR
の計算結果をSum(S)
、2桁目の桁上がりをCarry(C)
と呼びます。
入力と出力の対応が下記です。
たしかに「0 + 0」から「1 + 1」までの計算が人間が行う結果と一緒になっていると思います。
半加算回路の計算結果
A | B | C | S | 計算(10進数) |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 + 0 = 0 |
0 | 1 | 0 | 1 | 0 + 1 = 1 |
1 | 0 | 0 | 1 | 1 + 0 = 1 |
1 | 1 | 1 | 0 | 1 + 1 = 2 |
全加算器
続いて全加算器です。
これは、下の桁からの桁上がりを考慮するための回路です。
例えばひっ算をするときに次の状況がよくあると思います。(2進数)
この緑色の計算をコンピュータ上でもできるようにしたのが全加算器です。
要点としては、その桁の計算結果に下の桁からの桁上がり(Carry
の値)を足して最終結果とするということです。
結論から先に、回路図と計算結果の表は下記になります。
A | B | Ci | Co | S | 10進数での計算 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 + 0 + 0 = 0 |
0 | 0 | 1 | 0 | 1 | 0 + 0 + 0 = 1 |
0 | 1 | 0 | 0 | 1 | 0 + 1 + 0 = 1 |
0 | 1 | 1 | 1 | 0 | 0 + 1 + 1 = 2 |
1 | 0 | 0 | 0 | 1 | 1 + 0 + 0 = 1 |
1 | 0 | 1 | 1 | 0 | 1 + 0 + 1 = 2 |
1 | 1 | 0 | 1 | 0 | 1 + 1 + 0 = 2 |
1 | 1 | 1 | 1 | 1 | 1 + 1 + 1 = 3 |
ある桁の入力A, Bと下の桁からの桁上がり(Carry)Ciの3つの入力があります。
A, Bの計算を半加算器で行い、そのSumとCiも半加算器で計算します。
最終的な桁上がりは、最初のA + B の時点か、そのあとのA +B + Ciの結果のどちらかなのでそれを右下のOR
ゲートで判断します。
実際にはこの全加算器が何個も連なることで大きな数の計算ができるようになっているのですね。
最後に出力となるビットの値(上の図だとS
とCo
)を読んで2進数表記でならべることで下記のように人間はそのビット列を数値と認識します。
古典から量子への加算回路の置き換え
古典ゲートを量子ゲートに置き換え
前回までで古典論理ゲートと量子ゲートとの対応を確認しました。
そのままこの全加算器にも下記の要領で当てはめます。
そしてこれは量子コンピュータの特徴ですが、ゲートの出力の線の本数は入力と同じになります。
よって、最終的に不要なビットが生じますが、無視して量子全加算器の回路は下図になります。
計算例
例えばQuantumChallengeに提出した下記の回路を計算してみます。
この測定結果は下記です。 ひっ算で計算すると同じようにA + B + Ci = 0 + 1 + 1 = 10が成り立っていて確かに計算できてそうです
以上が量子ビットを使って足し算するための回路の組み方と計算が行われる仕組みです。
これは単純な足し算を量子回路上でどう実現するか、という話でしたが、他の様々な問題も工夫して量子回路に置き換えて何らかの答えを出せるようにします。
まとめ
- コンピュータで計算をするには
XOR
とAND
ゲートを組み合わせればよい - 量子コンピュータでも同様に
XOR
とAND
ゲートを組み合わせればよい - 一般に行いたい計算が実現できるように量子ゲートを組み合わせればよい
量子コンピュータで行う論理演算(3)
前回はMultiple Controlled Toffoli(MCT)を使って複数の条件のANDゲートの実装を紹介しました。
今回もCXゲート関連のテクニックの紹介です。
これで基本事項の紹介は最後にして次回からはちょっとした計算を紹介したいと思います。
今回は通常のプログラミングで
if not A: 処理
という場合の量子回路の作り方をご紹介します。
対象とする読者
- 量子プログラミングに興味を持ち始めたばかりのエンジニア
- 量子計算に興味を持ち始めたばかりの高校生・大学生 など
前提とする知識
- 論理演算(AND, OR, NOT)が分かること
- 基本的な量子ゲート(X, CX, CCX)が分かること
お断り
僕は基本Qiskitしか使わないので解説ソースもQiskitで書きます。
Q#やIonQなど他の言語・フレームワーク・ハードウェアに興味ある人には申し訳ないですが、考え方は共通していると思うのでご参考程度に、ということでお願いします。
バージョン情報
- Python 3.7.3
- Qiskit 0.23.1
目次
量子回路でif not A
を実装する方法
先ほどご紹介しましたが、下記のような場合です。
if not A: 処理
実装方法
先に結論を述べますと、下記のようにCXゲート
の制御ビットをXゲート
で挟めばよいです。
qr_input = QuantumRegister(1, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(2) qc = QuantumCircuit(qr_input, qr_output, cr) qc.x(qr_input) qc.cx(qr_input, qr_output) qc.x(qr_input) qc.barrier() qc.measure(qr_input, cr[:1]) qc.measure(qr_output, cr[1]) qc.reverse_bits() qc.draw(output='mpl')
見やすさのためにqc.barrier()
を追加していますが、計算上は不要です。
この測定結果は、下記のように制御ビット(ビット列の右側)が0
の時に標的ビット(ビット列の左側)が1
になります。
したがって、if文の条件に対応する制御ビットの値が0
の時に条件が満たされてCXゲートが機能しているということです。
解説
「制御ビットの端子(黒丸)の直前でXゲートがかかって標的ビットが1
になるんだから、CXゲートがかかって当然じゃん」
と思った方、その通りです。
それを利用しています。
この図の読み方を説明します。
この図は2つのXゲート
と制御ビットの黒丸を1セットで読みます。
Xゲート - 黒丸 - Xゲート
で一つの端子と思ってまとめて白丸に置き換えます。
その直前の状態がこの新しい端子への入力で、中でどんなゲートがかかるかはブラックボックスとして読んでください。
そうすると、
- 制御ビットは状態で初期化
- 新しいCXゲートの端子(制御ビットの状態がの状態で標的ビットを反転する)
- CXゲートを過ぎた後の制御ビットの状態はCXゲートに入る前の状態()のまま
という挙動になります。
ブラックボックスと書きましたが、左側のXゲートで反転させられた制御ビットの状態は右側のXゲートで元に戻すので、CXゲートはかかるけどXゲートはなかったことになります。
(実機ではXゲートを掛けている分ゲートエラーは乗りますが、数学上は影響なしです。)
※なお、この「元に戻す」というのは用語としてはUncomputation・Uncomputing(逆計算)
といいます。
端子での値が1(True)
の時に条件を満たすのが黒丸
に対して、端子での値が0(False)
の時に条件を満たすのが白丸
ということで、役割が逆になっています。
この対応は量子計算のバイブルNielsen-Chuangでもちゃんと(しれっと)紹介されています。 *1
現在出回っている教科書では当たり前すぎるのか白丸については解説無いままのことが多いと思います。
量子回路でif not A and not B
のような複数の条件を実装する方法
すべてnotの場合
下記のような場合です。
if not A and not B: 処理
これは1つの場合のCXゲート
をCCXゲート
に置き換えればよいです。
qr_input = QuantumRegister(2, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(3) qc = QuantumCircuit(qr_input, qr_output, cr) qc.x(qr_input) qc.ccx(qr_input[0], qr_input[1], qr_output) qc.x(qr_input) qc.barrier() qc.measure(qr_input, cr[:2]) qc.measure(qr_output, cr[2]) qc.reverse_bits() qc.draw(output='mpl')
この結果は下記で、標的ビットが反転しています。
3つ以上の場合はMCTを使います。
if not A and not B and not C: 処理
qr_input = QuantumRegister(3, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(4) qc = QuantumCircuit(qr_input, qr_output, cr) qc.x(qr_input) qc.mct(qr_input, qr_output) qc.x(qr_input) qc.barrier() qc.measure(qr_input, cr[:3]) qc.measure(qr_output, cr[3]) qc.reverse_bits() qc.draw(output='mpl')
notが一部混ざっている場合
下記のような場合です。
if not A and B and not C: 処理
AとCがFalse(0)で、BがTrue(1)の時にif文の条件が満たされてif文の中の処理が実行されます。
これはソースは若干書くのが手間ですが、not xx
になる端子だけXゲート
を掛けます。
qr_input = QuantumRegister(3, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(4) qc = QuantumCircuit(qr_input, qr_output, cr) qc.x([qr_input[0], qr_input[2]]) qc.mct(qr_input, qr_output) qc.x([qr_input[0], qr_input[2]]) qc.barrier() qc.measure(qr_input, cr[:3]) qc.measure(qr_output, cr[3]) qc.reverse_bits() qc.draw(output='mpl')
これはこのまま実行しても第2制御ビットが条件を満たさないので標的ビットは反転しません。
標的ビットを反転させるには下記のようにします。
qr_input = QuantumRegister(3, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(4) qc = QuantumCircuit(qr_input, qr_output, cr) qc.x(qr_input[1]) #|010>状態を入力とするということ qc.barrier() qc.x([qr_input[0], qr_input[2]]) qc.mct(qr_input, qr_output) qc.x([qr_input[0], qr_input[2]]) qc.barrier() qc.measure(qr_input, cr[:3]) qc.measure(qr_output, cr[3]) qc.reverse_bits() qc.draw(output='mpl')
見やすさのために、MCTの前にもqc.barrier()
を追加しています。
ソースにコメントしていますが、この回路はMCTゲートへの入力はとしていて、標的ビットがちゃんと反転していることが下記の測定結果からも分かります。
まとめ
if not A
の量子回路での実装は、制御ビットの端子をXゲート
で挟む。- 複数の端子がある場合は、
not
が対応する端子だけXゲート
で挟む。
*1:Quantum Computation and Quantum Information (10th anniversary edition), 2010, M. A. Nielsen and I. L. Chuang, p185, Figure 4.11
量子コンピュータで行う論理演算(2)
前回に引き続き、論理演算を量子回路に実装する方法を解説します。
前回基本的な古典論理演算を量子回路に実装する方法の一つで、AND(論理積)演算をCCXゲートで実装する方法を紹介しました。 これは2つの入力の場合の演算ですが、一般に複数の入力に対してAND演算する方法をご紹介します。
対象とする読者
- 量子プログラミングに興味を持ち始めたばかりのエンジニア
- 量子計算に興味を持ち始めたばかりの高校生・大学生 など
前提とする知識
- 論理演算(AND, OR, NOT)が分かること
- 基本的な量子ゲート(X, CNOT, CCNOTなど)が分かること
バージョン情報
- Python 3.7.3
- Qiskit 0.23.1
複数の入力についての古典ANDゲートとMulti Controlled Toffoli(トフォリ)ゲート
複数の入力についてANDゲート(論理積)を取るとは下記のような場合です
if A and B and C and D ....: 処理
通常プログラミングしていたらこのような場合に遭遇することがよくありますが、 このような条件の判定は、量子ゲートではMulti Controlled Toffoliゲート(MCTゲート)でできます。 ちょうどControlled-Xゲートの入力が複数に増えたものです。 (CCXゲートもMCTゲートの一つです。)
qr_input = QuantumRegister(3, 'input') << inputの数は好きに増やせる qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(4) qc = QuantumCircuit(qr_input, qr_output, cr) qc.mct(qr_input, qr_output) qc.measure(qr_input, cr[:3]) qc.measure(qr_output, cr[3]) qc.reverse_bits() qc.draw(output='mpl')
Multi Controlled Toffoliゲートはqc.mct(qr_input, qr_output)
で定義できますが、
この第一引数に設定されるビット数によって入力端子(制御ビット)の数を自動的に決めてくれます。
この入力端子の条件をすべて満たしたときに(上の図だとすべて状態の場合に)標的ビット(output)にXゲートを掛けます。
そのようになっていることを前回同様inputの状態に対するoutputの状態を測定することで確認しましょう。
入力がの場合
右側で測定されている状態は0001
で、outputのビット(標的ビット)は一番左のビットで表現されているので、0
のままですね。
入力がの場合
こちらもoutput(一番左)は0
のままです。
入力がの場合
こちらもoutput(一番左)は0
のままです。
入力がの場合
ここでやっとoutput(一番左)が1
に変化しました!
まとめ
量子コンピュータで行う論理演算(1)
先日QuantumChallengeに参加してみていくつか感じたことの一つに
「問題設定が与えられた後、それを量子回路に対応させることが難しい」
ということがあります。
現状の量子計算はアカデミア要素が強いせいもあってか参考になる記事も少なく、自分で考えるということが強く求められるフェーズのプログラミングだと感じました。
論文や有名なアルゴリズムを実装してみたという記事はいくつか見つかりましたが、どうしてそのように量子回路を組むのかまではまだ踏み込めていない印象です。
つまり、数理的な素養やもともと量子計算・量子情報処理に関わっている・いたという人はいくらか苦労した上でプログラミングできるけど、そうでない人には敷居が高いと感じました。
というわけで、自分の勉強も兼ねて量子回路を書くためのテクニック集的なものをこれから書いていこうと思います。
量子情報処理が専門でない人でこれから量子計算始めたいという人が少しでもプログラミングできるようになる助けになれば幸いと思います。
今回はQuantumChallengのweek1Aで解説がされていた、量子ゲートと論理演算との対応についていくつか解説します。
対象とする読者
- 量子プログラミングに興味を持ち始めたばかりのエンジニア
- 量子計算に興味を持ち始めたばかりの高校生・大学生 など
前提とする知識(簡単に解説はします)
- 論理演算(AND, OR, NOT)が分かること
- 基本的な量子ゲート(X, CNOT, CCNOTなど)が分かること
お断り
僕は基本Qiskitしか使わないので解説ソースもQiskitで書きます。
Q#やIonQなど他の言語・フレームワーク・ハードウェアに興味ある人には申し訳ないですが、考え方は共通していると思うのでご参考程度に、ということでお願いします。
バージョン情報
- Python 3.7.3
- Qiskit 0.23.1
目次
論理演算とは
2つないし複数の論理値(日本語で真/偽、Boolean型でいうところのTrue/False)を組み合わせて計算すること。
プログラミングでは主にif文の条件式で用いることで、処理の条件分岐を行います。
量子計算でも計算途中で条件分岐をすることが発生します。(今度紹介しますが加算器などの計算するにも根本的には条件分岐です。)
でも量子回路上にはif文は存在しないので、量子ゲートを組み合わせて実現します。
論理演算と量子ゲートの対応
古典NOTゲートとXゲート
NOTゲートというのは「○○でない」という元の「○○である」を否定することです。
通常のプログラミングだと、例えば性別フラグ・男性フラグis_man
などをBoolearn型で用意して、顧客データの集計などすることを想像してみてください。
あえてフラグの男女を反転させるとこういうケースです。
if not is_man: cnt_woman += 1 else: cnt_man += 1
古典NOTゲートは量子ゲートではXゲートが対応します。
qr = QuantumRegister(1, 'input') cr = ClassicalRegister(2) qc = QuantumCircuit(qr, cr) qc.measure(qr, cr[0]) qc.x(qr) qc.measure(qr, cr[1]) qc.reverse_bits() qc.draw(output='mpl')
この測定結果の分布は下記です。
Xゲートの性質を考えればその通りですが、入力が状態に対して出力は状態になっています。
測定結果のビットの並びは測定順と逆順で、左側がXゲート通過後で右側がXゲート通過前です。
(量子回路に書いてある測定の番号が若い順に文字列の右側から表示されます)
なお、量子ビットの状態はで初期化されているので、何らかの理由で状態を使いたい場合にもXゲートを使います。
以降の説明でもこの手法を多用します。
古典ANDゲートとCCNOT(CCX)ゲート
ANDゲートとは「AかつBである」と二つの条件の両方が満たされていることを示すものです。 例えば、性別ごとに職業を集計する時などでしょうか。
if is_man and is_sport_player: cnt_man_sport += 1 elif is_man and is_engineer: cnt_man_engineer += 1 elif is_woman and is_sport_player: cnt_woman_sport += 1 elif is_woman and is_engineer: cnt_woman_engineer += 1 (以下略)
古典ANDゲートにはCCNOT(CCX)ゲート(2つのコントールビットがともに状態であればターゲットビットの状態の0/1を反転する)が対応します。
CCNOTゲートの2つのコントロールビットを量子AND回路の入力、そしてCCNOTゲートのターゲットビットを量子AND回路の出力(論理演算した結果)に対応させます。
「AかつBである」のAは入力1の状態が1(BooleanでいうところのTrue)でBは入力2の状態が1に対応します。
qr_input = QuantumRegister(2, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(3) qc = QuantumCircuit(qr_input, qr_output, cr) qc.ccx(qr_input[0], qr_input[1], qr_output) qc.measure(qr_input, cr[:2]) qc.measure(qr_output, cr[2]) qc.reverse_bits() qc.draw(output='mpl')
この結果は下記に示すように、ターゲットビットは0
のままです。
コントロールビットである2つの入力がともに0
だからですね。
他のパターンは以下になります。(コードと入力が10
の場合は省略します。)
最後の入力が11
の場合のみ、ターゲットビットの状態が1
になっていますね。
「入力1が1(True)でかつ入力2が1(True)」であることが示されたということです。
古典XORゲートとCNOT(CX)ゲート
XORゲートとは「AとBのどちらかが一方のみがTrueである場合」を示します。 例えば会社の部署の人数を集計する時に、兼務を除きたい場合です。
if (dept_A or dept_B) and not (dept_A and dept_B): if dept_A: cnt_only_A += 1 else: cnt_only_B += 1
古典XORゲートはCNOT(CX)ゲートを2つ組み合わせた量子回路が対応します。
qr_input = QuantumRegister(2, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(3) qc = QuantumCircuit(qr_input, qr_output, cr) qc.cx(qr_input[0], qr_output) qc.cx(qr_input[1], qr_output) qc.measure(qr_input, cr[:2]) qc.measure(qr_output, cr[2]) qc.reverse_bits() qc.draw(output='mpl')
この状態の分布は下記で、入力どちらの状態も0なので出力も0です。
その他のパターンは以下になります。
最後の入力が11
の場合は出力が0
になっており、古典XORと同じ挙動になっていますね。
古典ORゲートとCNOT(CX)ゲート・CCNOT(CCX)ゲートの組み合わせ
ORゲートは「AとBのすくなくともどちらかTrueである場合」を示します。
XORと異なり、兼務を含めて集計する場合が相当します。
if (dept_A or dept_B): cnt_AorB += 1
古典ORゲートはCNOT(CX)ゲート2つとCCNOT(CX)ゲート1つを組み合わせた量子回路が対応します。
qr_input = QuantumRegister(2, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(3) qc = QuantumCircuit(qr_input, qr_output, cr) qc.cx(qr_input[0], qr_output) qc.cx(qr_input[1], qr_output) qc.ccx(qr_input[0], qr_input[1], qr_output) qc.measure(qr_input, cr[:2]) qc.measure(qr_output, cr[2]) qc.reverse_bits() qc.draw(output='mpl')
量子XOR回路と異なるのは、最後にCCXゲートがあることで入力が11の場合に2つのCXゲートを通ってターゲットビットの状態が0
-> 1
-> 0
と変化した後、改めてターゲットビットを反転して1
になることです。
上記の回路の分布は下記で、やはり入力がともに0なので出力も0です。
その他のパターンは以下になります。
最後の入力が11
の場合に出力が1
になっており、古典ORと同じ挙動になっていますね。
古典NANDゲートとCCNOT(CCX)ゲート
NANDゲートとは「AかつB以外の場合」を示します。 例えば、男性のスポーツ選手以外の人数(男性でスポーツ選手以外の人数 + 女性)を集計する場合などです。(あくまで例なのでこういう集計をする状況があるかは分かりません)
if not (is_man and is_sport_player): cnt_not_man_and_sport += 1
古典NANDにはCCNOT(CCX)ゲートのターゲットビットにXゲートを組み合わせた量子回路が対応します。
qr_input = QuantumRegister(2, 'input') qr_output = QuantumRegister(1, 'output') cr = ClassicalRegister(3) qc = QuantumCircuit(qr_input, qr_output, cr) qc.x(qr_output) qc.ccx(qr_input[0], qr_input[1], qr_output) qc.measure(qr_input, cr[:2]) qc.measure(qr_output, cr[2]) qc.reverse_bits() qc.draw(output='mpl')
量子ゲートそのものはそれぞれの量子ビットの状態を操作することなので、行いたい演算の結果がその通り得られるならターゲットビットにもXゲートをかけていいのです。 (かけちゃいけないというルールもない)
この結果は下記で、入力が00
の場合は「AでなくBでもない」ので「AかつB以外の場合」に含まれておりNANDの結果はTrue
です。
実際に出力は1
になっています。
その他のパターンは以下になります。
最後の回路でNANDの特徴である、入力がともに1
の時は出力が0になっていて「AかつBの場合」は「AかつB以外の場合」にふくまれていないことが示されています。
まとめ
IBM Quantum Challenge 2020 体験記
こんにちは、sakumatchoです。 2020/11/9 ~ 2020/11/30の22日間実施されたIBM Quamtum Challenge 2020に参加した体験記を書きます。
対象とする読者
- これから量子プログラミングを始めたいという方
- すでに学んでいるけど実践する場・挑戦する場が欲しいという方
- 惜しくも参加できず内容が気になる方
など
目次
- 自己紹介
- IBM Quantum Challengeとは
- IBM Quantum Challenge 2020 の出題内容
- 感想
自己紹介
昔
- 学生時代の専門:
超伝導量子干渉計(SQUID)を使って、半導体量子ドット中の光励起電子スピンの磁化やというカイラルP波超伝導体といわれている新奇超伝導体の磁化について研究する超伝導など磁気物性の実験屋でした - 量子情報処理・量子計算との関わり:
- FIRST 量子情報処理プロジェクトに関わっていました
- 量子情報関東StudentChapterの運営委員やっていました
- 論文(arXivには上げてないので見られない人多いと思います、すみません。)
今
- 職業:データサイエンティスト
- 趣味:
- 量子計算(趣味で量子計算だなんて良い時代になったもんだ)
- プログラミング
- 水泳(観る・やる、両方)
- マインド:
- 機械学習や量子計算を現実の問題に適用させようとしています
- 一人でも量子計算に興味を持つ人が増えてほしいと願っています
IBM Quantum Challengeとは
こちらで記載されていますが、IBMが年に一度主催している量子コンピューターの競技型オンライン・プログラミング・コンテストです。 コンテストではありますが、初心者向けの導入から課題が与えられるので、Pythonさえ書ければ量子プログラミング・量子計算が初めての方でも参加可能です。
IBM Quantum Challenge 2020 の出題内容
詳細は僕のGitHubでノートブックを公開していますのでご確認ください。 ここでは概要だけ示します。
なお、公式でも公開されています。
期間は3週間で、問題は1A, 1B, 2A, 2B, Finalの全5題でした。
1連の問題を解くとGroverの探索アルゴリズムを使いこなせるようになっており、また量子並列性や重ね合わせ状態の威力を実感できる内容となっています。
それぞれの課題では、前半で基礎知識を導入し、後半で問題が1題出題され、量子回路を構成する関数を作成して関数を提出します。
提出用に運営が作成した関数に関数を引数として渡し、チェック処理が走って構成した量子回路が必要な入出力や条件など満たしていれば正答となり次の課題に進むことができます。
なお、導入部ではIBMQ ExperienceのナビゲータであるDr. Ryoko(量子(りょうこ)ちゃん)とのアドベンチャーストーリーが展開され、課題を解くごとに先に進む話がまた面白いです(笑)
僕は今回期間内に2Bまで解くことができ、Finalはいまだ解けていません(笑) 解けた人ホントすごいです!
なお、IBMからbadgeをもらいました!
1A:量子全加算器
導入
- 量子ゲートの使い方
- 古典論理ゲート(AND, OR, NOT, XOR, NANDなど)を量子ゲートで再現
- 古典半加算器を量子ゲートで再現
- 量子回路のコスト計算の方法
古典半加算器
図1が通常の論理回路(量子と対比して古典回路とここで呼ぶことにします。)で作成される半加算器です。 回路の上側で左側が弧を描いている部品がXORゲート(排他的論理和)で、下側で半楕円の部品がANDゲート(論理積)です。
量子半加算器
図2が量子回路で作成した半加算器です。 回路を縦破線で区切って一番左でXORゲート、中央でANDゲートを作成し、最後に2と3の量子ビットを測定して計算結果の出力としています。
という感じに、集合演算は古典回路を量子で再構成することで同じように実行することができます。 「なんだ、じゃあ量子コンピュータも従来のコンピュータとできること変わらないのか、、」なんてことはありません! 後でGorverのアルゴリズムを使うと分かりますが、論理演算を並列に実行できるところが量子コンピュータのすごいところです!
課題
下記の真理値表を満たす全加算器を量子ゲートだけで実装します。 僕が提出した回路はオーソドックスなものですが、別解もあり1問目からやりこみが発生したようです。
全加算器の真理値表
A(input) | B(input) | X(carry input) | S(sum) | C(carry out) |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 | 1 |
提出した全加算器
図3が提出した回路で、課題の入力に合わせて最初にXゲートを加えている以外は基本的には先の半加算器を2つ組み合わせた構造です。 図4の古典全加算器と同じ構造になっていることを確かめてみてください。
古典全加算器
公式解答
学べる事・身につくこと
- 量子ゲートを使った論理演算の方法
1B:Groverのアルゴリズムの反復回数
導入
- Groverのアルゴリズム概要
- オラクルと確率振幅の反転増幅について
- Groverのアルゴリズムの実装例
- 外部入力(auxiliary bits)を用いた場合のGroverのアルゴリズムの実装例
- Groverのアルゴリズムの繰り返し回数と確率振幅
Groverのアルゴリズムの実装(外部入力を用いた場合)
図4の回路を構成して実行すると、最初に0と1はアダマールゲートが実行されることによって|00>, |01>, |10>, |11>の4状態が等確率で生成されるはずですが、結果は図5のように|11>だけが残ります!
繰り返し回数と確率振幅の大きさの関係
4量子ビットを使って|0000>から|1111>の中から|0111>だけ増幅するという例題で回路は図6で、Groverを3回繰り返している例です。
ここでのGroverの繰り返し回数はオラクル(一番縦に長いMCT)の数を数えてください。
3本あるはずです。
その|0111>の確率振幅の大きさは図7のように繰り返し回数に対してで変化します。
課題
例題と同様に使う量子ビットの数を7にして、[tex: N=27 = 128]個の状態の中から、|0000111>だけを増幅しその確率振幅の大きさが最大になる繰り返し回数を求め、回数を答えます。
例題と同様の回路(図6)を7量子ビット用に直して実行すると図8のような結果が得られます。 図からは8回で最大となるので、これが答えです。
公式解答
学べる事・身につくこと
- Groverのアルゴリズムの基本
2A:Groverのアルゴリズムでライツアウトパズルを解く
導入
- ライツアウトパズルとは
ライツアウトパズル
図9に示すのがライツアウトパズルと解答例です。
初期の点灯状態がinput
の配列で与えられ、1
が点灯で0
が消灯を示します。
対してすべてのマスを消灯状態にする正解状態をoutput
配列として求め、1
がpushで0
がunpushを示します。
課題
例題と同じく3 x 3のライツアウトパズルをGroverのアルゴリズムだけを使って解きます。
入力は3 x 3 = 9マスの点灯状態を示す0/1の配列数9の任意の配列とし、パズルの解としてpushするボタンの0/1を示すやはり配列数9の配列を測定結果として取り出す量子回路を構成する関数を作成し、関数を提出します。
ただし制約が大きく2つあります。
- 外部のソルバなどを使ってパズルを解くことは不可でGroverアルゴリズムだけを使うこと
- 出題された問題だけでなく、任意のライツアウトパズルを解ける回路であること
提出した回路
図11が僕が提出した量子回路(長くてデバッグがしんどい、、)で、図12がその回路の計測結果です。
1つの状態だけ確率が飛びぬけていて、それが実際正解の状態で[1, 1, 0, 0, 1, 0, 1, 0, 1]
です。
僕のGitHubではこの量子回路を構成するまでの検証も含めてご紹介しています。
公式解答
学べる事・身につくこと
- Groverのアルゴリズムの応用
2B:Groverのアルゴリズムで複数のライツアウトパズルを同時に解く
導入
- 4つのライツアウトパズルの重ね合わせ状態
- QRAM
4つのライツアウトパズルの重ね合わせ状態
重ね合わせ状態のライツアウトってどういうことだよ、って突っ込みたいところですが、
このストーリによるとこのライツアウト自体が量子ビットでできていてこの4状態でfluctuateしているそうです。
量子の世界の話なら仕方ないですね、解きましょう。
今回はpushするマスの配列を求めて終わりではなく、それも求めた上で各面のpushするマスの数を数えます。 例題では1回で解ける面を求めよというものでした。
古典の世界なら順に解いていけば解けるのですが、量子の世界だそうで1度で4面解いて目的の面を答えないといけません。
でも大丈夫、Groverならできるそうです。
qRAM
課題
図13と同様な3 x 3のライツアウトパズルが4面同時に出題され、その中に一つだけ3箇所だけpushして解ける問題があり、それが何番目の面かをGroverのアルゴリズムで当てるというものです。 提出するのは問題を解いて2ビットで表された0~3の面番号を測定して出力するような量子回路を構成する関数です。
図で示すと長いのでノートブックを参照してください。
コンセプトとしては公式のヒントにある図15の回路です。
オラクルの中でオラクルを記述するせいで量子回路が長くなります。
公式解答
学べる事・身につくこと
- qRAM
- オラクルの応用
Final:Groverのアルゴリズムで複数のアステロイドパズルを解く
公式からのノートブック公開が12/14現在ありませんので、解説を書けていませんが僕のノートブックをご参照ください。
導入
- アステロイドパズル
アステロイドパズルとは図16に示したように面に配置された星を縦横1列まとめて消せます。 面に配置された星をすべて消去できればクリアです。
課題
4 x 4のアステロイドパズルが16面同時に出題され、15面は縦横計3列消せばクリアできます。 その中に一つ含まれている3列消しでは解けない面が何番か当てることが課題です。 人間が目で見て解くことも可能ですが、やはり重ね合わせで出題されるのでGroverのアルゴリズムで解かないといけないという制約があります。 この問題を解いて面番号を出力する量子回路を構成し提出します。
まだ解けていません。 3列消去で解ける15面の解を抽出することはできましたが、それぞれの面番号と3列消去で解ける・解けないというフラグを結び付けられていません、、 3列消去で解ける問題は4列以上を消去しても解けるので、そのあたりの枝刈りもしないといけません。 これを解けた人が全体の17%くらいで200人くらいいるみたいですが、すごいです。
学べる事・身につくこと
- これでGroverのアルゴリズムマスター
- 枝刈りなど数理的な素養も試されている感じがあります
感想
- Groverのアルゴリズムはデータベース探索としか知りませんでしたが、データベースだけでなくより広い問題を解くことだできる便利なアルゴリズムであることが分かった。
- ライツアウトもアステロイドもトイプロブレムだけれども、量子計算を使って問題を解くことが出来て嬉しかった。 量子情報処理を知って10年経って「量子計算スゲー」って思えました。 (それまでは論文のイントロとかで、この結果は量子計算にも応用ができるらしいとか、量子計算で並列計算ができるらしいとか字面でしか知らなかった)
- こういう問題を解いていった結果のノウハウが溜まって、いずれ実際の問題を解けるようにしていきたい!
- 今回はQASMシミュレータ上での計算だったので、実機で動くのか知りたい。
- 来年も開催されたら、最後まで解きたい!
kaggle体験記: Global Wheat Detection (物体検出による小麦の穂の検出)
8月4日まで開催されていたkaggleの「Global Wheat Detection」コンペの体験談と学んだことをまとめます。
このコンペは様々な地域で撮影された写真から小麦の穂を検出するという物体検出の課題でした。
なお、僕は物体検出はもちろん深層学習もほぼ初心者のため、このエントリーでは技術的に深い内容は書けていないと思います。
逆にこれからkaggle始める、深層学習を使い始める、物体検出を始める、という方に近い内容となっております。
初めてのエントリーでわかりにくいところもあるかと思います。
ご指摘いただけますと幸いです。
目次
- 1. コンペ概要
- 2. 参戦動機
- 3. 結果として経験になったこと
- 4. EDA
- 5. 重要だった前処理
- 6. よく利用されていたアルゴリズム
- 7. 苦労したこと
- 8. 反省・これから頑張りたいこと
- 9. 基礎知識
1. コンペ概要
https://www.kaggle.com/c/global-wheat-detection
小麦は世界中の食卓に使われていて、植物学的にも農業的にも小麦の分布を知るということが重要らしい。
ただし、これまでの物体検出の取り組みでは地域によってことなる小麦を同じモデルでは検出できていなかった。
このコンペでは複数の地域の小麦の画像を混ぜたデータセットを用いて一つのモデルで小麦を検出できることを目指す。
ということから、地域によるバイアスがかからない柔軟なモデルを構築する必要があります。一昔前に問題になった人種バイアス・性別バイアスにも通じますね。
画像データサマリ
学習データ画像
- 3422件
評価データ画像
- 10件(公開データの件数、非公開なデータでは1000件)
評価方法
評価指標
- MAP(Mean Average Precision)
このコンペでは小麦の穂の検出箇所を示すバウンディングボックスという枠の位置・幅・高さが検証データセットとどれだけ近いか、ということを競います。
https://www.kaggle.com/c/global-wheat-detection/overview/evaluation
ノートブックの規定
このコンペはノートブックを提出する必要があります。
https://www.kaggle.com/c/global-wheat-detection/overview/code-requirements
- CPUだけを使う場合は9時間以内に実行が終了すること
- GPUを使う場合は6時間に実行が終了すること
- TPUは使用不可
- 提出するノートブックについてインターネットは使用不可
→kaggle kernel標準でインストールされていないライブラリなどをインターネットからpipすることは不可(whlファイルなどをデータセットとしてアップロードしておくことや、gitレポジトリをあらかじめcloneしてデータセットとしてアップロードしておくことは可) - 学習済みモデルなど外部データを使うことは可
- kaggle kernel内でライブラリを編集することは不可
- 提出ファイル名は「submission.csv」であること
2. 参戦動機
scikit-learnやSQLを使った統計的機械学習はこれまでの業務で経験したり勉強してきましたが、深層学習はありませんでした。
画像処理や物体検出は将来アプリ開発をしてみたく、今のうちに経験しておこうという動機です。
具体的には下記となります。
- PyTorchを使えるようになりたい
- 深層学習の勉強をしたい
- 物体検出の経験を積みたい
- 画像処理の経験を積みたい
- (将来的に)メダルが欲しい
→今回上位50%にやっと入った程度なので、力不足でした、、
3. 結果として経験になったこと
- PyTorchで学習済みモデルを使った再学習の標準的な流れ
- FasterRCNNとYOLOv5の使い方
→YOLOv5は使ってみたけど最終的にはライセンスの問題で使用不可となりました - 画像の前処理のライブラリ(albumentation, OpenCV)の使い方
- 画像の代表的な前処理(DataAugumentation)
- kaggle kernelの使い方
・datasetのアップロード方法
・internet使用不可の場合のライブラリ追加方法
4. EDA
小麦画像可視化
バウンディングボックスの位置・幅・高さは画像ごとに下記のようにCSVで与えられています。
"width", "height"列は画像自体のサイズで、1024px x 1024pxの画像ということです。
"x", "y" は各バウンディングボックスの左上の座標で、"w", "h"がその幅と高さです。
これらを基に下記のような画像を作ることでバウンディングボックスの形状や配置を理解することができます。
異常な大きさのバウンディングボックス
バウンディングボックスのCSVから面積の分布を観察しました。
上のグラフからは面積50万平方pxということで、1024px四方にも関わらず700px x 700px程度の大きさもありうることが示唆され、また逆に下の図からは数平方pxの非常に小さいバウンディングボックスが存在することがわかります。
実際に対象の画像を可視化すると下記のようになっていました。
最大面積のバウンディングボックスの方は見ての通りですが、最小面積の方は右下をよく見ると
という点のようなバウンディングボックスがあります。
これらは教師データとしてはノイズとなるので、除外します。
具体的には面積をあらかじめ計算し、観察した結果から上限・下限を決め打ちし、範囲外のバウンディングボックスを除外します。
また、学習用のデータセットの画像はより大きな画像から切り出された画像であることが元の論文からわかるそうです。(僕は未着手です)
なんとかして切り貼りして元の画像を復元することで新しい画像を作り出すこともできたようです。
https://www.kaggle.com/c/global-wheat-detection/discussion/149805
5. 重要だった前処理
画像処理
用いたライブラリ
- albumentations
https://albumentations.readthedocs.io/en/latest/
画像のデータ拡張のために作られたライブラリで、PyTorchのDatasetクラスのtransform関数に直接組み込めたり、最終的にPyTorchで実行する為に必要なtorch.Tensorクラスに変換することができる。
何ができるかは下記の記事がよくまとまっています。
https://qiita.com/Takayoshi_Makabe/items/79c8a5ba692aa94043f7 - OpenCV
https://opencv.org/
定番の画像処理ライブラリ - NumPy
https://numpy.org/
定番の行列計算ライブラリ
numpyのメソッドで画像処理ができるわけではないけど、画像データを配列として要素の入れ替えなどしました
前処理の種類
アフィン変換
- 回転
- 拡大・縮小
- 上下左右反転(マイナス倍の拡大縮小)
- せん断(やってない)
- 平行移動
https://imagingsolution.blog.fc2.com/blog-entry-284.html
の画像がわかりやすく、大きく4種類です。
画像の一部分を切り出すこと
HSV変換
画像データの表現方法の一つ、HSV(Hue-Sturation-Value=色相-彩度-明度)を調整すること
モザイク
ここでのモザイクは画像をぼかすことではなく、複数(今回は四枚)の画像を切り貼りして一つの画像とすることでした
cut-out
CNNの正則化手法の一つで、画像の一部を塗りつぶして欠落させること
これらを試した結果の前後が下図です。
画像処理後、範囲外やcut-outで画像が小麦がなくなった箇所のバウンディングボックスは削除や変形が必要です。
albumentationsを用いた場合には自動で処理してくれるメソッドもありますが、してくれないメソッドもあります。
- バウンディングボックスを処理してくれる:
https://www.kaggle.com/c/global-wheat-detection/discussion/149805 - バウンディングボックスを処理してくれない:
https://www.kaggle.com/c/global-wheat-detection/discussion/149805
なのでcut-outやモザイクは下記のノートブックのように自作関数で処理しています。
https://www.kaggle.com/nvnnghia/awesome-augmentation#Augmentation-functions
また、僕は今回適用する時間がなかったのですが下記のmix-upも有効だったようです。
mix-up
2つの画像を透過させる形で重ね合わせる手法です。
概要は下記の記事をご参照ください。
https://qiita.com/yu4u/items/70aa007346ec73b7ff05
https://www.kaggle.com/kaushal2896/data-augmentation-tutorial-basic-cutout-mixup#Let's-define-new-augmentations
Pseudo-labeling(擬似ラベリング)
COCOなどで作成された事前学習モデルから今回の小麦データで再学習する前に、検証用のpublicの画像データにバウンディングボックスを推論し、検証用データも学習データに含めること。
データの水増しとエントロピー減少に役立つらしい。
ノートブック
https://www.kaggle.com/nvnnghia/fasterrcnn-pseudo-labeling
元論文
http://deeplearning.net/wp-content/uploads/2013/03/pseudo_label_final.pdf
6. よく利用されていたアルゴリズム
Faster-RCNN
https://qiita.com/mshinoda88/items/9770ee671ea27f2c81a9#2-5-faster-r-cnn
EfficientDet
https://www.kaggle.com/shonenkov/training-efficientdet
YOLOv5(ライセンスの問題で使用不可)
https://github.com/ultralytics/yolov5
7. 苦労したこと
データ拡張のハイパーパラメータ調整
上記の前処理ではHSV・回転角・平行移動の距離などを元の画像からどれだけ変調するかというのがパラメータでした。
またここで紹介した以外にもコントラスト・ブライトネスの調整した方がいいのかなど、public scoreを見てみないとわかりませんでしたので、試したものを全て記録・比較しました。
実行した結果がどのノートブックかわかるように「ver」で管理していました。
albumentationsでのデータ拡張とそれ以外のデータ拡張を組み合わせること
top kernelの方々を参考にしつつ上記の要領で前処理を試しては追加しました。
この時の実行順やデータ型が適切でなくてエラーになったり、バウンディングボックスの座標が崩れました。
特に順番に決まりはないと思いますが、自作関数で前処理を追加した前後ではバウンディングボックスの数・位置・サイズを確認し、削除されるべきものが削除されているかなど確認しました。
dataloderのreturnではtorch.Tensorになっているようにしました。
YOLOv5など外部レポジトリを用いてモデル作成するときのバージョン管理
特にYOLOv5が日々アップデートされていたからですが、後から追いつこうとした場合に採用しているpytorchなどのバージョンが異なっていて、あるべきメソッドがなかったり、CUDAがうまく使えなかったです。
discussionやノートブックが共有されたら早めにキャッチアップしましょう。
8. 反省・これから頑張りたいこと
- PyTorchのお作法を学ぶ
・入力データのTensorのndimやshapeがどうあるべきか
・DatasetやDataloaderの挙動を理解する
・学習済みモデルの重みのセーブ・ロードの方法に何パターンかあり、状況に応じて使い分けられるようになる - (既存の手法を組み合わせるとしても)ゼロからスクリプトを書けるようになること
・今回はtop kernelのノートブックをforkしてそのまま使わせていただいたので、自分で必要と思う処理を探してきて、インターフェースに気をつけながら自分で組み合わせられるようになる - top kernelのノートブックを鮮度が新しいうちに真似すること
・時間が経つとノートブック内で参照されている外部レポジトリがアップデートされて、ノートブックだけforkしてもそのままでは実行できない状態になっている。その結果デバッグに無駄な時間を費やす(結果的に勉強にはなるのだけど、コンペ向きではない)
9. 基礎知識
kaggleカーネル
- データセット
外部ファイルなどをノートブックで使えるようにするには、kernelの右側で「add data」でできます。
- pip
インターネットが使えるコンペであればいつものこれです!pip install ライブラリ名
手元で実行している分にはこれでいいですが、submitする場合にはこれではダメです。
これはあらかじめwhlファイルを取得してkaggle datasetにアップロードしておくことで対処できます。
https://www.kaggle.com/c/severstal-steel-defect-detection/discussion/113195 - GitHub連携
データセットアップロード画面にGitHubの項目があります。
- 読み取り・書き込み権限
・inputフォルダ:予めデータセットとしてデータを格納することが可能。
しかし、後からファイル保存や書き込みは不可。
・outputフォルダ:予めデータを格納することは不可。
しかし、後からファイル保存や書き込みは可能。
使用するレポジトリの都合でファイルが作成される場合などはこちらに出力するようにしておく必要がある。 - ノートブックから「.py」ファイル中でCUDAを実行するための環境構築
コンペ終了直前でPyTorchが1.6.0にアップデートされました。
そのままYOLOv5などのスクリプトを実行しようとすると、CUDAが認識されませんでした。
原因は不明ですが、下記のノートの通りに「torch==1.6.0+cu101」であれば実行可能でした。
https://www.kaggle.com/okeaditya/what-s-new-in-pytorch-1-6
評価指標
- MAP(Mean Average Precision):
・物体検出の評価指標の一つ
・検出された物体のうちラベルが正解だったものの割合がPrecision
・IoUの閾値を0~1で変化させた時の平均がAverage Precision
・全ての画像についてAverage Precisionを平均したのがMean Average Precision - IoU(Intersection of Union) :
・物体検出の評価指標の一つ
・教師データと推論したバウンディングボックスの重なりの正確さを示す
・(教師データと推論結果の領域の積集合) / (教師データと推論結果の領域の和集合)
・全く重なっている部分がなければ0、ぴったり重なっていれば1、一部分が重なっていたり領域が包含関係にある場合には0~1の間となる。