master
CaoGang2018 2020-05-29 18:05:22 +08:00
parent fe86f0ff6f
commit 7e25bc99d5
16 changed files with 341 additions and 0 deletions

63
SCDA.py 100644
View File

@ -0,0 +1,63 @@
import torch as t
import torchvision.models as model
import torch.nn.functional as F
from util.largestConnectComponent import largestConnectComponent
"""
feat_map = t.ones(5, 2, 4)
print(feat_map)
A = feat_map.sum(dim=0)
print(A)
a = A.mean(dim=[0, 1])
print(float(a))
"""
def select_aggregate(feat_map):
A = t.sum(feat_map, dim=[0])
a = t.mean(A, dim=[0, 1]).float()
tmp = t.ones(A.shape)
tmp[A<a] = 0
tmp_out = t.zeros(feat_map.shape)
cc = largestConnectComponent(tmp)
for i in range(tmp.shape[0]):
for j in range(tmp.shape[1]):
if cc[i, j]:
tmp_out[:, i, j] = feat_map[:, i, j]
return tmp_out, cc
def select_aggregate_and(feat_map, cc2): # relu5_2
A = t.sum(feat_map, dim=[0])
a = t.mean(A, dim=[0, 1]).float()
tmp = t.ones(A.shape)
tmp[A<a] = 0
tmp_out = t.zeros(feat_map.shape)
cc = largestConnectComponent(tmp)
p, q = cc2.shape
tm = t.zeros(cc2.shape)
for i in range(p):
for j in range(q):
if cc2[i, j]:
tm[i, j] = 1
return tmp_out
cc_and = F.interpolate(t.from_numpy(tm.reshape(1, 1, p, q)), size=cc.shape, mode='nearest').reshape(cc.shape)
for i in range(tmp.shape[0]):
for j in range(tmp.shape[1]):
if cc[i, j] and cc_and[i, j] == 1:
tmp_out[:, i, j] = feat_map[:, i, j]
return tmp_out
# x = t.randn(3, 4, 4)
# # print(type(x))
# print(x)
# sx = select_aggregate(x)
# print(sx)
# print(cc)
# tx = t.zeros(x.shape)
# cc = largestConnectComponent(sx)
# for i in range(sx.shape[0]):
# for j in range(sx.shape[1]):
# if cc[i, j]:
# tx[:, i, j] = x[:, i, j]
# print(tx)

116
data/CUB_200.py 100644
View File

@ -0,0 +1,116 @@
import torch
import torchvision.transforms as transforms
import torch.utils.data as data
from os.path import join
from scipy.io import loadmat
from collections import namedtuple
from PIL import Image
rootdir = 'F:\Paper\SCDA\SCDA_pytorch_CODE\data\images'
dbStruc = namedtuple('dbStruct', ['name', 'class1'])
'''
path = 'imdb.mat'
mat = loadmat(path)
matStruct = mat['images'].item()
dbImage = matStruct[1]
print(dbImage.shape)
'''
def parse_dbStruct(path):
mat = loadmat(path)
matStruct = mat['images'].item()
dbImage = matStruct[1][0]
dbclass = matStruct[3]
return dbStruc(dbImage, dbclass)
def input_transform():
return transforms.Compose([
transforms.Scale(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], # 将Tensor正则化
std=[0.229, 0.224, 0.225]),
])
def input_transform2():
return transforms.Compose([
transforms.Scale(256),
transforms.CenterCrop(224),
transforms.RandomHorizontalFlip(p=1),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], # 将Tensor正则化
std=[0.229, 0.224, 0.225]),
])
def get_dataset():
structFile = join(rootdir, 'imdb.mat')
return WholeDataset(structFile)
img_dir = 'F:\Datesets\CUB_200\CUB_200_2011\CUB_200_2011\images'
class WholeDataset(data.Dataset):
def __init__(self, structFile):
super(WholeDataset, self).__init__()
self.dbStruct = parse_dbStruct(structFile)
self.images = [join(img_dir, dbim[0] + '.jpg') for dbim in self.dbStruct[0]]
self.classes = self.dbStruct[1][0]
self.input_transform1 = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], # 将Tensor正则化
std=[0.229, 0.224, 0.225]),
])
self.input_transform2 = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.RandomHorizontalFlip(p=1), # flip
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], # 将Tensor正则化
std=[0.229, 0.224, 0.225]),
])
# def input_transform(self):
# return transforms.Compose([
# transforms.Scale(256),
# transforms.CenterCrop(224),
# transforms.ToTensor(),
# transforms.Normalize(mean=[0.485, 0.456, 0.406], # 将Tensor正则化
# std=[0.229, 0.224, 0.225]),
# ])
# def input_transform2(self):
# return transforms.Compose([
# transforms.Scale(256),
# transforms.CenterCrop(224),
# transforms.RandomHorizontalFlip(p=1), # flip
# transforms.ToTensor(),
# transforms.Normalize(mean=[0.485, 0.456, 0.406], # 将Tensor正则化
# std=[0.229, 0.224, 0.225]),
# ])
def __getitem__(self, index):
img = Image.open(self.images[index])
img = img.convert('RGB')
label = self.classes[index]
img1 = self.input_transform1(img)
img2 = self.input_transform2(img)
return img1, img2, label
def __len__(self):
return len(self.images)

2
data/__init__.py 100644
View File

