import numpy as np import torch from torch.utils.data import DataLoader from sklearn.model_selection import train_test_split from torch.utils.data.dataset import IterableDataset from collections import deque from numpy.random import default_rng DATA = np.load( # "/home/seb/Perso/git/sudoku/sudoku_clean/data/sudoku_reshaped_million.npz" "sudoku_reshaped_3_million.npz" ) rng = np.random.default_rng() def get_datasets( add_proba_fill=False, train_size=1280 // 2, test_size=1280 // 2, max_holes=None ): quizzes = DATA["quizzes"][: train_size + test_size] solutions = DATA["solutions"][: train_size + test_size] X = quizzes if max_holes: while True: x_holes = X[:, 1].sum(-1) == 0 x_nb_holes = x_holes.sum((1, 2)) mask_x_max_holes = x_nb_holes > max_holes if not any(mask_x_max_holes): break for idx_x in np.nonzero(mask_x_max_holes)[0]: sub_x_holes = x_holes[idx_x] idx_fill = rng.choice(np.transpose(np.nonzero(sub_x_holes))) X[idx_x, :, idx_fill[0], idx_fill[1], :] = solutions[ idx_x, :, idx_fill[0], idx_fill[1], : ] X = X.reshape(X.shape[0], 2, 9 * 9 * 9) solutions = solutions.reshape(solutions.shape[0], 2, 9 * 9 * 9) X_train, X_test, solutions_train, solutions_test = train_test_split( X, solutions, test_size=test_size, random_state=42 ) if add_proba_fill: X_train_bis = X_train.copy() mask = solutions_train == 1 X_train_bis[mask] = np.random.randint(0, 2, size=mask.sum()) X_train = np.concatenate([X_train, X_train_bis]) solutions_train = np.concatenate([solutions_train, solutions_train]) train = torch.utils.data.TensorDataset( torch.Tensor(X_train), torch.Tensor(solutions_train) ) test = torch.utils.data.TensorDataset( torch.Tensor(X_test), torch.Tensor(solutions_test) ) return train, test train_dataset, test_dataset = get_datasets() def data_loader(batch_size=32, add_proba_fill=False): train, test = get_datasets(add_proba_fill=add_proba_fill) train_loader = torch.utils.data.DataLoader(train, batch_size=batch_size) test_loader = torch.utils.data.DataLoader(test, batch_size=batch_size) return train_loader, test_loader class DataIterBuffer(IterableDataset): def __init__(self, raw_dataset=[], buffer_optim=50, prop_new=0.1, seed=1): self.raw_dataset = raw_dataset # self.raw_dataset = iter(raw_dataset) self.buffer = deque() self.buffer_optim = buffer_optim self.prop_new = prop_new self.rng = default_rng(seed=seed) self.idx_dataset = 0 def __iter__(self): # while True: # if (np.random.random() < self.prop_new) and ( # len(self.buffer) <= self.buffer_optim # ): # try: # yield next(self.raw_dataset) # except StopIteration: # if len(self.buffer) != 0: # yield self.buffer.popleft() # else: # break # else: # if len(self.buffer) != 0: # yield self.buffer.popleft() # else: # try: # yield next(self.raw_dataset) # except StopIteration: # break while True: if (np.random.random() < self.prop_new) and ( len(self.buffer) <= self.buffer_optim ): if self.idx_dataset >= len(self.raw_dataset): if len(self.buffer) != 0: yield self.buffer.popleft() else: break else: yield self.raw_dataset[self.idx_dataset] self.idx_dataset += 1 else: if len(self.buffer) != 0: yield self.buffer.popleft() else: if self.idx_dataset >= len(self.raw_dataset): break else: yield self.raw_dataset[self.idx_dataset] self.idx_dataset += 1 def append(self, X, Y) -> None: """Add experience to the buffer. Args: experience: tuple (state, action, reward, done, new_state) """ X[Y == 0] = 0 mask = ~(X == Y).view(-1, 2 * 729).all(dim=1) for x, y in zip(X[mask], Y[mask]): self.buffer.append((x, y)) def __len__(self): return len(self.buffer) + len(self.raw_dataset) # class DataIterDeepBuffer(IterableDataset): # def __init__(self, raw_dataset=[], buffer_target_size=32, prop_new=0.1, seed=1, prof=6): # self.raw_dataset = iter(raw_dataset) # # self.buffer = deque() # self.buffer_target_size = buffer_target_size # self.prop_new = prop_new # self.rng = default_rng(seed=seed) # self.prof=prof # self.buffers=[deque() for _ in range(prof)] # def __iter__(self): # while True: # buffer_sizes = np.array([len(buffer) for buffer in self.buffers]) # if any(buffer_sizes>=self.buffer_target_size): # # # if (np.random.random() < self.prop_new) and ( # len(self.buffer) <= self.buffer_optim # ): # try: # yield next(self.raw_dataset) # except StopIteration: # if len(self.buffer) != 0: # yield self.buffer.popleft() # else: # break # else: # if len(self.buffer) != 0: # yield self.buffer.popleft() # else: # try: # yield next(self.raw_dataset) # except StopIteration: # break # def append(self, X, Y) -> None: # """Add experience to the buffer. # Args: # experience: tuple (state, action, reward, done, new_state) # """ # X[Y == 0] = 0 # mask = ~(X == Y).view(-1, 2 * 729).all(dim=1) # for x, y in zip(X[mask], Y[mask]): # self.buffer.append((x, y)) # def __len__(self): # return len(self.buffer) + len(self.raw_dataset)