图像分类__半监督

da201ff6879d588a207a552c160fdb08_720
不仅要验证集上的准确率达标,还要求无标签数据集上的概率大于threshold才能打上标签,加进半监督集
并且semiloader的读取也不用每一轮都尝试,这样太浪费时间了,可以每五轮或3轮尝试
semidataset的输入就是 无标签数据集,模型,置信度

no_label_loader = DataLoader(no_label_set, batch_size=16, shuffle=False) 他不能打乱,否则在semi_dataset中无法将索引对应的label正确加入进半监督训练集

class semi_dataset():
    def __init__(self,no_label_loader , model, device, thres=0.99):
        x, y = self.get_label(no_label_loader, model, device, thres)
        if x == []:
            flag = False #说明没一个无标签数据的可信度达标
        else:
            self.flag = True
            self.X = np.array(x)    #数据集之后Dataloader会完成对array矩阵处理成tensor
            self.Y = torch.LongTensor(y)    #而Y是tensor是因为模型输出也默认是tenosr,这里标签也设为tenosr,方便后面loss处理
            self.transform = train_transform
    def get_label(self, no_label_loader, model, device,thres):
        model = model.to(device)
        soft = nn.Softmax()
        pred_prob = []
        labels = []
        x = []
        y = []
        with torch.no_grad():
            for bat_x, _ in no_label_loader:
                bat_x = bat_x.to(device)
                pred = model(bat_x)
                pred_soft = soft(pred)
                pred_max, pred_value =  pred_soft.max(1) #代表是横着的维度,因为每个pred是tensor(batshcsize,11)
                                                         #分别承载概率最大值,和最大概率的索引
                pred_prob.extend(pred_max.cpu().numpy().tolist())
                labels.extend(pred_value.cpu().numpy().tolist()) #numy之能在cpu上,所以先到cpu上在转为numpy,在转成list,对list只能用extend,对值可以用appen

        for index, prob in enumerate(pred_prob):
            if prob> thres:
                x.append(no_label_loader.dataset[index][1])       #index调用到dataset的getitem函数的第二个返回结果即没有扩增过的原始数据
                y.append(labels[index])
        return x,y

    def __getitem__(self,item):
        return self.transform(self.x[item]), self.y[item]

    def __len__(self):
        return len(self.x)

对于semi_dataloader不应该直接定义,因为它不一定存在,其实它必须在模型训练过程中存在,比如模型的acc已经训练到了一个程度

def get_semi_loader(no_label_loader,model,device,thres):
    semi_set =  semi_dataset(no_label_loader,model,device,thres)
    if semi_set.flag == False:
        return None
    else:
        semi_loader = DataLoader(semi_set, batch_size=16, shuffle=False)  #这里对于打不打乱随便
        return semi_loader
posted @ 2026-02-24 23:03  peter_shen  阅读(8)  评论(0)    收藏  举报