LoginSignup
5
2

More than 3 years have passed since last update.

Qiskit: 人工ニューロンを量子回路で実現する(実装)

Last updated at Posted at 2020-04-11

はじめに

人工ニューロンを量子回路で実現しようという論文があったので私も実装してみました.
An artificial neuron implemented on actual quantum processor

m qubitsを用いた場合,$2^m$次元の入力を扱えるようになるらしいです.
ここでは,シグモイド関数等の活性化関数を作用させる手前までの計算を行います.

軽い解説

入力ベクトル$\vec{i}$と重みベクトル$\vec{w}$を以下のように定義します.

\vec{i} = (i_0, i_1, \cdots,i_{m-1}) \\ \vec{w} = (w_0, w_1, \cdots, w_{m-1})

ただし,$i_j , w_j \in {-1, 1}$とする.
ここで,二つの量子状態を考える.

|\psi_i> = \frac{1}{\sqrt{m}} \sum_{j=0}^{m-1} i_j|j> \\
|\psi_w> = \frac{1}{\sqrt{m}} \sum_{j=0}^{m-1} w_j|j> 

ただし,$|j> = {|0>, |1>, \cdots, |m-1>}$とする.
また,$U_i$と$U_w$を次のように定義する.

U_i |0>^{\otimes N} = |\psi_i> \\
U_w |\psi_i> = |1>^{\otimes N} = |m-1> \\
U_w|\psi_i> = \sum_{j=0}^{m-1} c_j |j> \equiv |\phi_{i,w} >

2つの量子状態の内積を求めると,

<\psi_w|\psi_i> = <\psi_w|U_w^{\dagger} U_w|\psi_i>=<m-1|\phi_{i,w}> = c_{m-1}

ancilla bitを追加し,それをtarget bitにしたmulti-controlled NOT gateを作用させると

|\phi_{i,w}>|0>_a = \sum_{j=0}^{m-2} c_j |j>|0>_a + c_{m-1}|m-1>|1>_a 

code

$U_i$と$U_w$の作成にはQuantum Hypergraph stateを用いています.

# coding: utf-8

from quantum_hypergraph_state import QuantumHypergraphState
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute
from qiskit import BasicAer

import numpy as np


class QuantumNeuron:

    def __init__(self, using_qubits, input, weight):
        self.num_of_input = using_qubits
        self.index = [i for i in range(self.num_of_input)]
        self.input = input
        self.weight = weight
        self.qr = QuantumRegister(self.num_of_input, name='qubits')   # input qubits and ancilla bit
        self.target = QuantumRegister(1, name='target_bit')
        self.qc = QuantumCircuit(self.qr, self.target)

    def construct_circuit(self):
        inputs = QuantumHypergraphState(self.num_of_input, self.input)
        inputs.construct_circuit(self.qc)
        weight = QuantumHypergraphState(self.num_of_input, self.weight)
        weight.construct_circuit(self.qc, inverse=True)
        ancilla_qubits = QuantumRegister(1)
        classical = ClassicalRegister(1)
        self.qc.add_register(ancilla_qubits)
        self.qc.add_register(classical)
        self.qc.mct([self.qr[i] for i in range(self.num_of_input)],
                    self.target[0],
                    q_ancilla=[ancilla_qubits[i] for i in range(1)])
        self.qc.measure(self.target[0], classical[0])

    def print_details(self, draw=False):
        print('num_of_input: {}'.format(self.num_of_input))
        print('index: {}'.format(self.index))
        if draw:
            print(self.qc.draw())


if __name__ == '__main__':
    num_qubits = 2
    sample = QuantumNeuron(num_qubits, input=[1, 1, 1, 1], weight=[1, 1, -1, -1])
    sample.construct_circuit()
    NUM_SHOTS = 10000
    seed = 1234
    backend = BasicAer.get_backend('qasm_simulator')
    results = execute(sample.qc, backend=backend, shots=NUM_SHOTS, seed_simulator=seed).result()
    sample.print_details()
    counts = results.get_counts()
    print(np.sqrt(counts['1'] / NUM_SHOTS) * 2**num_qubits)
5
2
0

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
5
2