半監督學習實戰 標註資料和偽標籤資料混合訓練

2021-10-09 03:55:40 字數 3798 閱讀 1280

當標註資料較少,而未標註的資料很多,並且標註成本很高時,可以考慮半監督學習訓練。首先,採用偽標籤技術把沒有標註的的打上偽標籤,然後用標註資料和偽標籤資料混合訓練模型。值得注意的是,要保證每個mini-batch中含有真實標籤和偽標籤,本文帶你用**實現。

首先是生成偽標籤,對於分類和目標檢測而言都比較簡單,這裡不贅述。

下面實現的是:如何在每個mini-batch中保證同時存在真實標籤和偽標籤,並且控制他們的比例,以分類為例進行說明。

第一步,需要修稿資料引導程式,如下:

import os

import torch

from torch.utils import data

import numpy as np

from torchvision import transforms as t

import torchvision

import cv2

import sys

import random

from pil import image

from data_augment import gussian_blur, random_crop

class dataset(data.dataset):

def __init__(self, img_list, img_list1, phase='train'):

self.phase = phase

# 標註的標籤

with open(img_list, 'r') as fd:

imgs = fd.readlines()

imgs = [img.rstrip("\n") for img in imgs]

random.shuffle(imgs)

self.imgs = imgs

# 偽標籤(模擬的)

with open(img_list1, 'r') as fd:

fake_imgs = fd.readlines()

fake_imgs = [img.rstrip("\n") for img in fake_imgs]

random.shuffle(fake_imgs)

self.fake_imgs = fake_imgs

normalize = t.normalize(mean=[0.5, 0.5, 0.5],

std=[0.5, 0.5, 0.5])

if self.phase == 'train':

self.transforms = t.compose([

t.randomhorizontalflip(),

t.totensor(),

normalize

])else:

self.transforms = t.compose([

t.totensor(),

normalize

])def __getitem__(self, index):

sample = self.imgs[index]

splits = sample.split()

img_path = splits[0]

# data augment

data = cv2.imread(img_path)

data = random_crop(data, 0.2)

data = gussian_blur(data, 0.2)

data = cv2.cvtcolor(data, cv2.color_bgr2rgb)

data = image.fromarray(data)

data = data.resize((224, 224))

data = self.transforms(data)

label = np.int32(splits[1])

# 取偽資料和偽標籤

fake_datas, fake_labels = ,

for i in range(2):

fake_sample = self.fake_imgs[(index+i)%len(self.fake_imgs)]

fake_splits = fake_sample.split()

fake_img_path = fake_splits[0]

fake_data = cv2.imread(fake_img_path)

fake_data = cv2.cvtcolor(fake_data, cv2.color_bgr2rgb)

fake_data = image.fromarray(fake_data)

fake_data = fake_data.resize((224, 224))

fake_data = self.transforms(fake_data)

fake_label = np.int32(fake_splits[1])

return data.float(), label, fake_datas, fake_labels

def __len__(self):

return len(self.imgs)

第二步,在訓練主程式中的實現,如下:

def train(epoch, net, trainloader, optimizer, criterion):

print('\nepoch: %d' % epoch)

net.train()

train_loss = 0

correct = 0

total = 0

batch_id = 0

for (inputs, targets, fake_inputs, fake_targets) in tqdm(trainloader):

# 將真標籤和偽標籤融合

inputs = torch.cat(fake_inputs, dim=0)

targets = torch.cat(fake_targets, dim=0)

inputs, targets = inputs.to(device), targets.to(device)

optimizer.zero_grad()

outputs = net(inputs)

loss = criterion(outputs, targets.long())

loss.backward()

optimizer.step()

train_loss += loss.item()

_, predicted = outputs.max(1)

total += targets.size(0)

correct += predicted.eq(targets.long()).sum().item()

iters = epoch * len(trainloader) + batch_id

if iters % 10 == 0:

acc = predicted.eq(targets.long()).sum().item()*1.0/targets.shape[0]

los = loss*1.0/targets.shape[0]

#tensor_board.visual_loss("train_loss", los, iters)

#tensor_board.visual_acc("train_acc", acc, iters)

batch_id += 1

就是這麼簡單,理論部分請參考我的另一篇部落格

相關:

監督學習,無監督學習和半監督學習

監督學習 supervised learning 無監督學習 unsupervised learning 半監督學習 semi supervised learning 2 概念 監督學習 用一部分已知分類 有標記的樣本來訓練機器後,讓它用學到的特徵,對沒有還分類 無標記的樣本進行分類 貼標籤。一句話...

機器學習(二) 有監督學習 無監督學習和半監督學習

1 特徵 feature 資料的特徵。舉例 書的內容 2 標籤 label 資料的標籤。舉例 書屬於的類別,例如 計算機 圖形學 英文書 教材 等。舉例 把很多書交給乙個學生,培養他給書本分類的能力。4 分類 classification 定性輸出稱為分類,或者說是離散變數 舉例 明天是陰 晴還是雨...

有監督學習 無監督學習和半監督學習的區別

1 特徵 feature 資料的特徵。舉例 書的內容 2 標籤 label 資料的標籤。舉例 書屬於的類別,例如 計算機 圖形學 英文書 教材 等。舉例 把很多書交給乙個學生,培養他給書本分類的能力。4 分類 classification 定性輸出稱為分類,或者說是離散變數 舉例 明天是陰 晴還是雨...