<jupyter_start><jupyter_text>Create Slice<jupyter_code>def rolling_window(series, window_size):
    return np.array([series[i : (i + window_size)] for i in range(0, series.shape[0] - window_size + 1)])

def to_timeseries_input(series, lookback, predictions):
    inputs = rolling_window(series[:-predictions], lookback)
    outputs = rolling_window(series[lookback:], predictions)
    return inputs, outputs

def createDataByDate(datadict, features, dates):
    databyDate = defaultdict(lambda : defaultdict(dict))
    for date in dates:
        for floor in datadict.keys():
            databyDate[date][floor] = np.asarray(datadict[floor][date][features])
    return databyDate

def splitDate(dates,cutoff):
    train_date = [x for x in dates if x <= cutoff]
    test_date = sorted(list(set(dates) - set(train_date)))
    return train_date, test_date

def getInfoDataByDate(data, dates):
    for date in dates:
        print("Date : {}".format(date))
        for floor in data[date]:
            print("{} shape : {}".format(floor,data[date][floor].shape))
            
def LoaderByZone(data,zone_name,dates, lookback, lookahead, batch_size, shuffle=False):
    loaderZ = {}
    for i,date in enumerate(dates):
        haruharu = data[date][zone_name]
        trainx, trainy = to_timeseries_input(haruharu, lookback, lookahead,)
        xshape = torch.tensor(trainx, dtype=torch.float).unsqueeze(-1)
        yshape = torch.tensor(trainy, dtype=torch.float)
        tensorwrap = TensorDataset(xshape,yshape)
        loaderxy = DataLoader(tensorwrap,batch_size = batch_size, shuffle=shuffle, drop_last=True)
        loaderZ[date] = loaderxy
    return loaderZ
for data in cleanedData.keys():
    zone = cleanedData[data]
    print("{} Start: {} End: {} Count:{}".format(data,zone.index.min(),zone.index.max(), zone.shape[0]))
    print("{} Dates: {}".format(data,len(np.unique(zone["date"]))))
cutting_date = "2019-05-08"
train_date, test_date = splitDate(remain_date, cutting_date)
databyDate = createDataByDate(cleanedData, feature, remain_date)
getInfoDataByDate(databyDate, train_date)
def getRatio(ratio, lookbackinit):
    lookahead = int(ratio*lookbackinit)
    return lookahead
z1 = "Floor7Z1"
z2 = "Floor7Z2"
z4 = "Floor7Z4"
z5 = "Floor7Z5"

lookback = 13
lookahead = 1
batch_size = 32
loaderZ1train = LoaderByZone(databyDate, z1, train_date, lookback, lookahead, batch_size, shuffle=True)
loaderZ1test = LoaderByZone(databyDate, z1, test_date, lookback, lookahead, batch_size)

loaderZ2train = LoaderByZone(databyDate, z2, train_date, lookback, lookahead, batch_size, shuffle=True)
loaderZ2test = LoaderByZone(databyDate, z2, test_date, lookback, lookahead, batch_size)

loaderZ4train = LoaderByZone(databyDate, z4, train_date, lookback, lookahead, batch_size, shuffle=True)
loaderZ4test = LoaderByZone(databyDate, z4, test_date, lookback, lookahead, batch_size)

loaderZ5train = LoaderByZone(databyDate, z5, train_date, lookback, lookahead, batch_size, shuffle=True)
loaderZ5test = LoaderByZone(databyDate, z5, test_date, lookback, lookahead, batch_size)
trainloader = [loaderZ1train, loaderZ2train, loaderZ4train, loaderZ5train]
loaderZ2train["2019-03-08"]
nb_iterations = len(train_date)*len(loaderZ2train["2019-03-08"])
nb_iterations<jupyter_output><empty_output><jupyter_text>Algorithm<jupyter_code>def proj_2shape(x,s=8):
    shape = x.shape
    if torch.linalg.norm(x,ord=1)==s and torch.all(x>0):
        return x
    u,_ = torch.sort(torch.abs(x),dim=0,descending=True)
    cumsum = torch.cumsum(u, dim=0)
    arange = torch.arange(1, shape[0]+1)
    rep_arange = arange.unsqueeze(1).repeat(1,shape[1])
    rho = torch.count_nonzero((u*rep_arange > (cumsum - s)), dim=0)
    theta = (cumsum[rho-1, torch.arange(0,shape[1])] - s)/rho
    proj = (torch.abs(x)-theta).clamp(min=0)
    proj*= torch.sign(x)
    return proj

