Pytorch系列(五):猫狗大战2-AlexNet


Pytorch猫狗大战系列:
猫狗大战1-训练和测试自己的数据集
猫狗大战2-AlexNet
猫狗大战3-MobileNet_V1&V2
猫狗大战3-MobileNet_V3


TensorFlow 2.0猫狗大战系列
猫狗大战1、制作与读取record数据
猫狗大战2、训练与保存模型


一、AlexNet介绍

AlexNet的出现,引发人工技能的浪潮.
尽管后续出现vgg, Google系列,ResNet,DenseNet等等更深更优秀的网络,但对AlexNet有着特殊的情怀.
AlexNet的网络结构
摘自 学习笔记:大话经典模型AlexNet、VGGNet、GoogLeNet、ResNet
在这里插入图片描述

二、Pytorch代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""                               *   *   *** *    * *   *
@File     :AlexNet.py             *   *    *   *  *  *   *
@Date     :5/9/20                 *   *    *    **   *   *
@Require  :pytorch                *****    *    **   *   *
@Author   :hjxu                   *   *    *    **   *   *
                                  *   * *  *   *  *  *   *
                                  *   *  ***  *    * *****
@Funtion  : AlexNet 定义
"""


import torch
import torch.nn as nn
import torchvision

class AlexNet(nn.Module):
    def __init__(self, num_classes=1000):
        super(AlexNet, self).__init__()
        self.feature_extraction = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4, padding=2, bias=False),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=0),
            nn.Conv2d(in_channels=96, out_channels=192, kernel_size=5, stride=1, padding=2, bias=False),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=0),
            nn.Conv2d(in_channels=192, out_channels=384, kernel_size=3, stride=1, padding=1, bias=False),
            nn.ReLU(inplace=True),
            nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, stride=1, padding=1, bias=False),
            nn.ReLU(inplace=True),
            nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1, bias=False),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=0),
        )
        self.classifier = nn.Sequential(
            nn.Dropout(p=0.5),
            nn.Linear(in_features=256*6*6, out_features=4096),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(in_features=4096, out_features=4096),
            nn.ReLU(inplace=True),
            nn.Linear(in_features=4096, out_features=num_classes),
        )
    def forward(self,x):
        x = self.feature_extraction(x)
        x = x.view(x.size(0), 256*6*6)
        x = self.classifier(x)
        return x



if __name__ == '__main__':
    # net = torchvision.models.AlexNet()
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    net = AlexNet()
    from torchsummary import summary
    print(summary(net, (3, 224, 224), device="cpu"))
    print("############################################")
    print(net)

    input = torch.randn(8, 3, 224, 224)

    out = net(input)
    print(out.shape)

50轮迭代,准确率0.98

训练脚本如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""                               *   *   *** *    * *   *
@File     :train.py               *   *    *   *  *  *   *
@Date     :                       *   *    *    **   *   *
@Require  :                       *****    *    **   *   *
@Author   :hjxu                   *   *    *    **   *   *
                                  *   * *  *   *  *  *   *
                                  *   *  ***  *    * *****
@Funtion  : 训练脚本
"""
from __future__ import print_function, division

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data import Dataset
from torchvision import transforms, datasets, models
from CnnNet import AlexNet

from DataLoader import DogCatDataSet
# 配置参数
random_state = 1
torch.manual_seed(random_state)  # 设置随机数种子,确保结果可重复
torch.cuda.manual_seed(random_state)
torch.cuda.manual_seed_all(random_state)
np.random.seed(random_state)
# random.seed(random_state)

epochs = 70  # 训练次数
batch_size = 32  # 批处理大小
num_workers = 4  # 多线程的数目
use_gpu = torch.cuda.is_available()

# 对加载的图像作归一化处理, 并裁剪为[224x224x3]大小的图像
data_transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),

])


train_dataset = DogCatDataSet(img_dir="./data/train", transform=data_transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4)

test_dataset = DogCatDataSet(img_dir="./data/validation", transform=data_transform)
test_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4)


# 加载resnet18 模型,
# net = SimpleCNN.MobileNetV1()
# net = models.MobileNetV2(num_classes=2)
net = AlexNet.AlexNet(num_classes=2)
# num_ftrs = net.fc.in_features

# net.fc = nn.Linear(num_ftrs, 2)  # 更新resnet18模型的fc模型,

if use_gpu:
    net = net.cuda()
print(net)

'''
Net (
  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))
  (maxpool): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear (44944 -> 2048)
  (fc2): Linear (2048 -> 512)
  (fc3): Linear (512 -> 2)
)
'''

# 定义loss和optimizer
cirterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

# 开始训练
net.train()
for epoch in range(epochs):
    if((epoch + 1) % 20 == 0):
        for param_group in optimizer.param_groups:
            lr = param_group['lr']
            param_group['lr'] = lr * 0.1
    running_loss = 0.0
    train_correct = 0
    train_total = 0
    for i, data in enumerate(train_loader, 0):
        inputs, train_labels = data
        if use_gpu:
            inputs, labels = Variable(inputs.cuda()), Variable(train_labels.cuda())
        else:
            inputs, labels = Variable(inputs), Variable(train_labels)
        # inputs, labels = Variable(inputs), Variable(train_labels)
        optimizer.zero_grad()
        outputs = net(inputs)
        _, train_predicted = torch.max(outputs.data, 1)
        # import pdb
        # pdb.set_trace()
        train_correct += (train_predicted == labels.data).sum()
        loss = cirterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        print("epoch: ",  epoch, " loss: ", loss.item())
        train_total += train_labels.size(0)

    print('train %d epoch loss: %.3f  acc: %.3f ' % (
    epoch + 1, running_loss / train_total * batch_size, 100 * train_correct / train_total))

    # 模型测试
    correct = 0
    test_loss = 0.0
    test_total = 0
    test_total = 0
    net.eval()
    for data in test_loader:
        images, labels = data
        if use_gpu:
            images, labels = Variable(images.cuda()), Variable(labels.cuda())
        else:
            images, labels = Variable(images), Variable(labels)
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        loss = cirterion(outputs, labels)
        test_loss += loss.item()
        test_total += labels.size(0)
        correct += (predicted == labels.data).sum()

    print('test  %d epoch loss: %.3f  acc: %.3f ' % (epoch + 1, test_loss / test_total * batch_size, 100 * correct / test_total))
torch.save(net, "./model/AlexNet.pth")
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值