LoginSignup
13
5

More than 1 year has passed since last update.

量子回路学習とDeBERTaで英文の分類

Last updated at Posted at 2022-12-01

この記事はBrainPad Advent Calender 2022 1日目の記事です。
今日はQuantum Circuit Learning(量子回路学習)とDeBERTaを使った英文の分類についての話をしたいと思います。
※本記事の量子計算は量子コンピュータのシミュレータを使っています。量子コンピュータは使っていません。

はじめに

 新卒一年目のBrainPadのデータサイエンティストです。そろそろ量子計算を使いたい季節になってきましたね。ということで量子計算(量子アルゴリズム)を使って何か書こうと考えたのですが、現在実装できる量子アルゴリズムで実務レベルで古典のアルゴリズムに勝てるものは私の知る限りではありません。そこでなにか量子計算が役に立つタスクがないかと試したのがこの記事になります。
 今回は自然言語処理のタスクである文章分類(英文の分類)をkaggleでもよく使われるモデルのDeBERTaと量子アルゴリズムのQCL(量子回路学習)をHuggingFaceとPennyLane使って実装し、普通のニューラルネットワークのDeBERTaと比較します。結果は...
実装:Google colab
記事に誤り等ありましたらご指摘いただけますと幸いです。

目次

1. QCL(量子回路学習)とは

 QCL(量子回路学習)は、NISQ(Noisy Intermediate Scale Quantum)(現在、および近い未来のノイズがある量子コンピュータ)で動くことを目指した量子機械学習アルゴリズムです。
論文:Quantum Circuit Learning

QCLについて

 ゲート型量子コンピュータの一般的な計算方法では、以下のような複数の量子ゲートを使って量子回路を組み量子ビットを変化させ最後に量子ビットを測定することで計算結果を取り出します。

図1. 量子回路の例
(引用元:量子回路の可視化)

 量子回路学習では、上記の量子回路に後から変更することが可能なパラメータを持つ量子ゲートを加えることで量子回路からの出力を変更できるようにします。さらにこのパラメータを出力したい値に近づけるために最適化し、量子回路で任意の関数関係を表現することを目指します。
 このような学習の方法は皆さんお馴染みのニューラルネットワークでの学習と非常に類似しています。ニューラルネットワークではパラメータ付きの線形変換器と非線形変換器(活性化関数)を使ったモデルを使い訓練データの入出力関係を近似するように学習を行います。一方、量子回路学習では複数量子ビットのテンソル積構造による非線形性を使い、パラメータは量子ゲートの回転操作の回転角として表現します。
 以下が今回扱う量子回路の概略図です。左側のブロックがデータの入力を行う量子ゲートで右側のブロックがパラメータを含む量子ゲートになっています。

図2. 量子回路学習の量子回路
(引用元:http://docs.qulacs.org/en/latest/apply/5.2_qcl.html)

 また量子回路を学習モデルに使うことで、重ね合わせの原理による高次元の特徴量空間が利用でき、古典のアルゴリズムに比べて効率的に表現しにくい非線形モデルを構築できるそうです。また、量子ゲートは全てユニタリー変換であり、ノルムが常に1であることがある種の正則化として機能し過学習が抑えられるそうです。
関連研究には以下のようなものがあります。
On the Expressibility and Overfitting of Quantum Circuit Learning

それでは量子回路学習のための量子回路の実装方法について説明します。

PENNYLANEについて

量子回路を組むと言っても現在では優秀なライブラリがあるおかげで簡単に実装することができます。
今回はXanadu(ザナドゥ)という会社のPennyLaneというPythonのライブラリを使います。他にも量子計算を試すためのライブラリは、

などたくさんあります。

QCLの実装

QCLの実装としては色々な方法が提案されています。今回は3つほど量子回路学習モデルを実装します。初めにベースになるものの実装です。

n_qubits = 10
num_wires = 10
n_layers = 1

# C++で書かれた高速シミュレータ
dev = qml.device("lightning.qubit", wires=num_wires)

@qml.qnode(dev, diff_method='adjoint')
def qnode(inputs, weights):
    # 入力データの埋め込みに使う量子ゲート
    qml.AngleEmbedding(inputs, wires=range(n_qubits))
    # パラメータ付きの回路と量子もつれのための回路
    qml.StronglyEntanglingLayers(weights, wires=range(n_qubits))
    # 全ての量子ビットをz基底で測定する
    return [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)]

以上で量子回路自体の実装は完了です。すごく簡単です!!
今回実装した量子回路は、以下のような構造になっています。

これを細かく表示したのが下の図で、左から順番に以下の量子ゲートが量子ビットに作用しています。

  1. RX回転ゲートで入力データを回転角度として埋め込む
  2. RX,RY,RZの回転ゲートで量子ビットを回転させる、ここの回転角度がパラメータ
    回転ゲートについては以下の記事などが参考になるかもしれません
    量子コンピュータの基本 - 回転ゲートについてしっかり学ぶ
  3. CNOTゲートにより量子もつれ状態を作る(隣接量子ビット間で量子もつれを作る)
  4. Z基底で測定を行い出力データとする

この量子回路を1layer QCLとします。

その他に今回は以下のような量子回路でも検証を行いました。
parameter 3layer QCL:量子回路のパラメータ部分をさらに3回繰り返したもの

3layer QCL:埋め込み層も含めて量子回路をさらに3回繰り返したもの

ここまでできればあとはDeBERTaのモデルにQCLの量子回路を組み込むだけです。

