AtCoder Beginner Contest 203(Sponsored by Panasonic) D.Pond(二分+二维前缀和)

java观察者模式类图,含答案解析

  返回  

KGTN论文+代码运行

2021/7/21 20:16:20 浏览:

在这里插入图片描述

运行main_KGTN.py:

主要运行流程:

  1. 定义一个adjacent_matrix
    ndarray [1000,1000] # 针对车辆重识别VERI776应该是[576,576]
  2. 定义一个KGTN模型
import numpy as np
import math
import torch
import torch.nn.functional as F
import torch.nn as nn

class KGTN(nn.Module):
    def __init__(self, 
                 feature_dim, 
                 num_classes,
                 use_all_base,
                 use_knowledge_propagation,
                 ggnn_time_step=None,
                 pretrain=False,
                 pretrain_model=None,
                 graph_learnable=False,
                 classifier_type='inner_product',
                 adjacent_matrix=None):
        super(KGTN, self).__init__()

        self.feature_dim = feature_dim
        self.use_knowledge_propagation = use_knowledge_propagation
        self.use_all_base = use_all_base
        self.ggnn_time_step = ggnn_time_step

        self.last_fc_weight = nn.Parameter(torch.rand(feature_dim, num_classes))

        if use_knowledge_propagation:
            self.ggnn = KGTM(
                num_nodes = num_classes, 
                use_all_base = use_all_base,
                hidden_state_channel = feature_dim,
                output_channel = feature_dim,
                time_step = self.ggnn_time_step,
                adjacent_matrix = adjacent_matrix,
                graph_learnable=graph_learnable 
            )
        # initialize parameters and load pretrain
        self.param_init()
        self.load_pretrain(pretrain_model, pretrain)
        
        assert classifier_type in ['inner_product', 'cosine', 'pearson']
        self.classifier_type=classifier_type
        if self.classifier_type == 'cosine' or self.classifier_type == 'pearson':
            init_scale_cls = 10
            self.scale_cls = nn.Parameter(
                torch.FloatTensor(1).fill_(init_scale_cls),
                requires_grad=True)

    def forward(self, input):
        if self.use_knowledge_propagation:
            step_fc_weight = self.ggnn(self.last_fc_weight.transpose(0, 1).unsqueeze(0))
            weight = step_fc_weight[-1]
            weight = weight.squeeze().transpose(0, 1)
            if self.classifier_type == 'cosine':
                # cos sim
                input = F.normalize(input, p=2, dim=1, eps=1e-12)
                weight = F.normalize(weight, p=2, dim=0, eps=1e-12)
                output = torch.matmul(input, weight) * self.scale_cls
            elif self.classifier_type == 'pearson':
                # pearson corr
                input = input - torch.mean(input, 1, keepdim=True)
                weight = weight - torch.tensor(torch.mean(weight, 0, keepdim=True), requires_grad=False)
                input = F.normalize(input, p=2, dim=1, eps=1e-12)
                weight = F.normalize(weight, p=2, dim=0, eps=1e-12)
                output = torch.matmul(input, weight) * self.scale_cls
            else:
                output = torch.matmul(input, weight)
            l2_reg = self.l2_reg(weight)
        else:
            output = torch.matmul(input, self.last_fc_weight)
            l2_reg = self.l2_reg(self.last_fc_weight)
        return output, l2_reg
    
    def l2_reg(self, input):
        return input.pow(2).sum()

    def load_pretrain(self,pretrain_model, pretrain):
        if pretrain:
            pretrain = torch.load('checkpoints/{}'.format(pretrain_model))['state_dict']
            self_param = self.state_dict()
            self_param.update(pretrain)

            self.load_state_dict(self_param)

    def param_init(self):
        # init parameters
        self.last_fc_weight.data.normal_(0.0, np.sqrt(2.0/self.feature_dim))

