AlexNet实战

前言:之前学了挺多卷积神经网络模型,但是都只停留在概念。代码都没自己敲过,肯定不行,而且这代码也很难很多都看不懂。所以想着先从最先较简单的AlexNet开始敲。不过还是好多没搞明白,之后逐一搞清楚。

AlexNet 实战

image-20230701100109370

  • The first convolutional layer filters the 224 × 224 × 3 input image with 96 kernels of size 11 × 11 × 3 with a stride of 4 pixels (this is the distance between the receptive field centers of neighboring neurons in a kernel map).

  • 第一个卷积层用96个大小为11 × 11 × 3的核对224 × 224 × 3输入图像进行过滤,步幅为4像素(这是核图中相邻神经元的感受野中心之间的距离)。

  • The second convolutional layer takes as input the (response-normalized and pooled) output of the first convolutional layer and filters it with 256 kernels of size 5 × 5 × 48.

  • 第二个卷积层将第一个卷积层的(响应归一化和池化)输出作为输入,并用 256 个大小为 5 × 5 × 48 的内核对其进行过滤。

  • The third, fourth, and fifth convolutional layers are connected to one another without any intervening pooling or normalization layers.

  • 第三个、第四个和第五个卷积层相互连接,没有任何中间池化或归一化层。

  • The third convolutional layer has 384 kernels of size 3 × 3 × 256

  • 第三个卷积层有384个大小为3 × 3 × 256的核

  • The fourth convolutional layer has 384 kernels of size 3 × 3 × 192, and the fifth convolutional layer has 256 kernels of size 3 × 3 × 192. The fully connected layers have 4096 neurons each.

  • 第四卷积层有384个大小为3 × 3 × 192的核,第五卷积层有256个大小为3 × 3 × 192的核。全连接层各有4096个神经元。

  • This is what we use throughout our network, with s = 2 and z = 3.

  • 这是我们在整个网络中使用的,s = 2 和 z = 3。(即池化层,stride=2,kernel_size = 3)

Alex.net

搭建AlexNet就按照论文中的一步一步搭

import torch
from torch import nn
import torch.nn.functional as F

class MyAlexNet(nn.Module):
    def __init__(self):
        super(MyAlexNet,self).__init__()
        ## input [3,224,224]
        self.c1 = nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4,padding=2) ##output [96,55,55]
        self.s1 = nn.MaxPool2d(kernel_size=3, stride=2) ##output [96,27,27]
        self.Relu = nn.ReLU()


        self.c2 = nn.Conv2d(in_channels=96,out_channels=256,kernel_size=5,padding=2) ##output [256,27,27]
        self.s2 = nn.MaxPool2d(kernel_size=3, stride=2) ##output [256,13,13]
        self.c3 = nn.Conv2d(in_channels=256,out_channels=384,kernel_size=3,padding=1) ##output [384,13,13]

        self.c4 = nn.Conv2d(in_channels=384,out_channels=384,kernel_size=3,padding=1) ##output [384,13,13]

        self.c5 = nn.Conv2d(in_channels=384,out_channels=256,kernel_size=3,padding=1) ##output [256,13,13]
        self.s5 = nn.MaxPool2d(kernel_size=3, stride=2) ##output [256,6,6]

        self.flatten = nn.Flatten()
        self.f6 = nn.Linear(256*6*6,4096)
        self.f7 = nn.Linear(4096,4096)
        self.f8 = nn.Linear(4096,2) 

    def forward(self,x):
        x = self.Relu(self.c1(x))
        x = self.s1(x)
        x = self.Relu(self.c2(x))
        x = self.s2(x)
        x = self.Relu(self.c3(x))
        x = self.Relu(self.c4(x))
        x = self.Relu(self.c5(x))
        x = self.s5(x)
        x = self.flatten(x)
        x = self.f6(x)
        x = F.dropout(x,p=0.5)
        x = self.f7(x)
        x = F.dropout(x,p=0.5)
        x = self.f8(x)
        return x
if __name__ == '__main__':
    x = torch.rand([1,3,224,224])
    model = MyAlexNet()
    y = model(x)
train.py
import torch
from torch import nn
from net import MyAlexNet
import numpy as np
from torch.optim import lr_scheduler
import os

from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

##解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

Root_train = r"F:/python/AlexNet/data/train"
Root_test = r"F:/python/AlexNet/data/val"

normalize = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])

train_transform = transforms.Compose([
    transforms.Resize((224,224)),
    transforms.RandomVerticalFlip(),##数据增强
    transforms.ToTensor(),#转换为张量
    normalize
])