def proj_l1(x, s=8):
    shape = x.shape
    if len(shape) == 4:
        proj = torch.zeros_like(x)
        for first_dim in range(x.shape[0]):
            for second_dim in range(x.shape[1]):
                inner_tensor = x[first_dim][second_dim]
                inner_proj = proj_2shape(inner_tensor,s=s)
                proj[first_dim][second_dim] = inner_proj
                
    elif len(shape) == 3:
        proj = torch.zeros_like(x)
        for first_dim in range(x.shape[0]):
            inner_tensor = x[first_dim]
            inner_proj = proj_2shape(inner_tensor,s=s)
            proj[first_dim] = inner_proj
        
    elif len(shape) == 2:
        proj = proj_2shape(x,s=s)
        
    elif len(shape) == 1:
        u,_ = torch.sort(torch.abs(x),descending=True)
        cumsum = torch.cumsum(u,dim=0)
        arange = torch.arange(1,shape[0]+1)
        rho = torch.count_nonzero((u*arange > (cumsum - s)))
        theta = (cumsum[rho-1] - s)/rho
        proj = (torch.abs(x)-theta).clamp(min=0)
        proj*= torch.sign(x)
    return proj
# #def simpleLMO(x,radius,p=1):
#     tolerance = 1e-10
#     if p == 1:
#         v = torch.zeros_like(x)
#         maxIdx = torch.argmax(torch.abs(x))
#         v.view(-1)[maxIdx] = -radius * torch.sign(x.view(-1)[maxIdx])
#         return v
#     elif p == 2:
#         x_norm = float(torch.norm(x, p=2))
#         if x_norm > tolerance:
#             return -radius * x.div(x_norm)
#         else:
#             return torch.zeros_like(x)
#     elif p == float('inf'):
#         return torch.full_like(x, fill_value=radius).masked_fill_(x > 0, -radius)

# #def simpleProject(x,radius,p=1):
#     if p==1:
#         x_norm = torch.norm(x, p=1)
#         if x_norm > radius:
#             sorted_ = torch.sort(torch.abs(x.flatten()), descending=True).values
#             running_mean = (torch.cumsum(sorted_, 0) - radius)/torch.arange(1,sorted_.numel() + 1)                                                                                  
#             is_less_or_equal = sorted_ <= running_mean
#             idx = is_less_or_equal.numel() - is_less_or_equal.sum() - 1
#             return torch.sign(x) * torch.max(torch.abs(x) - running_mean[idx], torch.zeros_like(x))
#         else:
#             return x
#     elif p == 2:
#         x_norm = torch.norm(x, p=2)
#         return radius * x.div(x_norm) if x_norm > radius else x
#     elif p == float('inf'):
#         return torch.clamp(x, min=-radius, max=radius)
def lmo(x,radius):
    """Returns v with norm(v, self.p) <= r minimizing v*x"""
    shape = x.shape
    if len(shape) == 4:
        v = torch.zeros_like(x)
        for first_dim in range(shape[0]):
            for second_dim in range(shape[1]):
                inner_x = x[first_dim][second_dim]
                rows, cols = x[first_dim][second_dim].shape
                v[first_dim][second_dim] = torch.zeros_like(inner_x)
                maxIdx = torch.argmax(torch.abs(inner_x),0)
                for col in range(cols):
                    v[first_dim][second_dim][maxIdx[col],col] = -radius*torch.sign(inner_x[maxIdx[col],col])
    elif len(shape) == 3:
        v = torch.zeros_like(x)
        for first_dim in range(shape[0]):
            inner_x = x[first_dim]
            rows, cols = x[first_dim].shape
            v[first_dim] = torch.zeros_like(inner_x)
            maxIdx = torch.argmax(torch.abs(inner_x),0)
            for col in range(cols):
                v[first_dim][maxIdx[col],col] = -radius*torch.sign(inner_x[maxIdx[col],col])
                    
    elif len(shape)==2:
        rows, cols = x.shape
        v = torch.zeros_like(x)
        maxIdx = torch.argmax(torch.abs(x),0)
        for col in range(cols):
            v[maxIdx[col],col] = -radius*torch.sign(x[maxIdx[col],col])
                
    else : 
        v = torch.zeros_like(x)
        maxIdx = torch.argmax(torch.abs(x))
        v.view(-1)[maxIdx] = -radius * torch.sign(x.view(-1)[maxIdx])
    return v
