《深度学习之PyTorch实战计算机视觉》学习笔记(6)

这部分利用pytorch手动实现一个简化版的Vgg网络模型,用来对猫狗进行分类

由于CPU计算太慢,改用GPU来计算。代码基于python3.7, pytorch 1.0,cuda 10.0 .

import torch
import torchvision
from torch.autograd import Variable
from torchvision import datasets, transforms
import os            # os包集成了一些对文件路径和目录进行操作的类
import matplotlib.pyplot as plt
%matplotlib inline
import time
# 读取数据
data_dir = 'DogsVSCats'
data_transform = {x:transforms.Compose([transforms.Scale([64, 64]),
                                       transforms.ToTensor()]) for x in ['train', 'valid']}   # 这一步类似预处理
image_datasets = {x:datasets.ImageFolder(root = os.path.join(data_dir,x),
                                        transform = data_transform[x]) for x in ['train', 'valid']}  # 这一步相当于读取数据
dataloader = {x:torch.utils.data.DataLoader(dataset = image_datasets[x],
                                           batch_size = 16,
                                           shuffle = True) for x in ['train', 'valid']}  # 读取完数据后,对数据进行装载
# 数据预览
X_example, Y_example = next(iter(dataloader['train']))
print(u'X_example个数{}'.format(len(X_example)))
print(u'Y_example个数{}'.format(len(Y_example)))

index_classes = image_datasets['train'].class_to_idx   # 显示类别对应的独热编码
print(index_classes)

example_classes = image_datasets['train'].classes     # 将原始图像的类别保存起来
print(example_classes)

img = torchvision.utils.make_grid(X_example)
img = img.numpy().transpose([1,2,0])
print([example_classes[i] for i in Y_example])
plt.imshow(img)
plt.show()
X_example个数16
Y_example个数16
{'cat': 0, 'dog': 1}
['cat', 'dog']
['dog', 'dog', 'cat', 'dog', 'cat', 'dog', 'dog', 'cat', 'cat', 'cat', 'cat', 'cat', 'dog', 'cat', 'dog', 'cat']

《深度学习之PyTorch实战计算机视觉》学习笔记(6)_第1张图片