val_transform = transforms.Compose([
    transforms.Resize((224,224)),
    transforms.ToTensor(),#转换为张量
    normalize
])

train_dataset = ImageFolder(Root_train,transform=train_transform)
val_dataset = ImageFolder(Root_test,transform=val_transform)

train_dataloader = DataLoader(train_dataset,batch_size=32,shuffle=True)
val_dataloader = DataLoader(val_dataset,batch_size=32,shuffle=True) ##分批次,打乱


device = 'cuda' if torch.cuda.is_available else 'cpu'
model = MyAlexNet().to(device) 

##定义损失函数
loss_fn = nn.CrossEntropyLoss()

##定义优化器
optimizer = torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.9)

##学习率每隔10轮变为原来的0.5
lr_scheduler = lr_scheduler.StepLR(optimizer,step_size=10,gamma=0.5)

##定义训练函数
def train(dataloader,model,loss_fn,optimizer):
    loss, current, n = 0.0, 0.0, 0
    for batch,(x,y) in enumerate(dataloader):
        image ,y = x.to(device), y.to(device)
        output = model(image)
        cur_loss = loss_fn(output,y)
        _, pred = torch.max(output,axis=1)
        cur_acc = torch.sum(y==pred)/output.shape[0]

        ##反向传播
        optimizer.zero_grad()
        cur_loss.backward()
        optimizer.step()
        loss +=cur_loss.item()
        current +=cur_acc.item()
        n += 1
    train_loss = loss / n
    train_acc = current / n
    print("train_loss" + str(train_loss))
    print("train_acc" + str(train_acc))
    return train_loss, train_acc

##定义验证函数
def val(dataloader,model,loss_fn):
    model.eval()
    loss, current, n = 0.0, 0.0, 0
    with torch.no_grad():
        for batch,(x,y) in enumerate(dataloader):
            image ,y = x.to(device), y.to(device)
            output = model(image)
            cur_loss = loss_fn(output,y)
            _, pred = torch.max(output,axis=1)
            cur_acc = torch.sum(y==pred)/output.shape[0]
            loss += cur_loss.item()
            current += cur_acc.item()
            n += 1
    val_loss = loss / n
    val_acc = current / n
    print("val_loss" + str(val_loss))
    print("val_acc" + str(val_acc))
    return val_loss, val_acc

##定义画图函数
def matplot_loss(train_loss,val_loss):
    plt.plot(train_loss,label='train_loss')
    plt.plot(val_loss,label="val_loss")
    plt.legend(loc='best')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.title("训练集和验证集loss值对比")
    plt.show()

def matplot_acc(train_loss,val_loss):
    plt.plot(train_loss,label='train_acc')
    plt.plot(val_loss,label="val_acc")
    plt.legend(loc='best')
    plt.ylabel('acc')
    plt.xlabel('epoch')
    plt.title("训练集和验证集acc值对 比")
    plt.show()


##开始训练
loss_train = []
acc_train = []
loss_val = []
acc_val = []

epoch = 20
min_acc = 0
for t in range(epoch):
    lr_scheduler.step()
    print(f"epoch{t+1}\n-----------")
    train_loss,train_acc = train(train_dataloader,model,loss_fn,optimizer)
    val_loss,val_acc = val(val_dataloader,model,loss_fn)

    loss_train.append(train_loss)
    acc_train.append(train_acc)
    loss_val.append(val_loss)
    acc_val.append(val_acc)

    ##保存最好的模型权重
    if val_acc > min_acc:
        folder='save_model'
        if not os.path.exists(folder):
            os.mkdir('save_model')
        min_acc = val_acc
        print(f"save bset model,第{t+1}轮")  
        torch.save(model.state_dict(),'save_model/best_model.pth')

    ##保存最后一轮的权重文件
    if t == epoch-1:
        torch.save(model.state_dict(),'save_model/last_model.pth')
matplot_loss(loss_train,loss_val)
matplot_acc(acc_train,acc_val)
print("Done")

image-20230701193450668

image-20230701193455621

test.py
import torch
from net import MyAlexNet
from torch.autograd import Variable
from torchvision import datasets, transforms
from torchvision.transforms import ToTensor
from torchvision.transforms import ToPILImage
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader



Root_train = r"F:/python/AlexNet/data/train"
Root_test = r"F:/python/AlexNet/data/val"

normalize = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])