class DMFW(optim.Optimizer):
    def __init__(self, params, eta_coef=required, eta_exp=required, L=required, matrix_line=required, reg_coef=required,radius=required):
        if eta_coef is not required and eta_coef <=0.:
            raise ValueError("Invalid eta : {}".format(eta_coef))
        if eta_exp is not required and (eta_exp == 0.5):
            raise ValueError("Invalid eta_exp : {}".format(eta_exp))
        defaults = dict(eta_coef=eta_coef, eta_exp=eta_exp,L=L, matrix_line=matrix_line,reg_coef = reg_coef,radius=radius)
        super(DMFW,self).__init__(params,defaults)

        for group in self.param_groups:
            self.eta_coef = group["eta_coef"]
            self.eta_exp = group["eta_exp"]
            self.reg_coef = group["reg_coef"]
            self.A = group["matrix_line"]
            self.L = group["L"]
            self.radius = group["radius"]
        self.num_layers = len(self.param_groups[0]['params'])
        self.dim = [k.shape for k in self.param_groups[0]['params']]
        self.G = [[torch.rand(k) for k in self.dim] for l in range(self.L)]
        
    @torch.no_grad()
    def initValue(self,closure):
        self.w_dict = defaultdict(dict)
        for group in self.param_groups:
            if closure is not None:
                with torch.enable_grad():
                    closure()
            for k,weight in enumerate(group["params"]):
                if weight.grad is None:
                    raise ValueError("Gradient is None")
                self.w_dict[k]["g"] = weight.grad.detach().clone()
                self.w_dict[k]["w"] = weight.detach().clone()
                
    def neighborsAverage(self, neighbors):
        for group in self.param_groups:
            for k,weight in enumerate(group["params"]):
                weighted_tmp = torch.zeros(self.dim[k])
                weighted_grad_tmp = torch.zeros(self.dim[k])
                for j in range(len(neighbors)):
                    weighted_tmp += self.A[j]*neighbors[j].w_dict[k]["w"]
                    weighted_grad_tmp += self.A[j]*neighbors[j].w_dict[k]["g"]
                self.w_dict[k]["y"] = weighted_tmp
                self.w_dict[k]["ds"] = weighted_grad_tmp
                

    def step(self, l, closure):
        if l == 0:
            self.init_gap = 0
        eta = min(self.eta_coef/(l+1)**self.eta_exp, 1)
        for group in self.param_groups:
            if closure is not None:
                with torch.enable_grad():
                    closure()
            self.gap = 0
            for k,weight in enumerate(group["params"]):
                a = lmo(weight.grad.data,self.radius)
                self.gap += torch.sum(torch.mul(weight.grad.data, weight.data - a))
                v = proj_l1(self.G[l][k], s=self.radius)
                #v = lmo(self.G[l][k] - 0.5 + torch.rand_like(self.G[l][k]), s= self.radius)
                if weight.grad is None:
                    raise ValueError("Grad is None")
                self.w_dict[k]["grad_old"] = weight.grad.detach().clone()
                weight.data = self.w_dict[k]['y']*(1-eta) + eta*v
                #print("weight {}".format(torch.linalg.norm(weight.data,ord=1,dim=0)))
                self.w_dict[k]["w"] = weight.detach().clone()
                
            self.init_gap += self.gap
            self.init_gap /= (l+1)
            
            
            with torch.enable_grad():
                closure()
            for k,weight in enumerate(group["params"]):
                self.G[l][k] -= 0.5*self.w_dict[k]["ds"]*self.reg_coef
                #self.G[l][k] += self.w_dict[k]["ds"]*self.reg_coef
                if weight.grad is None :
                    raise ValueError("Grad is none")
                weight.grad.add_(-self.w_dict[k]["grad_old"])
                self.w_dict[k]["g"] = weight.grad.detach().clone() + self.w_dict[k]["ds"]
                