# 模型搭建  简化了的VGGnet
class Models(torch.nn.Module):
    def __init__(self):
        super(Models,self).__init__()
        self.Conv = torch.nn.Sequential(
                    torch.nn.Conv2d(3, 64, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.Conv2d(64, 64, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.MaxPool2d(kernel_size = 2, stride = 2),
        
                    torch.nn.Conv2d(64, 128, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.Conv2d(128, 128, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.MaxPool2d(kernel_size = 2, stride = 2),
        
                    torch.nn.Conv2d(128, 256, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.Conv2d(256, 256, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.Conv2d(256, 256, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.MaxPool2d(kernel_size = 2, stride = 2),
        
                    torch.nn.Conv2d(256, 512, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.Conv2d(512, 512, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.Conv2d(512, 512, kernel_size = 3, stride = 1, padding = 1),
                    torch.nn.ReLU(),
                    torch.nn.MaxPool2d(kernel_size = 2, stride = 2))
        self.Classes = torch.nn.Sequential(
                        torch.nn.Linear(4*4*512, 1024),
                        torch.nn.ReLU(),
                        torch.nn.Dropout(p = 0.5),
                        torch.nn.Linear(1024, 1024),
                        torch.nn.ReLU(),
                        torch.nn.Dropout(p = 0.5),
                        torch.nn.Linear(1024, 2))
    def forward(self, inputs):
        x = self.Conv(inputs)
        x = x.view(-1, 4*4*512)
        x = self.Classes(x)
        return x
model = Models()
print(model)
Models(
  (Conv): Sequential(
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU()
    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU()
    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (6): ReLU()
    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (8): ReLU()
    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU()
    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (13): ReLU()
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (15): ReLU()
    (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (18): ReLU()
    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (20): ReLU()
    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (22): ReLU()
    (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (Classes): Sequential(
    (0): Linear(in_features=8192, out_features=1024, bias=True)
    (1): ReLU()
    (2): Dropout(p=0.5)
    (3): Linear(in_features=1024, out_features=1024, bias=True)
    (4): ReLU()
    (5): Dropout(p=0.5)
    (6): Linear(in_features=1024, out_features=2, bias=True)
  )
)
#  定义好模型的损失函数和对参数进行优化的优化函数
loss_f = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr = 0.00001)


# 用cpu计算太慢了,改用GPU计算 model = model.cuda()和X, y = Variable(X.cuda())

print(torch.cuda.is_available())
Use_gpu = torch.cuda.is_available()

if Use_gpu:
    model = model.cuda()

# 开始训练
epoch_n = 10
time_open = time.time()

for epoch in range(epoch_n):
    print('Epoch {}/{}'.format(epoch, epoch_n - 1))
    print('-'*10)
    
    for phase in ['train', 'valid']:
        if phase == 'train':
            print('Training...')
            model.train(True)
        else:
            print('Validing...')
            model.train(False)
            
        running_loss = 0.0
        running_correct = 0.0
        
        for batch, data in enumerate(dataloader[phase], 1):
            X, Y = data
            
            X, Y = Variable(X).cuda(),Variable(Y).cuda()
            
            y_pred = model(X)
            
            _, pred = torch.max(y_pred.data, 1)  # 找出每一行中的最大的值对应的索引
            
            optimizer.zero_grad()
            
            loss = loss_f(y_pred, Y)
            
            if phase == 'train':
                loss.backward()
                optimizer.step()
                
            running_loss += loss.data.item()
            running_correct += torch.sum(pred == Y.data)
            
            if batch % 500 == 0 and phase == 'train':
                print('Batch {}, Train Loss:{:.4f},Train ACC: {:.4f}'.format(batch,
                                                                            running_loss/batch,
                                                                            100*running_correct/(16*batch)))
        epoch_loss = running_loss * 16 / len(image_datasets[phase])
        epoch_acc = 100 * running_correct / len(image_datasets[phase])
        print('{} Loss:{:.4f} ACC:{:.4f}%'.format(phase, epoch_loss, epoch_acc))
    time_end = time.time() - time_open
    print(time_end)
            

True
Epoch 0/9

Training…
Batch 500, Train Loss:0.6932,Train ACC: 50.0000
Batch 1000, Train Loss:0.6929,Train ACC: 50.0000
train Loss:0.6914 ACC:51.0000%
Validing…
valid Loss:0.6866 ACC:55.0000%
85.06281304359436
Epoch 1/9

Training…
Batch 500, Train Loss:0.6797,Train ACC: 57.0000
Batch 1000, Train Loss:0.6764,Train ACC: 57.0000
train Loss:0.6757 ACC:58.0000%
Validing…
valid Loss:0.6623 ACC:60.0000%
170.04998254776
Epoch 2/9

Training…
Batch 500, Train Loss:0.6603,Train ACC: 60.0000
Batch 1000, Train Loss:0.6549,Train ACC: 61.0000
train Loss:0.6524 ACC:61.0000%
Validing…
valid Loss:0.6362 ACC:62.0000%
256.68618655204773
Epoch 3/9

Training…
Batch 500, Train Loss:0.6349,Train ACC: 63.0000
Batch 1000, Train Loss:0.6322,Train ACC: 64.0000
train Loss:0.6295 ACC:64.0000%
Validing…
valid Loss:0.6147 ACC:66.0000%
343.0681140422821
Epoch 4/9

Training…
Batch 500, Train Loss:0.6113,Train ACC: 66.0000
Batch 1000, Train Loss:0.6068,Train ACC: 67.0000
train Loss:0.6079 ACC:66.0000%
Validing…
valid Loss:0.6013 ACC:67.0000%
428.4903573989868
Epoch 5/9

Training…
Batch 500, Train Loss:0.5887,Train ACC: 68.0000
Batch 1000, Train Loss:0.5917,Train ACC: 68.0000
train Loss:0.5903 ACC:68.0000%
Validing…
valid Loss:0.5896 ACC:68.0000%
513.1176249980927
Epoch 6/9

Training…
Batch 500, Train Loss:0.5811,Train ACC: 69.0000
Batch 1000, Train Loss:0.5748,Train ACC: 70.0000
train Loss:0.5738 ACC:70.0000%
Validing…
valid Loss:0.5660 ACC:70.0000%
598.4780201911926
Epoch 7/9

Training…
Batch 500, Train Loss:0.5602,Train ACC: 70.0000
Batch 1000, Train Loss:0.5607,Train ACC: 71.0000
train Loss:0.5578 ACC:71.0000%
Validing…
valid Loss:0.5592 ACC:70.0000%
685.3335049152374
Epoch 8/9

Training…
Batch 500, Train Loss:0.5490,Train ACC: 71.0000
Batch 1000, Train Loss:0.5512,Train ACC: 71.0000
train Loss:0.5479 ACC:72.0000%
Validing…
valid Loss:0.5359 ACC:72.0000%
770.1090521812439
Epoch 9/9

Training…
Batch 500, Train Loss:0.5268,Train ACC: 73.0000
Batch 1000, Train Loss:0.5329,Train ACC: 73.0000
train Loss:0.5321 ACC:73.0000%
Validing…
valid Loss:0.5422 ACC:71.0000%
854.5065639019012

Process finished with exit code 0


你可能感兴趣的:(计算机视觉)