<jupyter_start><jupyter_text><jupyter_code>from google.colab import drive
drive.mount('/content/gdrive')
cd/content/gdrive/MyDrive/Colab Notebooks/QHK2021/04_test
!pip install pennylane --upgrade
!pip install qiskit ipywidgets
import pennylane as qml
from pennylane import numpy as np
from pennylane.templates import RandomLayers
import matplotlib.pyplot as plt
from qiskit import *
import torch
from torch.autograd import Variable
from torchvision import datasets, transforms
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import SubsetRandomSampler

import numpy.random as random
import pandas as pd
use_cuda = torch.cuda.is_available()
print(use_cuda)
n_epochs = 30     # Number of optimization epochs
n_channels = 1    # Number of channels
n_train = 128     # Size of the train dataset
n_test = 32       # Size of the test dataset
BATCH_SIZE = 16   # Size of batch

SAVE_PATH = "quanvolution_pqc/"   # Data saving folder
PREPROCESS = True                 # If False, skip quantum processing and load data from SAVE_PATH
random.seed(0)                    # Seed for NumPy random number generator

n_poly = 5                  # Order of polynomials
n_kernel = 3**2             # Size of kernel

rand_params = random.default_rng()
rand_params = 1 - rand_params.standard_normal(size=(n_channels, n_poly, n_kernel))
train_dataset = datasets.MNIST(root = "./",
                               train = True,
                               download = True,
                               transform = transforms.ToTensor())

test_dataset = datasets.MNIST(root = "./",
                              train = False,
                              download = False,
                              transform = transforms.ToTensor())

train_sampler = SubsetRandomSampler(range(n_train))
test_sampler = SubsetRandomSampler(range(n_test))

train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
                                           batch_size = BATCH_SIZE,
                                           shuffle = False,
                                           sampler = train_sampler)

test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
                                          batch_size = BATCH_SIZE,
                                          shuffle = False,
                                          sampler = test_sampler)
token1 = '2b740fada862fb6d9683487f84455ff8fccb2caaa3988e4f406d321ef67ce0644eb679211a1b6a377ec5ee9b3839d34434255304ab535a9ed11ce60703f07446'
token2 = '<KEY>'

# from qiskit import IBMQ
# IBMQ.save_account(token2)
# provider = IBMQ.enable_account(token1)
dev = qml.device("default.qubit", wires=9)
# dev = qml.device('qiskit.ibmq', wires=9, backend='ibmq_qasm_simulator',provider=provider)
# IBMQ.get_provider(hub='ibm-q', group='open', project='main')
# dev = qml.device('qiskit.ibmq', wires=9, backend='ibmq_qasm_simulator',
                #  ibmqx_token=token1, hub='ibm-q', group='open', project='main')
# print(dev.capabilities()['backend'])
# import pennylane as qml
# from pennylane_ionq import ops

# dev = qml.device("ionq.qpu", wires=9)

# Random circuit parameters

@qml.qnode(dev, interface='torch')
def pqc(data,params):
    # Encoding of 9 classical input values
    # len(params) = 2 * 9
    # print("data: ",data)
    # print("params: ",params)
    n_qubits = 9
    for j in range(n_qubits):
        qml.RY(np.pi * data[j], wires=j)
    
    # rand_params = np.random.uniform(high=2 * np.pi, size=(n_channels, 9))
    # print("rand", rand_params)
    # PQC
    for i in range(n_qubits):
        qml.RY(params[i], wires=i)
    for i in range(n_qubits-1):
        qml.CNOT(wires=[i,i+1])    
    qml.CNOT(wires=[n_qubits-1,0])
    for i in range(n_qubits):
        qml.RY(params[i+n_qubits], wires=i)
    # Measurement producing 9 classical output values
    return qml.expval(qml.PauliZ(0))
print(pqc([1,0,2,1,2,3,1,2,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]))
class QuanvNet(torch.nn.Module):
    def __init__(self, qc=True, opt=True):
        super().__init__()
        self.qc = qc
        self.opt = opt
        self.n_qubits = 9
        self.filters = 1
        self.conv_opt = torch.nn.Conv2d(in_channels=self.filters,out_channels=self.filters,kernel_size=3)
        self.conv1 = torch.nn.Conv2d(in_channels=self.filters,out_channels=8,kernel_size=3,padding='same')
        self.pre_pool = torch.nn.AvgPool2d(2)
        self.pool = torch.nn.MaxPool2d(2)
        self.conv2 = torch.nn.Conv2d(in_channels=8,out_channels=8,kernel_size=3)
        self.fc1 = torch.nn.Linear(32,16)
        self.fc2 = torch.nn.Linear(16,10)
        self.dropout = torch.nn.Dropout(0.4)
        self.q_params = torch.nn.Parameter(2*np.pi*torch.rand(12,12,self.filters,2*self.n_qubits))
        self.q_params.requires_grad = True

    def forward(self, inputs):
        if self.qc == True:
          out = torch.zeros((BATCH_SIZE,self.filters,12,12))
          for bat, image in enumerate(inputs):
              for j in range(1, 13, 1):
                  for k in range(1, 13, 1):
                      for i in range(self.filters):
                          q_results = pqc(
                          [
                              image[0, j - 1, k - 1].item(),
                              image[0, j - 1, k].item(),
                              image[0, j - 1, k + 1].item(),
                              image[0, j, k - 1].item(),
                              image[0, j, k].item(),
                              image[0, j, k + 1].item(),
                              image[0, j + 1, k - 1].item(),
                              image[0, j + 1, k].item(),
                              image[0, j + 1, k + 1].item()
                          ],
                              self.q_params[j-1,k-1,i]
                          )
                          out[bat,i,j - 1, k - 1] = q_results
        else:
          out = torch.zeros((BATCH_SIZE,self.filters,14,14))
          out = inputs
        print(out.size())
        if use_cuda:
          out = out.cuda()
        if self.opt==True:
          out = self.conv_opt(inputs)
        x = self.pool(F.relu(self.conv1(out)))
        print(x.size())
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x,1)
        print(x.size())
        x = F.relu(self.fc1(x))
        x = self.dropout(x)
        x = F.softmax(self.fc2(x))
        return x

