用nn.Linear()等更简单地构建神经网络层

之前那个多分类问题实战

是手写了每个层

其实我们可以使用nn.Linear,就不用手写了

这里第一个参数是in,第二个参数是out,就符合我们正常的思维习惯了

 

加上激活函数的话

 

 

如果我们要实现一个自己的网络结构

不需要实现backward(),nn.Module会自动提供,pytorch的autograd包会自动实现向后求导的功能
class MLP(nn.Module): def __init__(self): super(MLP,self).__init__()
self.model = nn.Sequential( nn.Linear(784,200), nn.ReLU(inplace=True),
nn.Linear(200,200), nn.ReLU(inplace=True), nn.Linear(200,10),
nn.ReLU(inplace=True), ) def forward(self,x): x = self.model(x) return x
在训练数据的部分
net = MLP() optimizer = optim.SGD(net.parameters(), lr=learning_rate) criteon
= nn.CrossEntropyLoss() for epoch in range(epochs): for batch_idx, (data,
target) in enumerate(train_loader): data = data.view(-1, 28*28) logits =
net(data) loss = criteon(logits, target) optimizer.zero_grad() loss.backward()
# print(w1.grad.norm(), w2.grad.norm()) optimizer.step()
我们之前在 深度学习与神经网络(四)中的多分类问题实战中优化器的时候是这么写的

是把w,b的参数写成一个list

现在我们的net继承自nn.module, 会把w,b的参数自动加到nn.parameters里面

 

重写一下之前的多分类问题实战
import torch import torch.nn as nn import torch.nn.functional as F import
torch.optim as optim from torchvision import datasets, transforms
batch_size=200 learning_rate=0.01 epochs=10 train_loader =
torch.utils.data.DataLoader( datasets.MNIST('dataset', train=True,
download=True, transform=transforms.Compose([ transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,)) ])), batch_size=batch_size,
shuffle=True) test_loader = torch.utils.data.DataLoader(
datasets.MNIST('dataset', train=False, transform=transforms.Compose([
transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])),
batch_size=batch_size, shuffle=True) class MLP(nn.Module): def __init__(self):
super(MLP, self).__init__() self.model = nn.Sequential( nn.Linear(784, 200),
nn.ReLU(inplace=True), nn.Linear(200, 200), nn.ReLU(inplace=True),
nn.Linear(200, 10), nn.ReLU(inplace=True), ) def forward(self, x): x =
self.model(x) return x net = MLP() optimizer = optim.SGD(net.parameters(),
lr=learning_rate) criteon = nn.CrossEntropyLoss() for epoch in range(epochs):
for batch_idx, (data, target) in enumerate(train_loader): data = data.view(-1,
28*28) logits = net(data) loss = criteon(logits, target) optimizer.zero_grad()
loss.backward() # print(w1.grad.norm(), w2.grad.norm()) optimizer.step() if
batch_idx % 100 == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss:
{:.6f}'.format( epoch, batch_idx * len(data), len(train_loader.dataset), 100. *
batch_idx / len(train_loader), loss.item())) test_loss = 0 correct = 0 for
data, target in test_loader: data = data.view(-1, 28 * 28) logits = net(data)
test_loss += criteon(logits, target).item() pred = logits.data.max(1)[1]
correct += pred.eq(target.data).sum() test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset), 100. * correct /
len(test_loader.dataset)))

train的效果基本上是一样的

 

之前的写法我们会有初始化的问题,在这里没有

这里我们的w和b的参数已经归nn.Linear()管理了, 没有暴露给我们,我们没法直接初始化

再就是我们用它的接口的时候他有一个自己的初始化方法,就不用我们操心了

 

全连接网络的层数和结构

全连接网络也叫做线性层

计算层数,输入层是不计算的,输出层要计算

因此这个网络有4层

而如果问有多少个隐藏层就是3个了

对于某一层的话,我们一般是指这一层的权指和这一层的输出加在一起叫一层

对于第二层是指的这

 

 

这个网络是用来处理很简单的数据集——MNIST图片数据集的

MNIST数据集每张图片是有28*28个像素点,所以输入是28*28;MNIST一共有10类,因此输出是10个点

即输入是28*28的矩阵,为了方便全连接层的处理,我们把它打平成784层的向量,然后中间节点都是256个点

我们来计算一下对于这样一个网络,需要多少参数量

神经网络的参数量就是有多少条连线

784*256+256*256+256*256+256*10 = 390K

所以参数量就是390K

然后每个参数是用一个4字节的浮点数来表示,所以390k*4 = 1.6MB

所以需要1.6M的内存或显存(如果用GPU的话)

 

这个数字现在看来是很小的
但是MNIST是在80年代产生的,那时候还是386的时候
当时的处理器可能就只有几十到上百KB
对于这样一个简单的网络,它都装不进内存里面
 

 

 

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信