Closed mohapatra-amrit closed 3 months ago
Hi @mohapatra-amrit
It seems that you're trying to create an output for a sentence the model has never seen before. Can you re-run your entire notebook making sure that all the sentences have been passed to the Model.from_diagrams
method and let me know what happens after.
This will be closed due to inactivity.
Hi guys. I have executed below codes properly, print('Final test accuracy: {}'.format(accuracy(test_pair_circuits, test_labels))) is not working. KeyError Traceback (most recent call last) in <cell line: 1>() ----> 1 print('Final test accuracy: {}'.format(accuracy(test_pair_circuits, test_labels)))
3 frames /usr/local/lib/python3.10/dist-packages/lambeq/training/pennylane_model.py in get_diagram_output(self, diagrams) 178 circuit_evals = [] 179 for d in diagrams: --> 180 p_circ = self.circuit_map[d] 181 p_circ.initialise_concrete_params(self.symbol_weight_map) 182 circuit_evals.append(p_circ.eval())
KeyError: quantum.circuit.Circuit(inside=(rigid.Layer(quantum.circuit.Ty(), quantum.gates.Ket('Ket(0)', quantum.circuit.Ty(), quantum.circuit.Ty(quantum.circuit.Qudit(2))), quantum.circuit.Ty()), rigid.Layer(quantum.circuit.Ty(), quantum.gates.Rx(mann_0), quantum.circuit.Ty()), rigid.Layer(quantum.circuit.Ty(), quantum.gates.Rz(man__n_1), quantum.circuit.Ty()), rigid.Layer(quantum.circuit.Ty(), quantum.gates.Rx(mann_2), quantum.circuit.Ty()), rigid.Layer(quantum.circuit.Ty(quantum.circuit.Qudit(2)), quantum.gates.Ket('Ket(0, 0, 0)', quantum.circuit.Ty(), quantum.circuit.Ty(quantum.circuit.Qudit(2), quantum.circuit.Qudit(2), quantum.circuit.Qudit(2))), quantum.circuit.Ty()), rigid.Layer(quantum.circuit.Ty(quantum.circuit.Qudit(2)), quantum.gates.QuantumGate('H', quantum.circuit.Ty(quantum.circuit.Qudit(2)), quantum.circuit.Ty(quantum.circuit.Qudit(2)), data=[(0.7071067811865476+0j), (0.7071067811865476+0j), (0.7071067811865476+0j), (-0.7071067811865476+0j)]), quantum.circuit.Ty(quantum.circuit.Qudit(2), quantum.circuit.Qudit(2))), rigid.Layer(quantum.circuit.Ty(quantum.circuit.Qudit(2), quantum.circuit.Qudit(2)), quantum.gates.QuantumGate('H', quantum.circuit.Ty(quantum.circuit.Qudit(2)), quantum.circuit.Ty(quantum.circuit.Qudit(2)), data=[(0.7071067811865476+0j), (0.7071067811865476+0j), (0.7071067811865476+0j), (-0.7071067811865476+0j)]), quantum.circuit.Ty(quantum.circuit.Qudit(2))), rigid.Layer(quantum.circuit.Ty(quantum.circuit.Qudit(2), quantum.circuit....
Inputting data
def read_data(filename): labels, sentences = [], [] with open(filename) as f: for line in f: line = line.split(',') labels.append(int(line[2])) sentences.append((line[0], line[1])) return labels, sentences
train_labels, train_data = read_data('mc_pair_train_data.csv') dev_labels, dev_data = read_data('mc_pair_dev_data.csv') test_labels, test_data = read_data('mc_pair_test_data.csv')
result = list(zip(train_data[:10], train_labels[:10])) for item in result: print(item)
Creating and parameterizing diagrams
train_data_l, train_data_r = zip(train_data) train_data_unpaired = list(train_data_l) + list(train_data_r) dev_data_l, dev_data_r = zip(dev_data) dev_data_unpaired = list(dev_data_l) + list(dev_data_r) test_data_l, test_data_r = zip(*test_data) test_data_unpaired = list(test_data_l) + list(test_data_r) from lambeq import BobcatParser
reader = BobcatParser(verbose='text')
raw_train_diagrams = reader.sentences2diagrams(train_data_unpaired) raw_dev_diagrams = reader.sentences2diagrams(dev_data_unpaired) raw_test_diagrams = reader.sentences2diagrams(test_data_unpaired)
Simplifying diagrams
from lambeq import remove_cups
train_diagrams = [remove_cups(diagram) for diagram in raw_train_diagrams] dev_diagrams = [remove_cups(diagram) for diagram in raw_dev_diagrams] test_diagrams = [remove_cups(diagram) for diagram in raw_test_diagrams]
We can visualise these diagrams using discopy.monoidal.Diagram.draw.
train_diagrams[1].draw()
Creating circuits
from lambeq import AtomicType, IQPAnsatz
ansatz = IQPAnsatz({AtomicType.NOUN: 1, AtomicType.SENTENCE: 1}, n_layers=1, n_single_qubit_params=3)
train_circuits = [ansatz(diagram) for diagram in train_diagrams] dev_circuits = [ansatz(diagram) for diagram in dev_diagrams] test_circuits = [ansatz(diagram) for diagram in test_diagrams]
train_circuits[0].draw(figsize=(6, 8))
Hybrid QNLP model
BATCH_SIZE = 50 EPOCHS = 100 SEED = 2
from torch import nn from lambeq import PennyLaneModel
inherit from PennyLaneModel to use the PennyLane circuit evaluation
class XORSentenceModel(PennyLaneModel): def init(self, kwargs): PennyLaneModel.init(self, kwargs)
Creating paired dataset
def make_pair_data(diagrams): pair_diags = list(zip(diagrams[:len(diagrams)//2], diagrams[len(diagrams)//2:])) return pair_diags
train_pair_circuits = make_pair_data(train_circuits) dev_pair_circuits = make_pair_data(dev_circuits) test_pair_circuits = make_pair_data(test_circuits)
Initializing the model
from lambeq import Dataset
all_pair_circuits = (train_pair_circuits + dev_pair_circuits + test_pair_circuits) a, b = zip(*all_pair_circuits)
initialise our model by passing in the diagrams, so that we have trainable parameters for each token
model = XORSentenceModel.from_diagrams(a + b, probabilities=True, normalize=True)
all_diagrams = a + b # where a and b are from train, dev, and test pair circuits model = XORSentenceModel.from_diagrams(all_diagrams, probabilities=True, normalize=True)
model.initialise_weights() model = model.double()
initialise datasets and optimizers as in PyTorch
train_pair_dataset = Dataset(train_pair_circuits, train_labels, batch_size=BATCH_SIZE)
optimizer = torch.optim.Adam(model.parameters(), lr=0.1)
Training and accuracies
def accuracy(circs, labels): predicted = model(circs) return (torch.round(torch.flatten(predicted)) == torch.DoubleTensor(labels)).sum().item()/len(circs)
best = {'acc': 0, 'epoch': 0}
for i in range(EPOCHS): epoch_loss = 0 for circuits, labels in train_pair_dataset: optimizer.zero_grad() predicted = model(circuits)
use BCELoss as our outputs are probabilities, and labels are binary
load the best performing iteration of the model on the dev set
if best['acc'] > accuracy(dev_pair_circuits, dev_labels): model.load('xor_model.lt') model = model.double() print('Final test accuracy: {}'.format(accuracy(test_pair_circuits, test_labels)))
Analysing the internal representations of the model
xor_labels = [[1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]
the first two entries correspond to the same label for both sentences,
the last two to different labels
xor_tensors = torch.tensor(xor_labels).double()
model.xor_net(xor_tensors).detach().numpy()
cooking sentence
print(test_data[0][0],test_data[0][1])
p_circ = test_pair_circuits[0][0].to_pennylane(probabilities=True) symbol_weight_map = dict(zip(model.symbols, model.weights)) p_circ.initialise_concrete_params(symbol_weight_map) unnorm = p_circ.eval().detach().numpy()
print(unnorm / np.sum(unnorm)) res = unnorm / np.sum(unnorm) if(res[0]>res[1]): print("Both Sentences are of different topic") else: print("Both Sentences are of same topic")