import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import qlstm_pennylane
import pandas as pd
import time
from importlib import reload
reload(qlstm_pennylane)
from qlstm_pennylane import QLSTM
#import of data
df = pd.read_csv('Data_csv.csv',sep=';',parse_dates=True)
df.head()
df.columns
for i in range(df.shape[0]):
if df['satbility'][i]==0:
df['satbility'][i]='stable'
else :
df['satbility'][i]='instable'
df.head()
tag_to_ix = {"stable": 0, "instable": 1} # Assign each tag with a unique index
ix_to_tag = {i:k for k,i in tag_to_ix.items()}
print(ix_to_tag)
def prepare_sequence(seq, to_ix):
idxs = [to_ix[w] for w in seq]
return torch.tensor(idxs, dtype=torch.long)# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset['W0'][i:(i+look_back)]
b=dataset['satbility'][i:(i+look_back)]
dataX.append(a)
dataY.append(b)
return dataX, dataY
X,Y = create_dataset(df, look_back=1)
#training_data1=list(zip(X,Y))
# Function to create a list of tuples
def create_list_of_tuples(lst1, lst2):
result = [] # Empty list to store the tuples
for i in range(len(lst1)):
# Create a tuple from corresponding elements
tuple_element = (lst1[i], lst2[i])
result.append(tuple_element) # Append the tuple to the list
return result
training_data=create_list_of_tuples(X,Y)
print(training_data1[0])
print(type(training_data1))
word_to_ix = {}
#print(training_data)
# For each words-list (sentence) and tags-list in each tuple of training_data
for sent, tags in training_data:
for word in sent:
if word not in word_to_ix: # word has not been assigned an index yet
word_to_ix[word] = len(word_to_ix) # Assign each word with a unique index
print(f"Vocabulary: {word_to_ix}")
print(f"Entities: {ix_to_tag}")
class LSTMTagger(nn.Module):
def __init__(self, embedding_dim, hidden_dim, vocab_size, tagset_size, n_qubits=0):
super(LSTMTagger, self).__init__()
self.hidden_dim = hidden_dim
self.word_embeddings = nn.Embedding(vocab_size, embedding_dim)
# The LSTM takes word embeddings as inputs, and outputs hidden states
# with dimensionality hidden_dim.
if n_qubits > 0:
print("Tagger will use Quantum LSTM")
self.lstm = QLSTM(embedding_dim, hidden_dim, n_qubits=n_qubits)
else:
print("Tagger will use Classical LSTM")
self.lstm = nn.LSTM(embedding_dim, hidden_dim)
# The linear layer that maps from hidden state space to tag space
self.hidden2tag = nn.Linear(hidden_dim, tagset_size)
def forward(self, sentence):
embeds = self.word_embeddings(sentence)
lstm_out, _ = self.lstm(embeds.view(len(sentence), 1, -1))
tag_logits = self.hidden2tag(lstm_out.view(len(sentence), -1))
tag_scores = F.log_softmax(tag_logits, dim=1)
return tag_scores
embedding_dim = 8
hidden_dim = 6
n_epochs = 5model_classical = LSTMTagger(embedding_dim,
hidden_dim,
vocab_size=len(word_to_ix),
tagset_size=len(tag_to_ix),
n_qubits=0)
def train(model, n_epochs):
loss_function = nn.NLLLoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)
history = {
'loss': [],
'acc': []
}
for epoch in range(n_epochs):
losses = []
preds = []
targets = []
for sentence, tags in training_data:
# Step 1. Remember that Pytorch accumulates gradients.
# We need to clear them out before each instance
model.zero_grad()
# Step 2. Get our inputs ready for the network, that is, turn them into
# Tensors of word indices.
sentence_in = prepare_sequence(sentence, word_to_ix)
labels = prepare_sequence(tags, tag_to_ix)
# Step 3. Run our forward pass.
tag_scores = model(sentence_in)
# Step 4. Compute the loss, gradients, and update the parameters by
# calling optimizer.step()
loss = loss_function(tag_scores, labels)
loss.backward()
optimizer.step()
losses.append(float(loss))
probs = torch.softmax(tag_scores, dim=-1)
preds.append(probs.argmax(dim=-1))
targets.append(labels)
avg_loss = np.mean(losses)
history['loss'].append(avg_loss)
preds = torch.cat(preds)
targets = torch.cat(targets)
corrects = (preds == targets)
accuracy = corrects.sum().float() / float(targets.size(0) )
history['acc'].append(accuracy)
print(f"Epoch {epoch+1} / {n_epochs}: Loss = {avg_loss:.3f} Acc = {accuracy:.2f}")
return history
start = time.time()
history_classical = train(model_classical, n_epochs)
end = time.time()
print(end - start)
def print_result(model):
with torch.no_grad():
input_sentence = training_data[0][0]
labels = training_data[0][1]
inputs = prepare_sequence(input_sentence, word_to_ix)
tag_scores = model(inputs)
tag_ids = torch.argmax(tag_scores, dim=1).numpy()
tag_labels = [ix_to_tag[k] for k in tag_ids]
print(f"Sentence: {input_sentence}")
print(f"Labels: {labels}")
print(f"Predicted: {tag_labels}")
print_result(model_classical)
n_qubits = 3
model_quantum = LSTMTagger(embedding_dim,
hidden_dim,
vocab_size=len(word_to_ix),
tagset_size=len(tag_to_ix),
n_qubits=n_qubits)
start = time.time()
history_quantum = train(model_quantum, n_epochs)
end = time.time()
print(end - start)
i use last version of pennlane