class Trainer:
    def __init__(self, graph, loaders, model, model_param, loss,
                 num_iterations):
        self.graph = graph
        self.num_nodes = graph.number_of_nodes()
        self.model = model
        self.param = model_param
        self.A = torch.tensor(nx.adjacency_matrix(graph).toarray())
        self.dataloader = loaders
        self.num_iterations = num_iterations
        self.loss = loss
        self.obj_values = np.ndarray((self.num_iterations + 1, 4),
                                     dtype='float')

        self.optimizers = [0.] * self.num_nodes
        self.models = [0.] * self.num_nodes
        self.losses = [0.] * self.num_nodes
        #self.gaps = [0.]*self.num_nodes

    def reset(self):
        self.optimizers = [0.] * self.num_nodes
        self.models = [0.] * self.num_nodes
        self.losses = [0.] * self.num_nodes
        self.gaps = [0.] * self.num_nodes

        self.obj_values = np.ndarray((self.num_iterations + 1, 4),
                                     dtype='float')
        
    def __nodeInit(self, data, label):
        nodewrap = TensorDataset(data, label)
        nodes = DataLoader(nodewrap, batch_size=data.size(0), shuffle=False)
        return nodes

    def weight_reset(self, layer):
        if isinstance(layer, nn.BatchNorm1d) or isinstance(layer, nn.Linear) or isinstance(layer,nn.Conv1d):
            layer.reset_parameters()
            
    def initModelWeight(self, model):
        for name,param in model.named_parameters():
            if 'bias' in name:
                nn.init.constant_(param,0.)
            elif 'weight' in name:
                if not 'batch' in name:
                    nn.init.xavier_normal_(param)
                else:
                    nn.init.uniform_(param)

    def saveCheckPts(self, t, path):
        check_pts = {}
        for i in range(self.num_nodes):
            ckp_i = {
                "t": t,
                "weight": [param for param in self.models[i].parameters()],
                "optimizer_weight": self.optimizers[i].w_dict,
                "oracles": self.optimizers[i].G,
                "loss": self.losses[i]
            }  #,
            #"avg_loss": self.avg_loss[i]}
            check_pts[i] = ckp_i
        torch.save(check_pts, path + "checkpts_models" + "_" + str(t) + ".tar")
        
    def plotPrediction(self, true, pred,date,path_to_save):
        fig = plt.figure(figsize=(5,3))
        plt.suptitle("{}".format(date))
        plt.plot(true)
        plt.plot(pred)
        #plt.show()
        fig.savefig(os.path.join(path_to_save,date))
        plt.close()

    def train(self, optimizer, L, eta_coef, eta_exp, reg_coef, radius, path_figure_date):
        seed_everything()
        self.reset()
        
        z1, z2, z4, z5 = self.dataloader

        for i in range(self.num_nodes):
            self.models[i] = self.model(*self.param)
            self.optimizers[i] = optimizer(self.models[i].parameters(),
                                           eta_coef=eta_coef,
                                           eta_exp=eta_exp,
                                           L=L,
                                           matrix_line=self.A[i],
                                           reg_coef=reg_coef,
                                           radius=radius)

        self.final_gap = [0.] * self.num_nodes
        
        t = 0
        
        for date in z1.keys():
            
            for i,loader in enumerate(self.dataloader):
                truez, predz = ModelPrediction(self.models[i], date, loader,lookahead)
                path = path_figure_date+"/Model_"+str(i)+"/"
                if not os.path.exists(path):
                    os.makedirs(path)
                self.plotPrediction(truez, predz,date,path_to_save=path)
            
            for (couple1, couple2, couple4,couple5) in zip(z1[date],z2[date], z4[date], z5[date]):
                datazones = [self.__nodeInit(*couple1), 
                             self.__nodeInit(*couple2),
                             self.__nodeInit(*couple4),
                             self.__nodeInit(*couple5)]
                

                for i in range(self.num_nodes):
                    self.initModelWeight(self.models[i])
                    self.models[i].train()

                    def closure():
                        self.optimizers[i].zero_grad(set_to_none=True)
                        x, y = iter(datazones[i]).next()
                        output = self.models[i](x)
                        loss = self.loss(output,y)
                        loss.backward()

                    self.optimizers[i].initValue(closure)
                
                for l in range(L):
                    #print("--------------------------")
                    for i in range(self.num_nodes):
                        self.optimizers[i].neighborsAverage(self.optimizers)
                    for i in range(self.num_nodes):
                        
                        def closure():
                            self.optimizers[i].zero_grad(set_to_none=True)
                            x, y = iter(datazones[i]).next()
                            output = self.models[i](x)
                            loss = self.loss(output, y)
                            loss.backward()
                            
                        self.optimizers[i].step(l, closure)

                self.gaps_off = [0.] * self.num_nodes
                for i in range(self.num_nodes):
                    with torch.no_grad():
                        self.models[i].eval()
                        x, y = iter(datazones[i]).next()
                        outputs = self.models[i](x)
                        curr_loss = self.loss(outputs, y)
                    self.final_gap[i] += self.optimizers[i].init_gap
                    self.final_gap[i] /= (t + 1)
                    self.gaps_off[i] = self.optimizers[i].init_gap
                    self.losses[i] = curr_loss.detach().numpy()

                loss = np.mean(self.losses)
                gap = np.max(self.final_gap)  #.detach().numpy(
                local_gap = np.max(self.gaps_off)
                if t % 1 == 0:
                    print("t_{} : loss : {:.5f} gap : {} local_gap {}".format(
                        t, loss, gap, local_gap))
                    
                self.obj_values[t, :] = [t, loss, gap, local_gap]
                    
                t+=1
            

        return self.obj_values