2. 全体の実装

 今回は全体の実装をpytorchで行いました。学習の可視化にはwandbを使っています。全体の実装は以下からも確認できます。
Google colab

主に必要なライブラリ

pip install datasets
pip install transformers
pip install PennyLane
pip install wandb
from tqdm.notebook import tqdm
from sklearn.metrics import roc_auc_score

import torch
import torch.nn as nn
from torch.optim import lr_scheduler
from torch.utils.data import Dataset, DataLoader
from datasets import load_dataset
from torchinfo import summary

from transformers import DataCollatorWithPadding
from transformers import AutoModel, AutoTokenizer, AutoConfig, AdamW

# 量子機械学習ライブラリ
import pennylane as qml
from pennylane import numpy as np

利用したデータセット

 英語の映画レビューデータセットで、各レビューに対してネガティブかポジティブか二値のレベルが付与されています。

imdb = load_dataset("imdb")
train_df = pd.DataFrame()
train_df['text'] = imdb['train']['text']
train_df['label'] = imdb['train']['label']
train_df.head()

以下のようなデータが含まれています。
スクリーンショット 2022-12-01 2.38.15.png

モデル全体像

 DeBERTaとQCLを使うと書いていますがモデルの構造は単純でDeBERTaのCLSトークンの出力をQCLに入力できるサイズに全結合層でサイズを減らしQCLに入力、QCLの出力を全結合層に通して二値分類の出力にしています。

モデルの実装

それではDeBERTaにくっつけます。
以下が今回使用したモデルで見ての通りほとんどが通常の自然言語処理のモデルになっています、先ほど実装したqnodeが新しく追加されているだけです。

class HybridModel(torch.nn.Module):
    def __init__(self, cfg):
        super().__init__()
        self.cfg =cfg
        self.backbone = AutoModel.from_pretrained('microsoft/deberta-base')
        self.config = AutoConfig.from_pretrained('microsoft/deberta-base')

        self.Linear1 = nn.Linear(self.config.hidden_size, 10)
        self.Linear3 = nn.Linear(10, self.cfg.num_classes)

        # ここが量子回路になります!!
        # 先ほど実装したqnodeと重みの形状が引数として与えられています。
        self.qlayer = qml.qnn.TorchLayer(qnode, weight_shapes)

        self.criterion = nn.CrossEntropyLoss()
        
    def forward(self, input_ids, attention_mask, label = None):
        out = self.backbone(input_ids = input_ids, attention_mask = attention_mask,
                         output_hidden_states = False)
        output = out[0][:, 0, :]
        output = self.Linear1(output)
        output = self.qlayer(output)
        output = self.Linear3(output)

        if label is not None:
            loss = self.criterion(output, label)
        else:
            loss = None
        return output, loss 

※pennylaneではKerasにも量子回路を組み込むことができるそうです。

その他

 あとは通常のディープラーニンモデルの学習を行う時の実装と同じです。Dataloaderやoptimizer,scheduler,モデルの評価のタイミングなど自由に実装してください!!ディープラーニングの分かりやすい実装方法の記事は世の中にたくさんあるので、ここではそれらの実装方法については省略します。

3. 結果

 学習の様子はwandbで可視化しました、学習曲線の様子は以下です。
QCLを含むモデルは圧倒的に学習が収束するのが遅かったです、精度は少しずつ良くなってはいるのですが学習は途中までで止めています。

※DeBERTa-baseは1epoch、それ以外は3epochまで学習させています。
 続いて、AUCは以下のようになりました。
ハイパラ探索などは行っていないので以下のスコアは参考程度になります。

モデル AUC
DeBERTa-base 0.98963
DeBERTa-base + 1layer QCL 0.97975
DeBERTa-base + parameter 3layer QCL 0.96981
DeBERTa-base + 3layer QCL 0.96982

 今回の英文の分類タスクがそもそも簡単なタスクであったみたいで、どれも非常に高い精度となりました。
学習の収束の速さに関しては通常のディープラーニングモデルが圧倒的であったので量子回路学習をより早く収束させる方法を模索したいと思いました。

改善点

改善できそうな箇所を以下に記載しています。

  • 量子回路学習の量子回路を変更する
    パラメータ量子回路は以下のように他にも用意されているので変更することができます。
qml.BasicEntanglerLayers(weights, wires=range(n_qubits))
  • optimizerの変更
  • schedulerの変更
  • 量子回路の組み込み方を変える
    以下では並列して複数の量子回路を使う方法が提案されている
    Turning quantum nodes into Torch Layers
  • 他のデータセットで試す
    など、さまざまな変更を加えることができそうです。

4. おわりに

 今回は量子機械学習アルゴリズムであるQCLをDeBERTaの出力部分に加えたモデルを使い、英語の文章分類のタスクで検証を行いました。結果はQCLを使ったものでもある程度精度が出せることが分かりましたが、従来のモデルに比べて精度(正確には途中で止めたので分かりませんが...)および学習の収束速度で劣っている結果になりました。
 予測の得意なデータと不得意なデータが通常のDeBERTaとDeBERTa+QCLのモデルで異なっていたりすれば、2つのモデルでアンサンブルすることでより精度を高めるなど量子機械学習が役に立つ可能性を見出せそうだな〜とか思いましたが、今回は間に合わず検証できませんでした。
 引き続き量子機械学習モデルを現実のデータセットに対して活用し検証をしていきたいと考えています。いつかkaggleとかで量子機械学習が活躍していたらいいですね〜

5. 参考文献

6. 論文

13
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5