pytorch的卷积层到第一个全连接层的参数个数如何确定?

pytorch写cnn的麻烦之处是cnn到第一个全连接层的参数不明确。可以手动计算,但太麻烦,不建议这做。下面通过代码自己计算出来参数个数。

问题:下面的的第一个全连接层的输入神经元个数是多少呢?

net = nn.Sequential(
    nn.Conv2d(1, 32, 3),nn.ReLU(),nn.MaxPool2d(2,2),
    nn.Conv2d(32, 64, 3),nn.ReLU(),nn.MaxPool2d(2,2),
#     nn.Linear(?, 4096),nn.ReLU(),
#     nn.Linear(4096,10)
)
 

 我们先不写全连接层,只写卷积层、激活层,池化层。(也就是将全连接层前面的都写好)

我们使用net(data)看看output形状,就可以知道全连接的神经元个数了。output的输出是(batch_size, out_channels,height,width)。

import torch,torchvision
import torch.nn as nn

net = nn.Sequential(
    nn.Conv2d(1, 32, 3),nn.ReLU(),nn.MaxPool2d(2,2),
    nn.Conv2d(32, 64, 3),nn.ReLU(),nn.MaxPool2d(2,2),
#     nn.Linear(?, 4096),nn.ReLU(),
#     nn.Linear(4096,10)
)

train_data = torchvision.datasets.MNIST('./data', train=True, transform=torchvision.transforms.ToTensor())
train_loader = torch.utils.data.DataLoader(train_data, batch_size=128, shuffle=True)

for data, target in train_loader:
    output = net(data)
    print(output.size())
    break

输出结果:

由输出结果可得,第一次的全连接输入神经元的个数为64*5*5.。即nn.Linear(64*5*5, 4096).

下面选看:

下面是完整的cnn识别mnist的代码,在全连接层前面加上nn.Flatten()可以将参数拉成(batch_size, ?)

import torch,torchvision
import torch.nn as nn

#构建模型
net = nn.Sequential(
    nn.Conv2d(1, 32, 3),nn.ReLU(),nn.MaxPool2d(2,2),
    nn.Conv2d(32, 64, 3),nn.ReLU(),nn.MaxPool2d(2,2),
    
    #nn.Flatten(会将参数拉成二维,即(batch_size, ?))
    nn.Flatten(),
    nn.Linear(64*5*5, 4096),nn.ReLU(),
    nn.Linear(4096,10)
)

train_data = torchvision.datasets.MNIST('./data', train=True, transform=torchvision.transforms.ToTensor())
train_loader = torch.utils.data.DataLoader(train_data, batch_size=128, shuffle=True)

criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)

device = torch.device('cuda'if torch.cuda.is_available() else 'cpu')
net = net.to(device)
print('training on: ',device)
for epoch in range(10):
    print('epoch:%d'%epoch)
    acc = 0.0
    sum = 0.0
    loss_sum = 0
    for batch, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = net(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        
        acc+=torch.sum(torch.argmax(output,dim=1)==target).cpu().item()
        sum+=len(target)
        loss_sum+=loss
        if batch%100==0:
            print('\tbatch: %d, loss: %.4f'%(batch, loss))
    print('epoch: %d, acc: %.2f%%, loss: %.4f'%(epoch, 100*acc/sum, loss_sum/len(train_loader)))

 结果图:

 

好的,我来为您介绍如何定义一个包含3x3卷积层全连接层和ReLU激活函数的CNN模型。这个模型包含以下主要组件: 1. 3x3卷积层,输出通道数为16 2. ReLU激活函数 3. 全连接层,输出节点数为10 4. 全连接层,输出节点数为512 5. ReLU激活函数 下面是一个使用PyTorch框架定义这个CNN模型的示例代码: ```python import torch.nn as nn import torch.nn.functional as F class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() # 3x3卷积层,输出通道数为16 self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, padding=1) # 全连接层,输出节点数为512 self.fc1 = nn.Linear(16 * 32 * 32, 512) # 全连接层,输出节点数为10 self.fc2 = nn.Linear(512, 10) def forward(self, x): # 卷积层 x = self.conv1(x) x = F.relu(x) # 展平 x = x.view(x.size(0), -1) # 全连接层和ReLU x = self.fc1(x) x = F.relu(x) # 第二个全连接层 x = self.fc2(x) return x ``` 解释: 1. 我们定义了一个名为SimpleCNN的类,继承自nn.Module。 2. 在__init__方法中,我们定义了两个全连接层(self.fc1和self.fc2)和一个卷积层(self.conv1)。 3. 卷积层参数: - in_channels=3: 输入图像为RGB,通道数为3 - out_channels=16: 输出通道数为16 - kernel_size=3: 卷积核大小为3x3 - padding=1: 为了保持输入和输出的尺寸一致,使用padding 4. 第一个全连接层(self.fc1)将展平后的特征图映射到512维。 5. 第二个全连接层(self.fc2)将512维的特征向量映射到10维输出。 6. 在forward方法中,我们定义了数据的传播过程: - 首先通过卷积层 - 然后使用ReLU激活函数 - 接着将特征图展平 - 通过第一个全连接层和ReLU - 最后通过第二个全连接层 注意,在这个实现中,我们假设输入图像的尺寸为32x32。如果您的输入图像尺寸不同,可能需要调整第一个全连接层的输入特征数。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

圣诞节不感冒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值