class Encoder(nn.Module):
    def __init__(self, input_dim, hid_dim, n_layers=1):
        super(Encoder,self).__init__()
        self.input_dim = input_dim
        self.hid_dim = hid_dim
        self.n_layers = n_layers
        self.lstm = nn.LSTM(input_dim, hid_dim, n_layers, batch_first=False, bias=False)
        
    def forward(self, seq):
        outputs, self.hidden = self.lstm(seq.view(seq.shape[1],seq.shape[0],self.input_dim))
        return outputs, self.hidden
    
    def init_hidden(self, batch_size):
        return (torch.zeros(self.n_layers, batch_size, self.hid_dim),
                torch.zeros(self.n_layers, batch_size, self.hid_dim))
    
class Decoder(nn.Module):
    def __init__(self, input_dim, hid_dim, output_dim, n_layers=1):
        super(Decoder,self).__init__()
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.hid_dim = hid_dim
        self.n_layers = n_layers
        
        self.lstm = nn.LSTM(input_dim, hid_dim, n_layers, batch_first = False, bias=False)
        self.fc = nn.Linear(hid_dim, output_dim)
        
    def forward(self, x, encoder_hidden):
        lstm_out, self.hidden = self.lstm(x.unsqueeze(0), encoder_hidden)
        output = self.fc(lstm_out.squeeze(0))
        return output, self.hidden
    
class Seq2Seq(nn.Module):
    def __init__(self, input_dim, hid_dim, output_dim, ts_out, forcing = 1):
        super(Seq2Seq,self).__init__()
        self.output_dim = output_dim
        self.ts_out = ts_out
        self.encoder = Encoder(input_dim, hid_dim)
        self.decoder = Decoder(input_dim,hid_dim,output_dim)
        self.forcing = forcing

        
    def forward(self, source, y=None):
        batch_size = source.shape[0]
        target_len = self.ts_out
        outputs = torch.zeros(target_len, batch_size,self.output_dim)
        encoder_hidden = self.encoder.init_hidden(batch_size)
        encoder_output, encoder_hidden = self.encoder(source)
        
        decoder_input = source[:,-1,:]
        decoder_hidden = encoder_hidden
        
        for t in range(target_len):
            decoder_output, decoder_hidden = self.decoder(decoder_input, decoder_hidden)
            outputs[t] = decoder_output
            if (y is not None) and (t>1) and (torch.rand(1) < self.forcing):
                decoder_input = y[:,t].unsqueeze(1)
            else :
                decoder_input = decoder_output
        #print(outputs.shape)
        return outputs.squeeze().permute(1,0)
