Learning From Synthetic Data for Crowd Counting(CVPR)源碼分析——utils.py

本文源代碼github鏈接

utils.py

from torch import nn

import torch.nn.functional as F

import numpy as np

from PIL import Image

import os

import shutil

from config import cfg

import pdb

import math


#初始化權重,models可以是包含多個在內部具有nn.Conv2d的實例的list,也可以是一個實例
#遞歸對models內部的model進行權重的初始化
def weights_normal_init(*models):

    for model in models:

        dev=0.01

        if isinstance(model, list):#如果m是個list

            for m in model:

                weights_normal_init(m, dev)

        else:                        #如果m是個實例

            for m in model.modules():            

                if isinstance(m, nn.Conv2d):        

                    m.weight.data.normal_(0.0, dev)

                    if m.bias is not None:

                        m.bias.data.fill_(0.0)

                elif isinstance(m, nn.Linear):

                    m.weight.data.normal_(0.0, dev)





def initialize_weights(*models):#也是初始化權重和bias的函數,不過這個函數用卷積核和通道數的大小對方差進行調整

    for model in models:

        if isinstance(model, list):

            for m in model:

                initialize_weights(m)

        else:

            for module in model.modules():

                if isinstance(module, nn.Conv2d):

                    n = module.kernel_size[0] * module.kernel_size[1] * module.out_channels

                    module.weight.data.normal_(0, math.sqrt(2. / n))

                    if module.bias is not None:

                        module.bias.data.zero_()

                elif isinstance(module, nn.BatchNorm2d):

                    module.weight.data.fill_(1)

                    module.bias.data.zero_()

                elif isinstance(module, nn.Linear):

                    n = module.weight.size(1)

                    module.weight.data.normal_(0, math.sqrt(2. / n))

                    module.bias.data.zero_()





def weights_init_kaiming(*models):#用作者名字命名的初始化權重函數,很皮

    for model in models:

        if isinstance(model, list):

            for m in model:

                weights_init_kaiming(m)

        else:

            for module in model.modules():

                if isinstance(module, nn.Conv2d):

                    #kaiming is first name of author whose last name is 'He' lol

                    nn.init.kaiming_uniform(module.weight) 

                    module.bias.data.zero_()



