图像分类__半监督

不仅要验证集上的准确率达标,还要求无标签数据集上的概率大于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

浙公网安备 33010602011771号