class LSTM(nn.Module):
    def __init__(self, input_size, output_size, time_step_in, time_step_out):
        super(LSTM, self).__init__()
        self.input_size = input_size
        self.output_size = output_size
        self.time_step_in = time_step_in
        self.time_step_out = time_step_out
        self.num_layers = 1
        
        self.encoder = nn.LSTM(self.input_size, self.output_size,
                               num_layers=self.num_layers, batch_first=True, bias=True)
        
        self.batch = nn.BatchNorm1d(self.output_size)
        self.linear2 = nn.Linear(self.num_layers*self.output_size, self.time_step_out)
        
    def forward(self,x):
        out_en, (h_en,_) = self.encoder(x)
        h_en = h_en.view(-1, self.num_layers*self.output_size)
        h_en = self.batch(h_en)
        out = nn.LeakyReLU()(h_en)
        #out = torch.sigmoid(self.linear(out))
        out = self.linear2(out)
        return out
class CNN1D(nn.Module):
    def __init__(self,output_chan, output_dim,input_dim,kernel_size):
        super(CNN1D, self).__init__()
        
        self.output_chan = output_chan
        self.output_dim = output_dim
        self.input_dim = input_dim
        
        self.conv1d = nn.Conv1d(in_channels=1, out_channels=output_chan, kernel_size=kernel_size, stride=1, 
                                padding=int(np.floor(kernel_size/2)))
        
        
        self.maxpool = nn.MaxPool1d(3)
        self.batchnorm = nn.BatchNorm1d(output_chan)
        self.fc1 = nn.Linear(output_chan*int((input_dim/3)), output_dim, bias=True)
        
    def forward(self, x):
        inputs = x.unsqueeze(1).squeeze(-1)
        #print(inputs.shape)
        out = self.conv1d(inputs)
        out = self.batchnorm(out)
        #print(out.shape)
        out = self.maxpool(out)
        #print(out.shape)
        out = nn.LeakyReLU()(out)
        
        out = out.view(-1, out.shape[1]*out.shape[2])
        
        out = self.fc1(out)
        return out
class Linear(nn.Module):
    def __init__(self, nb_units, input_dim, output_dim):
        super(Linear, self).__init__()
        
        self.nb_units = nb_units
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.nb_units2 = 16
    
        self.fc1 = nn.Linear(input_dim, nb_units)
        #self.fc2 = nn.Linear(nb_units, self.nb_units2)
        self.fc3 = nn.Linear(nb_units, output_dim)
        
        self.batch1 = nn.BatchNorm1d(nb_units)
        #self.batch2 = nn.BatchNorm1d(self.nb_units2)
        self.drop = nn.Dropout(0.5)
        
    def forward(self, x):
        inputs = x.squeeze(-1)
        out = self.fc1(inputs)
        out = self.batch1(out)
        out = nn.ReLU()(out)
        
        out = self.fc3(out)
        return out
complet_graph, complet = Graphs.completegraph(4)
cycle_graph, cycle = Graphs.cycle_graph(4)
grid_graph, grid = Graphs.gridgraph(2,2)
grid_graph_line, line = Graphs.gridgraph(4,1)
nb_iterations
loss_fn = nn.SmoothL1Loss()
num_iters_base = nb_iterations
eta_coef_DMFW = 1
eta_exp_DMFW = 0.75
rho_coef_DMFW = 4e-0
rho_exp_DMFW = 1/2
reg_coef_DMFW = 10
L_DMFW = 50 #or nb_iteration to get a better result
def ModelPrediction(model_to_test, date ,loader, lookahead):
    prediction = []
    true = []
    for val, valpred in loader[date]:
        model_to_test.eval()
        pred = model_to_test(val)
        #print(pred.shape)
        prediction.append(pred.detach().numpy())
        true.append(valpred.detach().numpy())
    pred_array = np.asarray(prediction)
    true_array = np.asarray(true)
    #print(pred_array.shape)
    pred_shape = pred_array.shape
    #print(pred_shape)
    flattenTrue = true_array.reshape(pred_shape[0]*pred_shape[1], lookahead)[::lookahead].flatten()
    flattenPred = pred_array.reshape(pred_shape[0]*pred_shape[1], lookahead)[::lookahead].flatten()
    return flattenTrue, flattenPred
trainXMFW = Trainer(cycle_graph,trainloader,CNN1D, (8,lookahead,lookback,5), loss_fn,num_iters_base)
values_dmfw = trainXMFW.train(DMFW, L_DMFW, eta_coef_DMFW, eta_exp_DMFW, reg_coef_DMFW,1,
                            path_figure_date="../OnlineModels/CNN1D/")
