torch-cifar10-3

torch-cifar10-3

现在的问题是需要造验证集,我的想法是从训练集里面随机的抽取出5000张作为训练集,但是那个Cifar要调两次,一次是训练集,一次是验证集,这样不太好,我想要读一次csv文件然后就能把两个数据集得到, 所以现在修改Cifar这个类的初始化条件,这次直接传入那个需要的list,然后在之前先得到关于训练和验证的list。

具体的是这样写的,不太规范。

def read_csv(csvfile):
    total = set(range(1, 50001))
    valid = list(np.random.choice(range(1, 50001), size=5000, replace=False))
    train = total-set(valid)
    print(len(valid), len(train))
    
    train_list = []
    val_list = []

    dirname = os.path.split(csvfile)[0]
    
    with open(csvfile, 'r') as f:
        lines = f.readlines()[1:]
        tokens = [l.strip().split(",") for l in lines]
    
        for x,y in tokens:
            label = name2label[y]
            newname = os.path.join(dirname, 'train', str(x)+".png")    
            if int(x) in train:
                train_list.append((newname, label))
            else:
                val_list.append((newname, label))
    assert len(train_list) == 45000 and len(val_list)==5000 
    return train_list, val_list

然后Cifar的类现在是这样写的

class Cifar(torch.utils.data.Dataset):
    #def __init__(self, csvfile, transformer=None):
    def __init__(self, img_list, transformer=None):
        #需要一个文件名和label的对应
        self.img_list = img_list  # img_list = [(img_path, label), ..., ]
        self.transformer = transformer

    def __getitem__(self, idx):
        img_path = self.img_list[idx][0]   # abs path
        #img = np.array(cv2.imread(img_path), dtype=np.float32)   # maybe this is error!!!
        img = Image.open(img_path)
        label = self.img_list[idx][1]
        img = self.transformer(img) 

这样读一次csv就得到了训练集验证集。其他的稍微修改了之后就可以训练和保存模型了。

接下来的就是用保存下来的模型在30w测试集上去测试然后检查一下之前写的会不会有问题,

网络保存的是这样写的


state = { 
                'net':net.state_dict(),
                'acc':acc,
                'epoch':epoch,
                }
        if not os.path.isdir('checkpoint'):
            os.mkdir('checkpoint')
        torch.save(state, './checkpoint/cifar.t7')

推理并上传结果

这个过程比较容易,就是把之前保存的网络模型读出来,然后输入测试集,做一次前向计算得到推理结果,但是要注意,需要对测试集做处理

transform_test = transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
    
            ])


#plt.figure(figsize=(25,20), dpi=50)

result = []
for i, item in enumerate(files):
    img = transform_test(Image.open(os.path.join(testdir,item))).to(device)    
    #print(img.shape)
    img = torch.unsqueeze(img, 0)

仍然是用Image读出来的图像,然后去做处理,然后放到device上面,torch.unsqueeze(img, 0)这个很有必要,不然会报 expected stride to be a single integer value or a list of 1 values to match....., 这个原因是没有做操作之间,img的shape仍是三维的,少了一个batch的维度,所以要转变成为4维的张量。

模型加载的时候我也搞了好长时间,原因是不知道‘.t7’该如何读,然后还有一个bug是因为我训练的时候用的是net = torch.nn.DataParallel(net)但是读出来的时候没有用这个,我是重新把这个注销掉训练又保存的,然后就可以加载出来了。

本来想只画一下图来看一下结果是不是差别很大,结果像素太低了,根本看不出来是个啥东西。所以还是上传了csv,结果如下。说明上面的代码应该没有问题。

avator

打赏,谢谢~~

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,多谢支持~

打开微信扫一扫,即可进行扫码打赏哦