通过Pytorch实现的AlexNet实现多分类项目留档

//训练代码(mytrain.py):

    import os
    from torchvision import transforms
    from torch.utils.data import Dataset, DataLoader
    from PIL import Image
    import numpy as np
    import torch
    from torch import optim
    import torch.nn as nn
    from torch.autograd import Variable
    from torchvision.models import alexnet

    import tqdm
    from tqdm import *


    def pre_process(path):
        # 传入训练集地址,预处理,地址表,打标签
        print('preprocessing the dataset in ', path)
        data = []
        real_list = os.listdir(path+'training_real/')
        fake_list = os.listdir(path+'training_fake/')
        # for jupyterlab
        if '.ipynb_checkpoints' in real_list : real_list.remove('.ipynb_checkpoints')
        if '.ipynb_checkpoints' in fake_list : fake_list.remove('.ipynb_checkpoints')
        # finished
        print('len of real_list:',len(real_list))
        print('len of fake_list:',len(fake_list))


        for imgpath in real_list:
            data.append([path+'training_real/'+imgpath,[0,0,0,0]])

        for imgpath in fake_list:
            lable_str = imgpath[-8:-4]
            if imgpath == '.ipynb_checkpoints' : print(imgpath,'in fake')
            lable = []
            for i in lable_str: 
                lable.append(int(i))
            data.append([path+'training_fake/'+imgpath,lable])

        print('len of data:',len(data))
        return data


    class MyDataset(Dataset):
        def __init__(self, data, transform, loader):
            self.data = data
            self.transform = transform
            self.loader = loader

        def __len__(self):
            return len(self.data)

        def __getitem__(self, idx):
            imgpath, label = self.data[idx]
            image = self.loader(imgpath)
            image = self.transform(image)
            return image, label


    def Myloader(path):
            return Image.open(path).convert('L').convert('RGB') # 转灰度图像


    def data_load(dataset_path):
        print('loading dataset......')
        # 返回 Dataloader_train

        # 自定义 transform
        transform = transforms.Compose([
            transforms.Resize((256,256)),
            transforms.ToTensor()
        ])

        # 预处理训练集集
        data = pre_process(dataset_path)

        # 初始化训练集
        train_data = MyDataset(data, transform=transform, loader=Myloader)
        Dtr = DataLoader(dataset=train_data, batch_size=50, shuffle=True, num_workers=0)

        return Dtr


    if __name__ == "__main__":
        epoch_num = 30
        best_model = None
        min_epochs = 5
        min_val_loss = 5
        epochs = 30
        lr = 0.0001
        batch_size = 25
        device = "cuda"

        dataset_path = './real_and_fake_face_training/'  # 训练集文件夹路径

        print(f'''
        paramater:
        ------------------
        epoch_num    \t {epoch_num} 
        best_model   \t {best_model}
        min_epochs   \t {min_epochs}
        min_val_loss   \t {min_val_loss}
        epochs   \t {epochs}
        lr      \t {lr}
        batch_size \t {batch_size}
        device   \t {device}
        dataset_path  \t {dataset_path}
        save_path  \t {save_path}
        ------------------
        ''')


        Dtr = data_load(dataset_path)
        model = alexnet(pretrained=True)
        model.classifier._modules['6'] = nn.Sequential(nn.Linear(4096, 4)) # 简单更改后的AlexNet
        print(model)

        print("training......")
        model = model.to(device)
        optimizer = optim.Adam(model.parameters(), lr=lr) # 优化方法 Adam
        criterion = nn.MultiLabelSoftMarginLoss().to(device)  # 损失函数用 MultiLabelSoftMarginLoss()

        for epoch in tqdm(range(epoch_num), ascii=True):
            train_loss = []
            for batch_idx, (data, target) in enumerate(Dtr, 0):

                target = torch.t(torch.stack(target))
                # print(target)
                # print(data)
                data, target = Variable(data).to(device), Variable(target).to(device)

                optimizer.zero_grad() # 梯度清0
                output = model(data)  # 前向传播 
                loss = criterion(output, target)  # 计算误差
                loss.backward() # 反向传播
                optimizer.step() # 更新参数
                train_loss.append(loss.cpu().item())

            tqdm.write('Epoch {:03d} train_loss {:.5f} '.format(epoch, np.mean(train_loss)))

        torch.save(model.state_dict(), 'model_weights.pth')
```python
//测试代码(mytest.py)

    import os
    from torchvision import transforms
    from torch.utils.data import Dataset, DataLoader
    from PIL import Image
    import torch
    from torch.autograd import Variable
    from torchvision.models import alexnet
    import torch.nn as nn

    class MyDataset(Dataset):
        def __init__(self, data, transform, loader):
            self.data = data
            self.transform = transform
            self.loader = loader

        def __len__(self):
            return len(self.data)

        def __getitem__(self, idx):
            imgpath, label = self.data[idx]
            image = self.loader(imgpath)
            image = self.transform(image)
            return image, label


    def Myloader(path):
            return Image.open(path).convert('L').convert('RGB') # 转灰度图像


    def load_data(path):
        print('Loading data....')
        test_list = os.listdir(path)

        data = []
        for imgpath in test_list:
            data.append([path + imgpath,[0,0,0,0]])

        print('len of data:',len(data))

        transform = transforms.Compose([
            transforms.Resize((256,256)),
            transforms.ToTensor()
        ])

        test_dataset = MyDataset(data,transform,Myloader)
        Dts = DataLoader(dataset=test_dataset, batch_size=50, shuffle=False, num_workers=0)

        return Dts


    if __name__ == '__main__':

        device = 'cuda'
        test_path = './real_and_fake_face_testing/real_and_fake_face_testing/'

        model = alexnet()
        model.classifier._modules['6'] = nn.Sequential(nn.Linear(4096, 4))
        model.load_state_dict(torch.load('model_weights.pth'))
        model.eval()
        model.to(device)

        Dts = load_data(test_path)
        test_list = os.listdir(test_path)
        pred = []

        print('Testing...')
        for batch_idx, (data, lable) in enumerate(Dts, 0):
            lable = torch.t(torch.stack(lable))
            data, lable = Variable(data).to(device), Variable(lable).to(device)
            temp = model(data)
            # print(temp)
            pred.append(temp)

        # file=open('result.txt',mode='x')
        # print(pred)
        print('-----------------map-----------------')
        # for k in pred : file.write(str(k[0]))
        # file.close()

        res = []
        for k in pred:
            for z in k: res.append(z.cpu().detach().numpy().tolist())
        print('the res len:',len(res))
        for i in range(len(res)):
            print(test_list[i],res[i],sep='\t')