## Random Polynomial Definition
def rand_poly(x_kernel):

  # result_array = []
  # for i in range(n_channels):
    i = 0                     # i is originally channel index
    result = .0
    for j in range(n_poly):
      for k, x in enumerate(x_kernel):
        result = result + rand_params[i, j, k] * (x ** j)
    # result_array.append(result)

    # originally returns result_array
    return result
class NLNet(torch.nn.Module):
    def __init__(self, nl=True, opt=False):
        super().__init__()
        self.nl = nl
        self.opt = opt
        self.filters = 1
        self.conv_opt = torch.nn.Conv2d(in_channels=self.filters,out_channels=self.filters,kernel_size=3)
        self.conv1 = torch.nn.Conv2d(in_channels=self.filters,out_channels=8,kernel_size=3,padding='same')
        self.pre_pool = torch.nn.AvgPool2d(2)
        self.pool = torch.nn.MaxPool2d(2)
        self.conv2 = torch.nn.Conv2d(in_channels=8,out_channels=8,kernel_size=3)
        self.fc1 = torch.nn.Linear(32,16)
        self.fc2 = torch.nn.Linear(16,10)
        self.dropout = torch.nn.Dropout(0.4)

    def forward(self, inputs):
        if self.nl == True:
          out = torch.zeros((BATCH_SIZE,self.filters,12,12))
          for bat, image in enumerate(inputs):
              for j in range(1, 13, 1):
                  for k in range(1, 13, 1):
                      for i in range(self.filters):
                          nl_results = rand_poly(
                          [
                              image[0, j - 1, k - 1].item(),
                              image[0, j - 1, k].item(),
                              image[0, j - 1, k + 1].item(),
                              image[0, j, k - 1].item(),
                              image[0, j, k].item(),
                              image[0, j, k + 1].item(),
                              image[0, j + 1, k - 1].item(),
                              image[0, j + 1, k].item(),
                              image[0, j + 1, k + 1].item()
                          ]
                          )
                          out[bat,i,j - 1, k - 1] = nl_results
        else:
          out = torch.zeros((BATCH_SIZE,self.filters,14,14))
          out = inputs
        # print(out.size())
        if use_cuda:
          out = out.cuda()
        if self.opt==True:
          out = self.conv_opt(inputs)
        x = self.pool(F.relu(self.conv1(out)))
        # print(x.size())
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x,1)
        # print(x.size())
        x = F.relu(self.fc1(x))
        x = self.dropout(x)
        x = F.softmax(self.fc2(x))
        return x

from torchsummary import summary
criterion = torch.nn.CrossEntropyLoss()
# model = QuanvNet(qc=True, opt=False)
model = NLNet(nl=True, opt=False)
if use_cuda:
    model.cuda()
opt = optim.Adam(model.parameters(),lr=0.01)
summary(model,(1,14,14))
for p in model.parameters():
    print(p.shape)
losses = []
accs = []
for epoch in range(1000):
  train_loss = 0
  acc = 0
  for (x_train, y_train) in train_loader:
    # print(y_train)
    opt.zero_grad()
    outputs = model(x_train.cuda() if use_cuda else x_train)
    _, preds = torch.max(outputs,1)
    acc += (preds==(y_train.cuda() if use_cuda else y_train)).sum().item()
    loss = criterion(outputs,(y_train.cuda() if use_cuda else y_train))
    loss.backward()
    opt.step()
    train_loss += loss
    del loss
  acc /= n_train
  train_loss /= (n_train/BATCH_SIZE)
  if epoch%10 == 9:
    if epoch%10 == 9:
      print(epoch+1,train_loss)
    losses.append(train_loss.item())
  if epoch%10 == 9:
    accs.append(acc) 
  del acc
from matplotlib.pyplot import plot
x = np.arange(0,10000,10)
plot(x,losses)
x = np.arange(0,10000,10)
plot(x,accs)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12587275051627494, 'fraction_numerical': 0.03422165404661225, 'mean_word_length': 1.9198966408268734, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 15, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '151097', 'license': 'MIT', 'n_tokens_mistral': 3579, 'n_tokens_neox': 3376, 'n_words': 694, 'path': 'Boseong Kim/04_test.ipynb', 'repo_name': 'JadeKim/2021QuantumHackatonKorea', 'size': '10292'}