def adjust_learning_rate(lr, decay, optimizer, cur_epoch, n_epochs):#學習率衰減函數

    """Sets the learning rate to the initially 

        configured `lr` decayed by `decay` every `n_epochs`"""

    new_lr = lr * (decay ** (cur_epoch // n_epochs))#衰減

    for param_group in optimizer.param_groups:

        param_group['lr'] = new_lr



def calculate_mean_iu(predictions, gts, num_classes):#計算每個類別預測準確度的平均值

    sum_iu = 0

    class_iu = []

    for i in xrange(num_classes):

        n_ii = t_i = sum_n_ji = 1e-9 

        for p, gt in zip(predictions, gts):

            n_ii += np.sum(gt[p == i] == i)#好像是預測正確的個數,但是沒太看懂

            t_i += np.sum(gt == i)#i等於groundtruth

            sum_n_ji += np.sum(p == i)#i等於預測值

        sum_iu += float(n_ii) / (t_i + sum_n_ji - n_ii)#第i類的準確度

        class_iu.append(float(n_ii) / (t_i + sum_n_ji - n_ii))

    mean_iu = sum_iu / num_classes#平均正確率

    return mean_iu,class_iu





def calculate_lane_metrics(predictions, gts, num_classes):#計算預測準確率矩陣

    sum_iu = 0

    class_iu = []

    acc = []

    rec = []

    f1_m = []

    for i in xrange(num_classes):

        tp = fp = fn = 0.

        for p, gt in zip(predictions, gts):

            tp += np.sum(gt[p == i] == i)#預測正確

            fp += np.sum( (gt[p == i] != i ))#不屬於第i類但被預測爲第i類

            fn += np.sum(gt[p != i] == i)#屬於第i類但被預測爲其他類



        class_iu.append(tp / (tp + fp + fn + 1e-9))

        acc.append(tp/(tp+fp+1e-9))#準確率

        rec.append(tp/(tp+fn+1e-9))#召回率

        f1_m.append(2*acc[i]*rec[i]/(acc[i]+rec[i]+1e-9))#F1值

        sum_iu += tp / (tp + fp + fn + 1e-9)

    mean_iu = sum_iu / num_classes

    return {'miu':mean_iu,

    		'ciu':class_iu

    		},\

    		{'acc':acc,

             'rec':rec,

             'f1_m':f1_m

    		}





class CrossEntropyLoss2d(nn.Module):#交叉熵損失函數

    def __init__(self, weight=None, size_average=True):

        super(CrossEntropyLoss2d, self).__init__()

        self.nll_loss = nn.NLLLoss2d(weight, size_average)



    def forward(self, inputs, targets):

        return self.nll_loss(F.log_softmax(inputs), targets)



def rmrf_mkdir(dir_name):

    if os.path.exists(dir_name):

        shutil.rmtree(dir_name)#遞歸刪除dir_name的全部目錄

    os.mkdir(dir_name)



def rm_file(path_file):

    if os.path.exists(path_file):

        os.remove(path_file)



def colorize_mask(mask):#將圖像轉換爲P模式,其中每個像素點由8bit數字定義

    # mask: numpy array of the mask

    new_mask = Image.fromarray(mask.astype(np.uint8)).convert('P')

    new_mask.putpalette(cfg.VIS.PALETTE_LABEL_COLORS)#放置調色板(?)



    return new_mask



def _fast_hist(label_pred, label_true, num_classes):

    mask = (label_true >= 0) & (label_true < num_classes)

    hist = np.bincount(

        num_classes * label_true[mask].astype(int) +

        label_pred[mask], minlength=num_classes ** 2).reshape(num_classes, num_classes)

    return hist



def scores(predictions, gts, num_classes):

    hist = np.zeros((num_classes, num_classes))

    for lp, lt in zip(predictions, gts):

        hist += _fast_hist(lp.flatten(), lt.flatten(), num_classes)#flatten函數能將多維函數轉化爲一維函數

    # axis 0: gt, axis 1: prediction

    # acc = np.diag(hist).sum() / hist.sum()

    # acc_cls = np.diag(hist) / hist.sum(axis=1)

    # acc_cls = np.nanmean(acc_cls)

    iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist))

    mean_iu = np.nanmean(iu)

    # freq = hist.sum(axis=1) / hist.sum()

    # fwavacc = (freq[freq > 0] * iu[freq > 0]).sum()

    # return acc, acc_cls, mean_iu, fwavacc

    # pdb.set_trace()

    return {'miu':mean_iu,

    		'ciu':iu

    		}



def acc(predictions, gts, num_classes=2):

    predictions = predictions.data.numpy().astype(np.int64)

    gts = gts.data.numpy().astype(np.int64)

    predictions[predictions>=0.5]=1

    predictions[predictions<0.5]=0



    t = predictions==gts

    acc = np.sum(t)/float((t.shape[0]*t.shape[1]))

    return acc








def streaming_scores(hist,predictions, gts, num_classes):

    for lp, lt in zip(predictions, gts):

        hist += _fast_hist(lp.flatten(), lt.flatten(), num_classes)

    # axis 0: gt, axis 1: prediction

    # acc = np.diag(hist).sum() / hist.sum()

    # acc_cls = np.diag(hist) / hist.sum(axis=1)

    # acc_cls = np.nanmean(acc_cls)

    iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist))

    mean_iu = np.nanmean(iu)

    # freq = hist.sum(axis=1) / hist.sum()

    # fwavacc = (freq[freq > 0] * iu[freq > 0]).sum()

    # return hist, acc, acc_cls, mean_iu, fwavacc

    return hist, \

    	{'miu':mean_iu,

        'ciu':iu

        }

本文主要供個人學習筆記之用。與諸君共勉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章