train_transform = transforms.Compose([
    transforms.Resize((224,224)),
    transforms.RandomVerticalFlip(),##数据增强
    transforms.ToTensor(),#转换为张量
    normalize
])

val_transform = transforms.Compose([
    transforms.Resize((224,224)),
    transforms.ToTensor(),#转换为张量
    normalize
])

train_dataset = ImageFolder(Root_train,transform=train_transform)
val_dataset = ImageFolder(Root_test,transform=val_transform)

train_dataloader = DataLoader(train_dataset,batch_size=32,shuffle=True)
val_dataloader = DataLoader(val_dataset,batch_size=32,shuffle=True) ##分批次,打乱


device = 'cuda' if torch.cuda.is_available else 'cpu'
model = MyAlexNet().to(device) 

## 加载模型
model.load_state_dict(torch.load("F:/python/AlexNet/save_model/best_model.pth"))

classes = [
    "cat",
    "dog",
]

##把张量转为照片格式
show = ToPILImage()

##进入验证阶段
model.eval()
for i in range(50):
    x, y = val_dataset[i][0],val_dataset[i][1]
    show(x).show()
    x = Variable(torch.unsqueeze(x,dim=0).float(),requires_grad=True).to(device)
    x = torch.tensor(x).to(device)
    with torch.no_grad():
        pred = model(x)
        predicted,actual = classes[torch.argmax(pred[0])],classes[y]
        print(f'predicted:"{predicted}",Actual:"{actual}"')

image-20230701184444246

如果归一化的话,就会出现这种效果,但是如果把normalize = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])去掉就能显示正常图片

### 回答1: AlexNet是一种非常著名的卷积神经网络,在Imagenet项目中取得了重大的突破。Imagenet项目是一个图像分类的竞赛,要求参赛者使用机器学习算法对大规模的图像数据集进行分类。 AlexNet是由Alex Krizhevsky等人在2012年开发的。它是一个8层的深度卷积神经网络模型。AlexNet通过多层卷积、池化和非线性操作来提取图像特征,并使用全连接层和softmax分类器对图像进行分类。该网络使用大量的参数和多层卷积能够更好地捕捉图像中的细节和复杂特征,极大地提高了图像分类的准确性。 在Imagenet项目中,AlexNet在2012年的竞赛中取得了显著的成功。AlexNet在图像分类任务上的表现远远超过了之前所有的模型,将错误率降低了近15%。它引入了ReLU激活函数、Dropout正则化和局部响应归一化等创新技术,这些技术在后续的深度学习模型中得到了广泛应用。 AlexNet的成功不仅极大地推动了深度学习的发展,也彻底改变了图像处理领域。它的创新设计和优秀性能为后续的神经网络提供了指导和灵感。自此,深度学习在图像分类、目标检测和语义分割等任务中都取得了重大突破。 总之,AlexNet在Imagenet项目中的实战应用不仅为图像分类任务带来了巨大的进步,也促进了深度学习的发展。该网络的设计和性能表现成为了后续神经网络模型的基础,对于改善图像处理任务的准确性和效率起到了至关重要的作用。 ### 回答2: AlexNet是一个卷积神经网络架构,它在2012年的ImageNet挑战赛中大获成功。ImageNet是一个大型的图像分类数据集,包含来自1000个不同类别的120万个高分辨率图像。 AlexNet的架构由8个卷积层、5个最大池化层、3个全连接层和一个softmax输出层组成。它引入了ReLU(修正线性单元)作为激活函数,这一激活函数相较于传统的sigmoid和tanh函数,在训练过程中可以更好地避免梯度消失问题。 在ImageNet比赛中,AlexNet表现出色,将错误率降低到当年最低的15.3%。它在计算机视觉领域的影响不可忽视,对于深度学习的普及和发展起到了重要作用。 想要进行AlexNet实战,首先需要下载和准备ImageNet数据集。然后,可以使用深度学习框架(如TensorFlow、PyTorch等)搭建AlexNet模型,并加载ImageNet的预训练权重。接下来,可以对模型进行训练和微调,以适应应用的特定数据集和任务。 在实战过程中,可以使用训练集进行模型的训练,并利用验证集来评估模型的性能。根据性能评估的结果,可以调整模型的超参数或进行进一步的训练。最后,可以使用测试集来评估模型的泛化能力和准确性。 通过AlexNet实战项目,我们可以深入了解卷积神经网络的原理和应用,掌握深度学习框架的使用技巧,并对计算机视觉领域的图像分类任务有更深入的理解。这对于从事相关研究、开发或工程实践都是非常有益的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值