//  [python]
def train(
        self,
        images,
        captions,
        lengths,
        hard_negative=True,
        labels=None,
        soft_margin=None,
        mode="train",
        sim_type='euc',
        ids='non',
    ):
        """One epoch training.
        """
        self.Eiters += 1

        # compute the embeddings
        img_embs, cap_embs, cap_lens = self.forward_emb(images, captions, lengths)
        sims = self.forward_sim(img_embs, cap_embs, cap_lens)
        

        # measure accuracy and record loss
        self.optimizer.zero_grad()
        loss = self.criterion(
            sims,
            hard_negative=hard_negative,
            labels=labels,
            soft_margin=soft_margin,
            mode=mode,
            noise_tem = self.noise_tem
        )

        # return per-sample loss
        if mode == "eval_loss":
            return loss
        if mode =="y_score":
            img_embs,cap_embs = self.glo_emb(images, captions, lengths)
            loss = loss.reshape(-1, 1)
            gmm_A = GaussianMixture(n_components=2, max_iter=100, tol=1e-2, reg_covar=5e-4)
            gmm_A.fit(loss.cpu().numpy())
            #print(y_loss)
            #data = loss.cpu().numpy()
            prob_A = gmm_A.predict_proba(loss.cpu().numpy())
            #class_pre = gmm_A.predict(loss.cpu().numpy())
            prob_A = prob_A[:, gmm_A.means_.argmin()]
            class_c = prob_A>0.8
            class_n = 1-class_c
            if class_c.sum()==img_embs.size()[0]:
                y_value = torch.ones(img_embs.size()[0]).cuda()
                return y_value
            if class_n.sum()==img_embs.size()[0]:
                y_value = torch.zeros(img_embs.size()[0]).cuda()
                return y_value
            clean_index = class_c.nonzero()[0]

            noise_index = class_n.nonzero()[0]
            image_c = img_embs.index_select(0,torch.from_numpy(clean_index).cuda())
            image_n = img_embs.index_select(0,torch.from_numpy(noise_index).cuda())

            text_c = cap_embs.index_select(0,torch.from_numpy(clean_index).cuda())
            text_n = cap_embs.index_select(0,torch.from_numpy(noise_index).cuda())
            if sim_type=='euc':
                img_e_dis = EuclideanDistances(image_c,image_n)
                text_e_dis = EuclideanDistances(text_c,text_n)
                top_img = img_e_dis.topk(k=1, dim=1, largest=False, sorted=True)
                top_text = text_e_dis.topk(k=1, dim=1, largest=False, sorted=True)
                img2text = torch.gather(text_e_dis,1,top_img[1]).float()
                text2img = torch.gather(img_e_dis,1,top_text[1]).float()
                y_half_img = torch.where(top_img[0]/img2text<1,top_img[0]/img2text,img2text/top_img[0])
                y_half_text = torch.where(top_text[0]/text2img<1,top_text[0]/text2img,text2img/top_text[0])
                dis_f_n = (y_half_img+y_half_text)/2
            else:
                sim_img = SIM_PAIR(image_c,image_n)
                sim_text = SIM_PAIR(text_c,text_n)

                img2text = SIM_SELE(sim_img,sim_text)
                text2img = SIM_SELE(sim_text,sim_img)

                dis_f_n = (img2text+text2img)/2
                #dis_f_n =1- (dis_fin - dis_fin.min()) / (dis_fin.max() - dis_fin.min())
                
            y_value = torch.zeros(img_embs.size()[0]).cuda()
                    
            y_value[clean_index]=1
            y_value.scatter_(0, torch.from_numpy(noise_index).cuda(), dis_f_n.clamp(0,1).squeeze(1))
            
            return y_value
        # compute gradient and do SGD step
        loss.backward()
        if self.grad_clip > 0:
            clip_grad_norm_(self.params, self.grad_clip)
        self.optimizer.step()

        return loss.item()