深度学习与神经网络(五)——全连接层(nn.Linear())

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

之前那个多分类问题实战

是手写了每个层

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

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

输入的nn.Linear(in_features, out_features) 的in和out实际上是w和b的维度

 

 

加上激活函数的话

 

 

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

不需要实现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
对于这样一个简单的网络,它都装不进内存里面
 

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值