pytorch实现Inception网络并绘制loss图片(MNIST为例)

参考博客-zhiguo98
个人体会:Inception块需要卷积核与池化层保证same.多个分支才能拼接成同样大小的块,区别是各个分支的通道数不同,最后由反向传递自己选择哪一个分支作为中间层.

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt


transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,),(0.3081,))

])

train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)

train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=True)


# 构建Inception模型
class MyInception(nn.Module):
    def __init__(self, in_channels):
        super(MyInception, self).__init__()
        # 以下所有卷积核以及池化层都是same操作
        # 第一个分支 (1,28,28)
        self.branch1 = nn.Conv2d(
            in_channels=in_channels,
            out_channels=16,
            kernel_size=1
        )

        # 第二个分支
        self.branch2 = nn.Sequential(
            nn.Conv2d(
                in_channels=in_channels,
                out_channels=16,
                kernel_size=1
            ),
            nn.Conv2d(
                in_channels=16,
                out_channels=24,
                kernel_size=5,
                padding=2
            )
        )

        # 第三个分支
        self.branch3 = nn.Sequential(
            nn.Conv2d(
                in_channels=in_channels,
                out_channels=16,
                kernel_size=1
            ),
            nn.Conv2d(
                in_channels=16,
                out_channels=24,
                kernel_size=3,
                padding=1
            ),
            nn.Conv2d(
                in_channels=24,
                out_channels=24,
                kernel_size=3,
                padding=1
            )
        )

        # 第四部分
        # self.branch4 = nn.Conv2d(in_channels, 24, kernel_size=1)
        self.branch4 = nn.Sequential(
            nn.AvgPool2d(
                kernel_size=3,
                stride=1,
                padding=1
            ),
            nn.Conv2d(
                in_channels=in_channels,
                out_channels=24,
                kernel_size=1
            )
        )

    def forward(self, x):
        b1 = self.branch1(x)
        b2 = self.branch2(x)
        b3 = self.branch3(x)
        # same池化
        # branch_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1)
        b4 = self.branch4(x)
        output = [b1, b2, b3, b4]
        return torch.cat(output, dim=1)


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.incep1 = MyInception(in_channels=10)
        self.conv2 = nn.Conv2d(88, 20, kernel_size=5)
        self.incep2 = MyInception(in_channels=20)

        self.mp = nn.MaxPool2d(2)
        self.fc = nn.Linear(1408, 10)

    def forward(self, x):
        batch_size = x.size(0)
        x = self.mp(F.relu(self.conv1(x)))  # (1,28,28)->(10,24,24)->(10,12,12)
        x = self.incep1(x)  # (10,12,12)->(88,12,12)
        x = self.mp(F.relu(self.conv2(x)))  # (88,12,12) -> (20,8,8) -> (20,4,4)
        x = self.incep2(x)  # (20,4,4) -> (88,4,4)
        x = x.view(batch_size, -1)  # (batch_size,84*4*4)
        x = self.fc(x)
        return x


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

# 损失函数
loss_func = nn.CrossEntropyLoss()
# 优化器
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3, momentum=0.5)

costs = []

# 训练网络
def train(epoch):
    batch_loss = 0
    for step, (data) in enumerate(train_loader):
        inputs, labels = data
        if torch.cuda.is_available():
            inputs = inputs.cuda()
            labels = labels.cuda()
        optimizer.zero_grad()
        output = model(inputs)
        loss = loss_func(output, labels)
        loss.backward()
        optimizer.step()
        costs.append(loss)
        batch_loss += loss.item()

        if step % 300 == 299:
            print(f'epoch:{epoch},step:{step + 1},mini_loss:{batch_loss / 300:.3f}')
            batch_loss = 0


# 测试网络
def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            inputs, labels = data
            if torch.cuda.is_available():
                inputs = inputs.cuda()
                labels = labels.cuda()
            output = model(inputs)
            _, predicted = torch.max(output, dim=1)
            total += labels.size(0)
            correct += (predicted == labels).sum()
    print(f'测试集上的准确率为:{correct / total * 100:.3f}%')


if __name__ == '__main__':
    for epoch in range(3):
        train(epoch)
        test()
    # 绘制图片:此时的costs里面的数据是tensor类型,如果是gpu上跑的就是cuda,需要将他转换成array
    print(costs)
    if torch.cuda.is_available():
        costs = [cost.cpu().detach().numpy() for cost in costs]
    else:
        costs = [cost.numpy() for cost in costs]
    print(costs)
    plt.plot(costs)
    plt.xlabel('number of iteration')
    plt.ylabel('loss')
    plt.title('Inception Net')
    plt.show()

图片:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch 是一个广泛使用的深度学习框架,支持建立卷积神经网络(Convolutional Neural Network,CNN)模型。以下是一个简单的 PyTorch CNN 模型的示例代码: ``` python import torch import torch.nn as nn import torch.optim as optim import torchvision.datasets as datasets import torchvision.transforms as transforms # 定义 CNN 模型 class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=5, padding=2) self.relu1 = nn.ReLU() self.pool1 = nn.MaxPool2d(kernel_size=2) self.conv2 = nn.Conv2d(16, 32, kernel_size=5, padding=2) self.relu2 = nn.ReLU() self.pool2 = nn.MaxPool2d(kernel_size=2) self.fc1 = nn.Linear(32 * 8 * 8, 10) def forward(self, x): x = self.conv1(x) x = self.relu1(x) x = self.pool1(x) x = self.conv2(x) x = self.relu2(x) x = self.pool2(x) x = x.view(-1, 32 * 8 * 8) x = self.fc1(x) return x # 加载 CIFAR10 数据集 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True) # 训练模型 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') net = CNN().to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) for epoch in range(10): running_loss = 0.0 for i, data in enumerate(trainloader, 0): inputs, labels = data[0].to(device), data[1].to(device) optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if i % 100 == 99: print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100)) running_loss = 0.0 print('Finished Training') ``` 在这个示例代码中,定义了一个简单的 CNN 模型,包含两个卷积层和两个池化层,最后连接一个全连接层。模型的训练部分则使用了 CIFAR10 数据集,使用交叉熵损失函数和随机梯度下降(SGD)优化器进行训练。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值