class KGTM(nn.Module):
    def __init__(self,
                 num_nodes = 512, 
                 use_all_base = False,
                 hidden_state_channel = 20,
                 output_channel = 20,
                 time_step = 3,
                 adjacent_matrix = None,
                 graph_learnable=False):

        super(KGTM, self).__init__()
        self.num_nodes = num_nodes
        self.use_all_base = use_all_base
        self.time_step = time_step
        self.hidden_state_channel = hidden_state_channel
        self.output_channel = output_channel
        self.adjacent_matrix = adjacent_matrix
        self.graph_learnable = graph_learnable
        #  form the connect matrix 
        self._in_matrix,self._out_matrix = self.load_adjacent_matrix(self.adjacent_matrix)
        
        self._in_matrix = nn.Parameter(torch.from_numpy(self._in_matrix), requires_grad=graph_learnable)
        self._out_matrix = nn.Parameter(torch.from_numpy(self._out_matrix), requires_grad=graph_learnable)

        self.fc_eq3_w = nn.Linear(2 * hidden_state_channel,hidden_state_channel, bias = False)
        self.fc_eq3_u = nn.Linear(hidden_state_channel,hidden_state_channel, bias = False)
        self.fc_eq4_w = nn.Linear(2 * hidden_state_channel,hidden_state_channel, bias = False)
        self.fc_eq4_u = nn.Linear(hidden_state_channel,hidden_state_channel, bias = False)
        self.fc_eq5_w = nn.Linear(2 * hidden_state_channel,hidden_state_channel, bias = False)
        self.fc_eq5_u = nn.Linear(hidden_state_channel,hidden_state_channel, bias = False)

        self.transform_fc = nn.Linear(hidden_state_channel, hidden_state_channel, bias=False)

        self.fc_output = nn.Linear(2 * hidden_state_channel,output_channel)

        self._initialize_weights()

    def forward(self, input):
        outputs_per_step = []
        # input : batch * 512 * 10
        batch_size = input.size()[0]
        input = input.view(-1,self.hidden_state_channel)

        batch_aog_nodes = input.view(-1,self.num_nodes,self.hidden_state_channel)

        batch_in_matrix = self._in_matrix.repeat(batch_size,1).view(batch_size,self.num_nodes,-1)
        batch_out_matrix = self._out_matrix.repeat(batch_size,1).view(batch_size,self.num_nodes,-1)

        # propogation process
        for t in range(self.time_step):
             # eq(2)
            av = torch.cat((torch.bmm(batch_in_matrix,batch_aog_nodes) ,torch.bmm(batch_out_matrix,batch_aog_nodes)),2)
            av = av.view(batch_size * self.num_nodes,-1)
            flatten_aog_nodes = batch_aog_nodes.view(batch_size * self.num_nodes,-1)
            # eq(3)
            zv = torch.sigmoid(self.fc_eq3_w(av) + self.fc_eq3_u(flatten_aog_nodes))
            # eq(4)
            rv = torch.sigmoid(self.fc_eq4_w(av) + self.fc_eq4_u(flatten_aog_nodes))
            # eq(5)
            hv = torch.tanh(self.fc_eq5_w(av) + self.fc_eq5_u(rv * flatten_aog_nodes))
            # hv = self.fc_eq5_w(av) + self.fc_eq5_u(rv * flatten_aog_nodes)
            # eg(6)
            flatten_aog_nodes = (1 - zv) * flatten_aog_nodes + zv *  hv

            batch_aog_nodes = flatten_aog_nodes.view(batch_size,self.num_nodes,-1)

            # compute the output of each step
            step_output = torch.cat((flatten_aog_nodes,input),1)
            # step_output = flatten_aog_nodes
            step_output = self.fc_output(step_output)
            step_output = step_output.view(batch_size,self.num_nodes,-1)
            outputs_per_step.append(step_output)

        return outputs_per_step


    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                m.weight.data.normal_(0, 0.01)
                if m.bias is not None:
                    m.bias.data.zero_()
        
        self.fc_eq3_w.weight.data.zero_()
        self.fc_eq3_u.weight.data.zero_()
        self.fc_eq4_w.weight.data.zero_()
        self.fc_eq4_u.weight.data.zero_()
        self.fc_eq5_w.weight.data.zero_()
        self.fc_eq5_u.weight.data.zero_()

        self.transform_fc.weight.data = torch.eye(self.hidden_state_channel)
  
    def load_adjacent_matrix(self, mat):
        in_matrix = mat
        out_matrix = in_matrix.transpose()

        return in_matrix.astype(np.float32),out_matrix.astype(np.float32)

定义:

        model = KGTN(
               feature_dim=2048, # feature dim
               num_classes=576, # 576
               use_all_base=False, # False
               use_knowledge_propagation=True,
               ggnn_time_step=2,
               pretrain=False,
               adjacent_matrix = adjacent_matrix,
               classifier_type='inner_product',
               )
        model = model.cuda()

3.用数据集执行训练

optimizer = torch.optim.SGD(filter(lambda p:p.requires_grad==True, model.parameters()), 0.01, momentum=0.9, dampening=0.9, weight_decay=0.0001)
loss_function = nn.CrossEntropyLoss()
loss_function = loss_function.cuda()
for 第i轮epoch:
        model.train()      
        (x,y)  # x [1000,2048] y[1000] 这里的1000表示类别数目,一定要跟类别一致,这里的batch_size都是1,貌似[64,2048]也OK的
        # 这里
        optimizer.zero_grad()

        output, l2_reg = model(x.cuda())

        cls_loss = loss_function(output,y.cuda())
        total_loss = cls_loss + 0.001 * l2_reg

        total_loss.backward()
        optimizer.step()
  1. 修改保存模型的路径
【记得改output_dir:】
cfg.output_dir = '../outputs/veri776_b64_pven_0714_kgtn/'

save_checkpoint(epoch, cfg.output_dir,
            model=model, optimizer=optimizer)
# change
save_checkpoint(epoch, cfg.output_dir,
			model_kgtn=model_kgtn, optimizer=optimizer)

运行save_feature.py:

##加载 配置文件
KGTN/DataSplit/FeatureExtractor/train_save_data.yaml

修改imagenet文件:
rootdir: '../data/imagenet/' # Change this to ImageNet directory

下载ImageNet太慢了,只是为了看数据形状,修改KGTN/FeatureExtractor/myMetaDataset.py的加载路径:

    def __getitem__(self,i):
        # image_path = os.path.join(self.rootdir, self.meta['image_names'][i])
        #image_path = os.path.join('/data1/tianshui/imagenet/image/ILSVRC2012_img_val', self.meta['image_names'][i].split('/')[-1])
		
		# change
        image_path = "/home/qinghua/Documents/wjn/KGTN/data/n02486410_0.JPEG"
        img = Image.open(image_path).convert('RGB')
        img = self.transform(img)
        target = self.target_transform(self.meta['image_labels'][i])
        return img, target

h5py报错:

f = h5py.File('../features/ResNet50_sgm/train.hdf5', 'w')

一直报错:

File "h5py/h5f.pyx", line 120, in h5py.h5f.create
BlockingIOError: [Errno 11] Unable to create file (unable to lock file, errno = 11, error message = 'Resource temporarily unavailable')

【解决方案】

os.environ["HDF5_USE_FILE_LOCKING"] = "FALSE"

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号