plt.figure(figsize=(10,5))
plt.suptitle("{}".format(cycle))
plt.plot(values_dmfw[:,0][:-1],values_dmfw[:,2][:-1], label='DMFW', marker='^', markersize=4,
         markevery=[i for i in range(len(values_dmfw[:,0][1:])) if i%10==0])
plt.axhline(y=0, color='grey', linestyle='--')
plt.legend(loc='upper right')
#plt.ylim((1e-4, 1e0))
plt.yscale("log")
plt.xlabel("#Iterations",fontsize=15)
plt.ylabel("Gap",fontsize=15)
np.mean(values_dmfw[:,1][:-1])
onlineloss = np.cumsum(values_dmfw[:,1][:-1])
arangement = np.arange(1,len(onlineloss)+1)
onlineloss = onlineloss/arangement
plt.figure(figsize=(10,5))
plt.suptitle("{}".format(cycle))
plt.plot(values_dmfw[:,0][:-1],values_dmfw[:,1][:-1], label='Step Loss', marker='^', markersize=4,
         markevery=[i for i in range(len(values_dmfw[:,0][1:])) if i%10==0])
plt.plot(values_dmfw[:,0][:-1],onlineloss, label='Online Loss', marker='^', markersize=4,
         markevery=[i for i in range(len(values_dmfw[:,0][1:])) if i%10==0])
plt.axhline(y=0, color='grey', linestyle='--')
plt.legend(loc='upper right')
#plt.ylim((1e-3, 1e2))
plt.yscale("log")
plt.xlabel("#Iterations",fontsize=15)
plt.ylabel("Loss",fontsize=15)<jupyter_output><empty_output><jupyter_text>Prediction<jupyter_code>#torch.save(trainXMFW.models[3].state_dict(),"./OnlineModel/CNN1D/FINAL43_BestFinal/model3.pt")
model_trained = trainXMFW.models[0]
true, pred = ModelPrediction(model_trained,"2019-05-16", loaderZ1test, lookahead)
plt.plot(true) 
plt.plot(pred)
def PredictionSlidingWindow(model, dates, date_begin, date_end, loader, lookahead, scaler, zone_name, ft_idx):
    predictTrue = []
    predictPred = []
    valuePD = pd.DataFrame()
    idx_begin = dates.index(date_begin)
    idx_end = dates.index(date_end)
    for date in dates[idx_begin:idx_end]:
        true, pred = ModelPrediction(model, date, loader, lookahead)
        maxi = scalers[zone_name].data_max_[ft_idx]
        mini = scalers[zone_name].data_min_[ft_idx]
        true = true.reshape(-1,1)*(maxi-mini) + mini
        pred = pred.reshape(-1,1)*(maxi-mini) + mini
        array = np.concatenate([true, pred],axis=1)
        result = pd.DataFrame({"Truth": true.squeeze(),
                              "Prediction" : pred.squeeze()})
                              #"Date": pd.date_range(start=date,periods=true.shape[0], freq="5min")})
        valuePD = pd.concat((valuePD, result)).reset_index(drop=True)
    return valuePD
floor_dict["Floor7Z1"].columns
ft_idx = 3
indexroom = 3
mymodel = trainXMFW.models[indexroom]
testloader = [loaderZ1test, loaderZ2test, loaderZ4test, loaderZ5test]
may = [date for date in test_date if '2019-05' in date]
myfloor = ["Floor7Z1","Floor7Z2","Floor7Z4","Floor7Z5"]
resultpd = PredictionSlidingWindow(mymodel,test_date,may[0], may[-1],testloader[indexroom], lookahead, scalers,
                                 myfloor[indexroom], ft_idx)
resultpd[["Truth","Prediction"]].plot(figsize=(15,5),title="Model_"+str(indexroom))<jupyter_output><empty_output><jupyter_text>floor_dict["Floor7Z1"].columns<jupyter_code>scalers<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13327607186314508, 'fraction_numerical': 0.013957483358385226, 'mean_word_length': 2.2367658982972314, 'pattern_counts': {'":': 8, '<': 22, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 19, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '569460', 'license': 'Apache-2.0', 'n_tokens_mistral': 9630, 'n_tokens_neox': 9292, 'n_words': 1600, 'path': 'DMFW/prototype/Prototype.ipynb', 'repo_name': 'AnganMitra/decentralearn', 'size': '27942'}