@ -0,0 +1,2 @@
from .CUB_200 import WholeDataset

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

BIN
data/imdb.mat 100644

Binary file not shown.

85
main.py 100644
View File

@ -0,0 +1,85 @@
from torch.utils.data import DataLoader
from data.CUB_200 import get_dataset, input_transform, input_transform2
import SCDA
from torchvision import models
import torch
import torch.nn.functional as F
import csv
import numpy as np
from util.model import pool_model
def write_csv(results,file_name):
import csv
with open(file_name,'w') as f:
writer = csv.writer(f)
writer.writerow(['id','label'])
writer.writerows(results)
net1 = models.vgg16(pretrained=True).features[:-3]
net2 = models.vgg16(pretrained=True).features
dataset_or = get_dataset()
# dataset_filp = get_dataset(transform=input_transform2)
data_or = DataLoader(dataset_or, batch_size=10, shuffle=True,num_workers=0)
# data_flip = DataLoader(dataset_filp, batch_size=20, shuffle=True,num_workers=0)
net1.eval()
net2.eval()
result = []
max_ave_pool = pool_model()
out = open('feat.csv', 'a', newline='')
csv_write = csv.writer(out, dialect='excel')
csv_write.writerow(['features', 'label'])
for ii, (img1, img2, label) in enumerate(data_or):
input1 = img1
feat_re = net1(input1)
feat_po = net2(input1)
input2 = img2
feat_flip_re = net1(input2)
feat_flip_po = net2(input2)
m, _, _, _ = feat_re.shape
label = label.detach().numpy()
f_po = torch.zeros(feat_po.shape)
f_re = torch.zeros(feat_re.shape)
filp_po = torch.zeros(feat_flip_po.shape)
filp_re = torch.zeros(feat_flip_re.shape)
for i in range(m):
# f_re[i] = SCDA.select_aggregate(feat_re[i].detach().numpy())
f_po[i] = SCDA.select_aggregate(feat_po[i])[0] # 31a
cc2 = SCDA.select_aggregate(feat_po[i])[1]
f_re[i] = SCDA.select_aggregate_and(feat_re[i], cc2) # 28a
filp_po[i] = SCDA.select_aggregate(feat_flip_po[i])[0] # 31b
cc2_f = SCDA.select_aggregate(feat_flip_po[i])[1]
filp_re[i] = SCDA.select_aggregate_and(feat_flip_re[i], cc2_f) # 28b
# print(f.shape)
# l = int(lable[i])
# csv_write.writerow([f, l])
# del f, l
# result.append((f, l))
# print(f_po.shape)
l31a = max_ave_pool(f_po)
l28a = max_ave_pool(f_re)
l31b = max_ave_pool(filp_po)
l28b = max_ave_pool(filp_re)
feat = torch.cat((l31a, 0.5*l28a, l31b, 0.5*l28b), dim=1).reshape(m, -1).detach().numpy()
for i in range(m):
csv_write.writerow([feat[i], int(label[i])])
print('batch {} complete'.format(ii))
# avg.train_data_L31a
# maxi.train_data_L31a
# ratio.*avg.train_data_L28a
# ratio.*maxi.train_data_L28a
# avg.train_data_L31b
# maxi.train_data_L31b
# ratio.*avg.train_data_L28b
# ratio.*maxi.train_data_L28b

0
util/__init__.py 100644
View File

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,37 @@
from skimage.measure import label
import numpy as np
def largestConnectComponent(bw_img, neighbor=2):
'''
compute largest Connect component of a binary image
Parameters:
---
bw_img: ndarray
binary image
Returns:
---
lcc: ndarray
largest connect component.
Example:
---
>>> lcc = largestConnectComponent(bw_img)
'''
labeled_img, num = label(bw_img, connectivity=neighbor, background=0, return_num=True)
# plt.figure(), plt.imshow(labeled_img, 'gray')
max_label = 0
max_num = 0
for i in range(1, num+1): # 这里从1开始防止将背景设置为最大连通域
if np.sum(labeled_img == i) > max_num:
max_num = np.sum(labeled_img == i)
max_label = i
lcc = (labeled_img == max_label)
return lcc

38
util/model.py 100644
View File

@ -0,0 +1,38 @@
import torch as t
import torch.nn as nn
from torchvision import models
import torch.nn.functional as F
class pool_model(nn.Module):
def __init__(self):
super(pool_model, self).__init__()
self.pool1 = nn.AdaptiveAvgPool2d(1)
self.pool2 = nn.AdaptiveMaxPool2d(1)
def forward(self, x):
tmp1 = self.pool1(x)
tmp2 = self.pool2(x)
b, c, _, _ = tmp1.shape
# print(tmp1.shape)
return t.cat((tmp1, tmp2), dim=1).reshape(b, -1)
# x = t.ones(2, 512, 7, 7)
# model = pool_model()
# print(model(x).shape)
# class Net(nn.modules):
# def __init__(self):
# super(Net, self).__init__()
# self.basenet = models.vgg16(pretrained=True).features
# # print(self.basenet)
# def forward(self, x):
# x = self.basenet(x)
# return x
# net1 = models.vgg16(pretrained=False).features[:-3]
# net2 = models.vgg16(pretrained=False).features
# x = t.ones(2, 3, 224, 224)
# print(net1(x).shape)
# x1 = F.interpolate(net2(x), size=net1(x).shape[-2:], mode='nearest')
# print(x1.shape)