Yang 提取Cifar-100的特征
不同的点:特征选择需要4096维的特征,而我们的代码可能64维就可以了
步骤:①保存模型②提取模型特征,然后应保存为mat
备注:MetaSAug_1
①保存模型
import os import time import argparse import random import copy import torch import torchvision import numpy as np import torch.nn.functional as F from torch.autograd import Variable import torchvision.transforms as transforms from data_utils import * from resnet import * import shutil from loss import * import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms from torch.utils.data.sampler import WeightedRandomSampler import torch.nn.functional as F import os parser = argparse.ArgumentParser(description='Imbalanced Example') parser.add_argument('--dataset', default='cifar100', type=str, help='dataset (cifar10 or cifar100[default])') parser.add_argument('--batch-size', type=int, default=100, metavar='N', help='input batch size for training (default: 64)') parser.add_argument('--num_classes', type=int, default=100) parser.add_argument('--num_meta', type=int, default=0, help='The number of meta data for each class.') parser.add_argument('--imb_factor', type=float, default=0.005) #100 #200=0.005 parser.add_argument('--test-batch-size', type=int, default=100, metavar='N', help='input batch size for testing (default: 100)') parser.add_argument('--epochs', type=int, default=200, metavar='N', help='number of epochs to train') parser.add_argument('--lr', '--learning-rate', default=1e-1, type=float, help='initial learning rate') parser.add_argument('--momentum', default=0.9, type=float, help='momentum') parser.add_argument('--nesterov', default=True, type=bool, help='nesterov momentum') parser.add_argument('--weight-decay', '--wd', default=5e-4, type=float, help='weight decay (default: 5e-4)') parser.add_argument('--no-cuda', action='store_true', default=False, help='disables CUDA training') parser.add_argument('--split', type=int, default=1000) parser.add_argument('--seed', type=int, default=42, metavar='S', help='random seed (default: 42)') parser.add_argument('--print-freq', '-p', default=100, type=int, help='print frequency (default: 10)') parser.add_argument('--lam', default=0.25, type=float, help='[0.25, 0.5, 0.75, 1.0]') #default=0.25 parser.add_argument('--gpu', default=0, type=int) parser.add_argument('--meta_lr', default=0.1, type=float) parser.add_argument('--save_name', default='name', type=str) parser.add_argument('--idx', default='0', type=str) # 定义基本的ResNet块 class BasicBlock(nn.Module): expansion = 1 def __init__(self, in_planes, planes, stride=1): super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(planes) self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(planes) self.shortcut = nn.Sequential() if stride != 1 or in_planes != self.expansion * planes: self.shortcut = nn.Sequential( nn.Conv2d(in_planes, self.expansion * planes, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(self.expansion * planes) ) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out += self.shortcut(x) out = F.relu(out) return out class ResNet32(nn.Module): def __init__(self, block, num_blocks, num_classes=100, feature_size=4096): super(ResNet32, self).__init__() self.in_planes = 16 self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(16) self.layer1 = self._make_layer(block, 16, num_blocks[0], stride=1) self.layer2 = self._make_layer(block, 32, num_blocks[1], stride=2) self.layer3 = self._make_layer(block, 64, num_blocks[2], stride=2) self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) self.fc = nn.Linear(64 * block.expansion, feature_size) def _make_layer(self, block, planes, num_blocks, stride): strides = [stride] + [1] * (num_blocks - 1) layers = [] for stride in strides: layers.append(block(self.in_planes, planes, stride)) self.in_planes = planes * block.expansion return nn.Sequential(*layers) def forward_features(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.layer1(out) out = self.layer2(out) out = self.layer3(out) out = self.avgpool(out) out = out.view(out.size(0), -1) out = self.fc(out) features = out # print("Shape of features in forward_features:", features.shape) # 添加这行代码来打印特征的形状 # print("Shape of fc weight matrix:", self.fc.weight.shape) return out, features def forward(self, x): return self.forward_features(x)[0] # 返回 forward_features 的第一个输出 def ResNet32_100(): return ResNet32(BasicBlock, [5, 5, 5], num_classes=100, feature_size=4096) # 添加 feature_size 参数 args = parser.parse_args() # for arg in vars(args): # print("{}={}".format(arg, getattr(args, arg))) os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID" os.environ["CUDA_VISIBLE_DEVICES"]= str(args.gpu) kwargs = {'num_workers': 1, 'pin_memory': False} use_cuda = not args.no_cuda and torch.cuda.is_available() torch.manual_seed(args.seed) device = torch.device("cuda" if use_cuda else "cpu") train_data_meta, train_data, test_dataset = build_dataset(args.dataset, args.num_meta) print(f'length of meta dataset:{len(train_data_meta)}') print(f'length of train dataset: {len(train_data)}') train_loader = torch.utils.data.DataLoader( train_data, batch_size=args.batch_size, shuffle=True, **kwargs) np.random.seed(42) random.seed(42) torch.manual_seed(args.seed) classe_labels = range(args.num_classes) data_list = {} for j in range(args.num_classes): data_list[j] = [i for i, label in enumerate(train_loader.dataset.targets) if label == j] img_num_list = get_img_num_per_cls(args.dataset, args.imb_factor, args.num_meta*args.num_classes) print(img_num_list) print(sum(img_num_list)) im_data = {} idx_to_del = [] for cls_idx, img_id_list in data_list.items(): random.shuffle(img_id_list) img_num = img_num_list[int(cls_idx)] im_data[cls_idx] = img_id_list[img_num:] idx_to_del.extend(img_id_list[img_num:]) print(len(idx_to_del)) imbalanced_train_dataset = copy.deepcopy(train_data) imbalanced_train_dataset.targets = np.delete(train_loader.dataset.targets, idx_to_del, axis=0) imbalanced_train_dataset.data = np.delete(train_loader.dataset.data, idx_to_del, axis=0) print(len(imbalanced_train_dataset)) imbalanced_train_loader = torch.utils.data.DataLoader( imbalanced_train_dataset, batch_size=args.batch_size, shuffle=True, **kwargs) test_loader = torch.utils.data.DataLoader( test_dataset, batch_size=args.batch_size, shuffle=False, **kwargs) best_prec1 = 0 # 初始化模型、损失函数和优化器 net = ResNet32_100() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4) # 将模型转移到GPU(如果可用) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") net.to(device) # 训练模型 best_prec1 = 0 def main(): global best_prec1 for epoch in range(200): # 你可以调整这个值来增加训练轮数 net.train() running_loss = 0.0 for i, data in enumerate(imbalanced_train_loader, 0): inputs, labels = data[0].to(device), data[1].to(device) optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if i % 100 == 99: # 每100个小批量打印一次损失 print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100)) running_loss = 0.0 # 评估模型 prec1 = validate(test_loader, net, criterion, device) print("epoch:{},prec1:{}".format(epoch, prec1)) # 保存模型 is_best = prec1 > best_prec1 best_prec1 = max(prec1, best_prec1) save_checkpoint({ 'epoch': epoch + 1, 'state_dict': net.state_dict(), 'best_prec1': best_prec1, 'optimizer': optimizer.state_dict(), }, is_best, epoch + 1, prec1) # 传递 is_best 参数 print('Finished Training') print('Best accuracy: ', best_prec1) def validate(val_loader, model, criterion, device): model.eval() correct = 0 total = 0 with torch.no_grad(): for data in val_loader: inputs, labels = data[0].to(device), data[1].to(device) outputs = model(inputs) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() acc = 100 * correct / total return acc # 定义基本的ResNet块 class BasicBlock(nn.Module): expansion = 1 def __init__(self, in_planes, planes, stride=1): super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(planes) self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(planes) self.shortcut = nn.Sequential() if stride != 1 or in_planes != self.expansion * planes: self.shortcut = nn.Sequential( nn.Conv2d(in_planes, self.expansion * planes, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(self.expansion * planes) ) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out += self.shortcut(x) out = F.relu(out) return out def save_checkpoint(state, is_best, epoch, accuracy): path = 'checkpoint/zhangYang_IR200/' if not os.path.exists(path): os.makedirs(path) if is_best: filename = str(epoch) + '_best_' + str(accuracy) + '.pth.tar' # 将整数转换为字符串 else: filename = str(epoch) + '_' + str(accuracy) + '.pth.tar' # 将整数转换为字符串 torch.save(state, os.path.join(path, filename)) # 修正保存路径 if __name__ == '__main__': main()
②保存mat
import argparse import random from data_utils import * from loss import * import torch.nn as nn import torch.optim as optim from torch.utils.data.sampler import WeightedRandomSampler import os import torch import scipy.io as sio from Meta_train import ResNet32_100 parser = argparse.ArgumentParser(description='Imbalanced Example') parser.add_argument('--dataset', default='cifar100', type=str, help='dataset (cifar10 or cifar100[default])') parser.add_argument('--batch-size', type=int, default=100, metavar='N', help='input batch size for training (default: 64)') parser.add_argument('--num_classes', type=int, default=100) parser.add_argument('--num_meta', type=int, default=0, help='The number of meta data for each class.') parser.add_argument('--imb_factor', type=float, default=0.01) #100 parser.add_argument('--test-batch-size', type=int, default=100, metavar='N', help='input batch size for testing (default: 100)') parser.add_argument('--epochs', type=int, default=200, metavar='N', help='number of epochs to train') parser.add_argument('--lr', '--learning-rate', default=1e-1, type=float, help='initial learning rate') parser.add_argument('--momentum', default=0.9, type=float, help='momentum') parser.add_argument('--nesterov', default=True, type=bool, help='nesterov momentum') parser.add_argument('--weight-decay', '--wd', default=5e-4, type=float, help='weight decay (default: 5e-4)') parser.add_argument('--no-cuda', action='store_true', default=False, help='disables CUDA training') parser.add_argument('--split', type=int, default=1000) parser.add_argument('--seed', type=int, default=42, metavar='S', help='random seed (default: 42)') parser.add_argument('--print-freq', '-p', default=100, type=int, help='print frequency (default: 10)') parser.add_argument('--lam', default=0.25, type=float, help='[0.25, 0.5, 0.75, 1.0]') #default=0.25 parser.add_argument('--gpu', default=0, type=int) parser.add_argument('--meta_lr', default=0.1, type=float) parser.add_argument('--save_name', default='name', type=str) parser.add_argument('--idx', default='0', type=str) args = parser.parse_args() for arg in vars(args): print("{}={}".format(arg, getattr(args, arg))) os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID" os.environ["CUDA_VISIBLE_DEVICES"]= str(args.gpu) kwargs = {'num_workers': 1, 'pin_memory': False} use_cuda = not args.no_cuda and torch.cuda.is_available() torch.manual_seed(args.seed) device = torch.device("cuda" if use_cuda else "cpu") train_data_meta, train_data, test_dataset = build_dataset(args.dataset, args.num_meta) print(f'length of meta dataset:{len(train_data_meta)}') print(f'length of train dataset: {len(train_data)}') train_loader = torch.utils.data.DataLoader( train_data, batch_size=args.batch_size, shuffle=True, **kwargs) np.random.seed(42) random.seed(42) torch.manual_seed(args.seed) classe_labels = range(args.num_classes) data_list = {} for j in range(args.num_classes): data_list[j] = [i for i, label in enumerate(train_loader.dataset.targets) if label == j] img_num_list = get_img_num_per_cls(args.dataset, args.imb_factor, args.num_meta*args.num_classes) print(img_num_list) print(sum(img_num_list)) im_data = {} idx_to_del = [] for cls_idx, img_id_list in data_list.items(): random.shuffle(img_id_list) img_num = img_num_list[int(cls_idx)] im_data[cls_idx] = img_id_list[img_num:] idx_to_del.extend(img_id_list[img_num:]) print(len(idx_to_del)) imbalanced_train_dataset = copy.deepcopy(train_data) imbalanced_train_dataset.targets = np.delete(train_loader.dataset.targets, idx_to_del, axis=0) imbalanced_train_dataset.data = np.delete(train_loader.dataset.data, idx_to_del, axis=0) print(len(imbalanced_train_dataset)) imbalanced_train_loader = torch.utils.data.DataLoader( imbalanced_train_dataset, batch_size=args.batch_size, shuffle=True, **kwargs) test_loader = torch.utils.data.DataLoader( test_dataset, batch_size=args.batch_size, shuffle=False, **kwargs) best_prec1 = 0 # 初始化模型、损失函数和优化器 net = ResNet32_100() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4) # 将模型转移到GPU(如果可用) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") net.to(device) # 训练模型 best_prec1 = 0 def load_model(model, checkpoint_path): checkpoint = torch.load(checkpoint_path) model.load_state_dict(checkpoint['state_dict']) return model # 定义一个函数来提取特征并保存为.mat文件 def extract_features(model, dataloader): model.eval() features_list = [] labels_list = [] # 存储标签 with torch.no_grad(): for images, labels in dataloader: # 获取标签 outputs, features = model.forward_features(images) features_list.append(features) labels_list.append(labels) features = torch.cat(features_list, dim=0) labels = torch.cat(labels_list, dim=0) # 连接所有标签 labels = labels.view(-1, 1) # 调整标签形状以便连接到特征数组 features = torch.cat((features, labels.float()), dim=1) # 在特征数组中添加标签 print("Shape of features:", features.shape) # 打印特征的形状 return features # 返回特征 def main(): # 加载已保存的模型 model = ResNet32_100() model = load_model(model, '/home/zy/pycharm/project/temp/MetaSAug_1/test/checkpoint/ours/183_33.16.pth.tar') # 提取特征 train # features = extract_features(model, imbalanced_train_loader) # 提取特征 test features = extract_features(model, test_loader) # 将特征保存为.mat文件 filename = 'Test1_183_33.16' sio.savemat('/home/zy/pycharm/project/temp/MetaSAug_1/test/matFile/' + filename + '.mat', {'data_array': features.cpu().numpy()}) # 打印.mat文件的大小 print("The size of the .mat file is:", features.shape[0], "x", features.shape[1]) if __name__ == '__main__': main()
本文作者:太好了还有脑子可以用
本文链接:https://www.cnblogs.com/ZarkY/p/18111483
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· RFID实践——.NET IoT程序读取高频RFID卡/标签