Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2022
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.53 KB | None | 0 0
  1.  
  2. from tqdm import tqdm
  3. import os
  4. from functools import partial
  5. import pandas as pd
  6. from functools import partial
  7. from torch.utils.data import DataLoader
  8. from torch.utils.data import Dataset
  9. import torch
  10.  
  11. # QML
  12. import pennylane as qml
  13. from pennylane import numpy as np
  14. from pennylane.optimize import NesterovMomentumOptimizer, QNGOptimizer
  15. from pennylane.templates.embeddings import AmplitudeEmbedding,AngleEmbedding
  16.  
  17.  
  18.  
  19. #################################################################
  20. # DEFINING CIRCUITS
  21. #################################################################
  22.  
  23. def circuit1(params, embedding, n_layers, n_qubits, x):
  24. embedding(x)
  25.  
  26. for layer in range(n_layers):
  27. W = params[layer]
  28.  
  29. # Define Rotations
  30. for i in range(n_qubits):
  31. qml.Rot(W[i, 0], W[i, 1], W[i, 2], wires=i)
  32.  
  33. # CNots
  34. if n_qubits > 1: # Da erro quando n_qubits=1 coz nao pode haver CNots TODO?
  35. for i in range(n_qubits):
  36. if i == n_qubits-1:
  37. qml.CNOT(wires=[i, 0])
  38. else:
  39. qml.CNOT(wires=[i, i+1])
  40.  
  41. return qml.expval(qml.PauliZ(0))
  42.  
  43.  
  44. def circuit2(params, embedding, n_layers, n_qubits, x):
  45. embedding(x)
  46.  
  47. for layer in range(n_layers):
  48. W = params[layer]
  49. for i in range(n_qubits):
  50. qml.Rot(W[i, 0], W[i, 1], W[i, 2], wires=i)
  51.  
  52. if n_qubits > 1: # Da erro quando n_qubits=1 coz nao pode haver CNots TODO?
  53. for i in range(n_qubits):
  54. for j in range(i+1,n_qubits):
  55. qml.CNOT(wires=[i, j])
  56.  
  57. return qml.expval(qml.PauliZ(0))
  58.  
  59.  
  60. #################################################################
  61. # DEFINING DATALOADERS
  62. #################################################################
  63.  
  64. class BankData(Dataset):
  65. """
  66. This will load the data
  67. """
  68. def __init__(self, category, standardization='ML'):
  69.  
  70. # Load data_banknote_authentication.txt
  71. # https://archive.ics.uci.edu/ml/machine-learning-databases/00267/data_banknote_authentication.txt
  72. # 1 Variance of Wavelet Transformed image (continuous).
  73. # 2 Skewness of Wavelet Transformed image (continuous).
  74. # 3 Kurtosis of Wavelet Transformed image (continuous).
  75. # 4 Entropy of image (continuous).
  76. # 5 label (0 for authentic, 1 for inauthentic).
  77. if 'data_banknote_authentication.txt' not in os.listdir():
  78. os.system('wget https://archive.ics.uci.edu/ml/machine-learning-databases/00267/data_banknote_authentication.txt')
  79.  
  80.  
  81. self.data = pd.DataFrame(np.loadtxt('data_banknote_authentication.txt', delimiter=','))
  82. self.data.columns = ['var', 'skew', 'kurt', 'ent', 'label']
  83.  
  84. # Sanity checks
  85. assert category in {'train', 'validation', 'test', 'all'}, "Invalid category!"
  86.  
  87.  
  88. # Standardization
  89. _features = self.data.columns[:-1] # Everything except label
  90.  
  91. if standardization == 'ML':
  92. self.data[_features] = (self.data[_features]-self.data[_features].mean())/self.data[_features].std()
  93.  
  94. elif standardization == 'AngleEmbedding':
  95. # Put the data between -pi and pi
  96. self.data[_features] = self.data[_features] % (2*np.pi)
  97. pass
  98. elif standardization == 'AmplitudeEmbedding':
  99. pass
  100. else:
  101. # Error
  102. raise ValueError("Invalid standardization!")
  103.  
  104.  
  105. # This will equally devide the dataset into
  106. # train, validation and test
  107. train, validation, test = np.split(self.data, [int(len(self.data)*(1/3)), int(len(self.data)*(2/3))])
  108.  
  109. if category == "train":
  110. self.data = train
  111. elif category == "validation":
  112. self.data = validation
  113. elif category == "test":
  114. self.data = test
  115. elif category == "all":
  116. pass
  117. else:
  118. # error
  119. raise ValueError("Invalid category!")
  120.  
  121. del train, validation, test
  122.  
  123. self.label = self.data["label"]
  124. self.data.drop(columns=["label"], inplace=True)
  125.  
  126. self.n_samples = self.data.shape[0]
  127.  
  128. def get_columns(self):
  129. return self.data.columns
  130.  
  131. def __getitem__(self, index):
  132. # Data, Label
  133. return torch.tensor(self.data.iloc[index]), \
  134. torch.tensor(self.label.iloc[index])
  135.  
  136. def __len__(self):
  137. return self.n_samples
  138.  
  139.  
  140. #################################################################
  141. # TRAINING LOOP
  142. #################################################################
  143.  
  144.  
  145. class Trainer():
  146. def __init__(self, parameteres):
  147. # Get parameters
  148. self.max_epochs = parameteres['max_epochs']
  149. self.batch_size = parameteres['batch_size']
  150. self.circuit_name = parameteres['circuit_name']
  151. self.n_features = parameteres['n_features']
  152. self.embedding_method = parameteres['embedding_method']
  153. self.n_layers = parameteres['n_layers']
  154.  
  155. # This assumes I'm using angle embedding for demonstration purposes
  156. self.n_qubits = self.n_features
  157. self.embedding = partial(globals()[self.embedding_method], wires=range(self.n_qubits), rotation='Z')
  158. self.normalization = self.embedding_method
  159.  
  160. # Defining device
  161. self.dev = qml.device(parameteres['device'], wires=self.n_qubits)
  162. self.opt = parameteres['optimizer']
  163.  
  164. # Parameter Initialization
  165. self.weights = 0.01 * np.random.randn(self.n_layers, self.n_qubits, 3, requires_grad=True)
  166. self.bias = np.array(0.0, requires_grad=True)
  167.  
  168. # Define circuit
  169. self.circuit_ = qml.QNode(globals()[self.circuit_name], self.dev)
  170.  
  171. # Load data
  172. self.load_data()
  173.  
  174.  
  175. def circuit(self, weights, x):
  176. return self.circuit_(weights, self.embedding, self.n_layers, self.n_qubits, x)
  177.  
  178. def classifier(self, weights, bias, x):
  179. return self.circuit(weights, x) + bias
  180.  
  181. def cost(self, weights, bias, X, Y): # weights, bias, X_batch, Y_batch
  182. predictions = np.array([np.sign(self.classifier(weights, bias, x)) for x in X])
  183. loss = np.mean((predictions - Y)**2)
  184.  
  185. return loss
  186.  
  187. def train(self):
  188. for epoch in range(self.max_epochs):
  189. self.epoch = epoch
  190. # Create batch iterator
  191. dataloader = DataLoader(dataset=self.train_dataset, batch_size=self.batch_size, num_workers=os.cpu_count())
  192.  
  193. for i, pack in tqdm(enumerate(iter(dataloader)), total=len(self.train_dataset)/self.batch_size, desc=f"Training epoch {epoch+1}/{self.max_epochs} - "):
  194. # Get current Step
  195. self.global_step = epoch * (len(self.train_dataset)/self.batch_size) + i
  196. loss = self.training_step(i, pack)
  197.  
  198. # Print to terminal
  199. print("Epoch: {:5d} | Step: {:5d} | Cost: {:0.7f} ".format(
  200. epoch, i, loss
  201. ))
  202.  
  203.  
  204.  
  205. def training_step(self, i, pack):
  206. x_batch, y_batch = pack
  207.  
  208. x_batch = np.array(x_batch, requires_grad=False)
  209. y_batch = np.array(y_batch, requires_grad=False)
  210.  
  211. # Replace 0 with -1 on y due to the architecture of the circuit TODO: Maybe change loss?
  212. y_batch[y_batch == 0] = -1
  213.  
  214. # Other things I've tried
  215. print("params before\n", self.weights, "\n", self.bias)
  216. pack, loss = self.opt.step_and_cost(self.cost, self.weights, self.bias, x_batch, y_batch)
  217. self.weights, self.bias, _, _ = pack
  218. # Also tried this (again) and only get a gradient on the bias
  219. #grad = self.opt.compute_grad(self.cost, (self.weights, self.bias), {'X':x_batch, 'Y':y_batch})
  220. #self.weights, self.bias = self.opt.apply_grad(grad, (self.weights, self.bias))
  221. print("params after\n", self.weights, "\n", self.bias)
  222. return loss
  223.  
  224.  
  225. def load_data(self):
  226. # Datasets initialization / Load data
  227. print("[Info] Loading data...")
  228. self.train_dataset = BankData('train')
  229. self.val_dataset = BankData('validation')
  230.  
  231.  
  232.  
  233.  
  234. dummy_params = {
  235. 'device': 'default.qubit',
  236. 'batch_size': 10,
  237. 'max_epochs': 4,
  238. 'n_datapoints': 10000,
  239. 'patience': 20,
  240. 'check_val_every_n_epoch': 2,
  241. 'optimizer': NesterovMomentumOptimizer(100),
  242. 'n_layers': 1,
  243. 'embedding_method': 'AngleEmbedding',
  244. 'circuit_name':'circuit1',
  245. 'n_features': 4,
  246. }
  247.  
  248. machine = Trainer(dummy_params)
  249. machine.train()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement