关于利用pytorch复现alexnet网络并实现对MNIST数据及分类

一、alexnet网络结构

(一)图解

(二)网络各层参数

  • 1.AlexNet共8层,包括5个卷积层和3个全连接层
  • 2.每一层都使用了Relu函数作为激活函数
  • 3.AlexNet有一个特殊的计算层-LRN层,开辟性的使用了LRN(局部相应归一化层

二、alexnet优点

1.用ReLU得到非线性,用ReLU非线性函数作为激活函数
2.使用dropout的trick在训练期间有选择性的忽略隐藏层神经元,来减缓学习模型的过拟合
3.使用重叠最大池进行池化操作,避免平均池的平均效果
4.使用GPU可以减少训练时间,这比CPU处理快了10倍,所以可以被用于更大的数据集和图像上。

三、各层的相关计算

Layer1:Conv-> Relu->pooling->LRN

  1. input: 224*244*3
  2. 卷积核大小: 11*11*3*96个
  3. stride = 4
  4. group = 2:这个属性强行把前面的结果fecture map分开,卷积部分分成两个部分做
  5. 池化层窗口大小: 3*3,stride =2
  6. 卷积后output: 55*55*96
  7. 池化后output:27*27*96

Layer2:Conv-> Relu->pooling->LRN

  1. input: 27*27*96
  2. 卷积核大小: 5*5*96*256个
  3. stride = 1,padding=2
  4. 池化层窗口大小: 3*3*256,stride =2
  5. 卷积后output: 27*27*256
  6. 池化后output:13*13*256

Layer3:Conv->LRN

  1. input:13*13*256
  2. 卷积核:3*3*256*384个
  3. stride=1;padding=1
  4. output:13*13*384

Layer4:Conv->LRN

  1. input:13*13*384
  2. 卷积核:3*3*384个
  3. stride=1;padding=1
  4. output:13*13*384

Layer5: Conv->Relu->pooling->dropout

  1. input:13*13*384
  2. 卷积核:3*3*256
  3. stride=1;padding=1
  4. 池化层窗口:stride=2
  5. 卷积后output:13*13*256
  6. 池化后output:6*6*256

Layer6: 全连接层>Relu->dropout

  1. input:6*6*256
  2. 该层有4096个卷积核,每个卷积核的大小为6*6*256.由于卷积核的尺寸刚好与待处理的特征图(输入)尺寸相同,即卷积核中的每个系数与特征图(输入)尺寸的一个像素值相乘,一一对应, 因此,该层被称为全连接层。由于卷积核与特征图的尺寸相同,卷积运算后就只有一一个值,因此,卷积后的像素尺寸为4096*1*1,即有4096个神经元。

Layer7: 全连接层>Relu->dropout

Layer8: 全连接层-Relu

四、代码实现

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

class Alexnet(nn.Module):
    def __init__(self):
        super(Alexnet, self).__init__()
        self.conv1 = nn.Conv2d(3, 96,11,4,0)
        self.pool = nn.MaxPool2d(3, 2)
        self.conv2 = nn.Conv2d(96, 256, 5, 1, 2)
        self.Conv3 = nn.Conv2d(256, 384, 3, 1, 1)
        self.Conv4 = nn.Conv2d(384,384, 3, 1, 1)
        self.Conv5 = nn.Conv2d(384,256, 3, 1, 1)
        self.drop = nn.Dropout(0.5)
        self.fc1 = nn.Linear(9216, 4096)
        self.fc2 = nn.Linear(4096, 4096)
        self.fc3 = nn.Linear(4096, 100)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = F.relu(self.conv3(x))
        x = F.relu(self.conv4(x))
        x = self.pool(F.relu(self.conv5(x)))
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = self.drop(F.relu(self.fc1(x)))
        x = self.drop(F.relu(self.fc2(x)))
        x = self.fc3(x)
        return x

net = Alexnet()
print(net)

五、应用于mnist数据集

(一)引入包

import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision
import torch.nn.functional as F

(二)配置参数

torch.manual_seed(1)
batch_size = 64
learning_rate = 1e-2
num_epoches = 100

(三)数据预处理

# 下载数据集
train_data = torchvision.datasets.MNIST(
    root='./data/',  # 保存或提取的位置
    train=True,  # true说明是用于训练的数据,false说明是用于测试的数据
    transform=torchvision.transforms.ToTensor(),  # #转换成PIL.Image or numpy.ndarray
    download=False

)
test_data = torchvision.datasets.MNIST(
    root='./data',
    train=False,  # 表明是测试集
    transform=torchvision.transforms.ToTensor()
)
# 批训练50个samples,1 channel,28*28(50,1,28,28)
# torch中DataLoader是包装数据的工具,能够帮我们有效迭代数据,这样就可以批训练
train_loader = Data.DataLoader(
    dataset=train_data,
    batch_size=batch_size,
    shuffle=True,  # 是否打乱数据,一般都打乱

)
test_loader = Data.DataLoader(
    dataset=test_data,
    batch_size=batch_size,
    shuffle=True,  # 是否打乱数据,一般都打乱

)

(四)网络

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1,32,3,1,1)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(32, 64, 3, 1, 1)
        self.conv3 = nn.Conv2d(64, 128, 3, 1, 1)
        self.conv4 = nn.Conv2d(128,256, 3, 1, 1)
        self.conv5 = nn.Conv2d(256,256, 3, 1, 1)
        self.pool2 = nn.MaxPool2d(3, 2)
        self.drop = nn.Dropout(0.5)
        self.fc1 = nn.Linear(256*3*3, 1024)
        self.fc2 = nn.Linear(1024, 512)
        self.fc3 = nn.Linear(512, 10)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool1(F.relu(self.conv2(x)))
        x = F.relu(self.conv3(x))
        x = F.relu(self.conv4(x))
        x = self.pool2(F.relu(self.conv5(x)))
        x = x.view(-1,256*3*3)
        x = F.relu(self.fc1(x))
        x = self.drop(F.relu(self.fc1(x)))
        x = self.drop(F.relu(self.fc2(x)))
        x = self.fc3(x)
        return x
net = Net()

model = Net()

(五)训练

# 定义loss和optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 开始训练

for i, data in enumerate(train_loader, 1):
    img, label = data
    img = torch.autograd.Variable(img)
    label = torch.autograd.Variable(label)
print(label.size(0))

#开始训练

for epoch in range (num_epoches) :
    running_loss = 0.0
    running_acc= 0.0
    for i,data in enumerate(train_loader, 1):
        img,label = data
        img = torch.autograd.Variable(img)
        label = torch.autograd.Variable(label)
        out = model (img)
        loss = criterion(out, label) # loss
        a = loss.item() * label.size(0)
        running_loss=running_loss+a
        _,pred=torch.max(out,1)
        num_correct=(pred==label).sum()
        accuracy = (pred == label).float().mean()
        b= num_correct.item()
        running_acc=running_acc+b
        #后向传
        optimizer.zero_grad()
        loss.backward() #后向传播,计算梯度
        optimizer.step() #利用梯度更新W、b参数
    # #打印一个循环后,训练集合上的loss和正确率
    print('Train {} epoch, Loss:{:.6f}, Acс:{:.6f}'.format(epoch + 1,running_loss/(len(train_data)),running_acc / (len(train_data))))

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常好的问题!我可以回答这个问题。对于mnist数据集分类问题,我们可以使用卷积神经网络(CNN)来解决。在PyTorch实现CNN非常简单,你只需要按照以下步骤: 1. 导入需要的库和模块 ``` import torch import torch.nn as nn import torch.nn.functional as F ``` 2. 定义CNN模型 ``` class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5) self.pool = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5) self.fc1 = nn.Linear(in_features=16 * 4 * 4, out_features=120) self.fc2 = nn.Linear(in_features=120, out_features=84) self.fc3 = nn.Linear(in_features=84, out_features=10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 16 * 4 * 4) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x ``` 这里我们定义了一个简单的CNN模型,包括两个卷积层和三个全连接层。我们使用ReLU作为激活函数,并在卷积层之间使用max-pooling来减小输出尺寸。 3. 加载mnist数据集 ``` trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transforms.ToTensor()) trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, num_workers=2) ``` 这里我们使用torchvision库来加载mnist数据集,并使用transforms.ToTensor()将数据转换为PyTorch张量。我们还使用DataLoader来生成批数据,以便进行批量训练。 4. 定义优化器和损失函数 ``` net = Net() criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9) ``` 我们使用交叉熵损失作为损失函数,并使用随机梯度下降(SGD)作为优化器。 5. 训练网络 ``` for epoch in range(10): # loop over the dataset multiple times running_loss = 0.0 for i, data in enumerate(trainloader, 0): # get the inputs; data is a list of [inputs, labels] inputs, labels = data # zero the parameter gradients optimizer.zero_grad() # forward + backward + optimize outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() # print statistics running_loss += loss.item() if i % 2000 == 1999: # print every 2000 mini-batches print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000)) running_loss = 0.0 print('Finished Training') ``` 这里我们使用PyTorch的自动微分来计算梯度,并调用优化器更新权重。我们通过训练数据多次迭代来训练网络。 6. 测试网络 ``` correct = 0 total = 0 with torch.no_grad(): for data in testloader: images, labels = data outputs = net(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the network on the 10000 test images: %d %%' % ( 100 * correct / total)) ``` 这里我们使用测试数据集来测试训练过的神经网络的准确度。 希望这个回答能帮到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值