这篇文章是多层感知机的使用
对于这张 图的理解
比如我们的输入为[x1,x2,x3…,xn]是一个n1的矩阵
我们的隐藏层w1是一个mn的矩阵
w1 * input = m1的矩阵
加上我们的偏执b是一个m1的矩阵
最后再和w2一个1*m的矩阵
你发现做来做去都是线性变换,其实直接代入一般的数学公式也能看出来
我们算来算去都在算一个线性变化,但是我们之前已经学习过了,一个线性变换一个等式就能完成,那何必多次依据呢。
关键就在于激活函数,我们需要一个非线性的函数,来帮我们了解,一个输出不止有正类负类两种类型,还有一些其他的输出来帮助我们更好的表达一个模型。
比如sigmod函数
比如relu函数(其实relu函数不涉及指数运算,所以运算代价很小)
在理解多层感知机之前,先理解上面两幅图。
import torch
import torchvision
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter,test_iter = d2l.load_data_fashion_mnist(batch_size)
num_inputs,num_outputs,num_hiddens=784,10,256 初始化我们的一些数据
导入对应的库,并且获得相对应的数据集
- num_input表示我们输入一个向量的维度
- num_output表示我们输出的维度
- num_hidden表示是隐藏层的维数
W1 = nn.Parameter(torch.randn(num_inputs,num_hiddens,requires_grad=True))
b1 = nn.Parameter(torchi.zeros(num_hiddens,requires_grad=True))
W2 = nn.Parameter(torch.randn(num_hiddens,num_outputs,requires_grad=True))
b1 = nn.Parameter(torchi.zeros(num_outputs,requires=True))
params = [W1,b1,W2,b2]
真的不需要扯这么多犊子,其实我们所谓的线性层就是参数+bias的组合。
这里我需要好好分析一下
我们的输入是一个 256784的矩阵X,XW1,W1是一个784256的矩阵。这两个矩阵点积的物理意义是,第一行×第一列是到第一个隐藏层的映射,其实已经是一个w11x1…的过程了
loss = nn.CrossEntropyLoss()#损失函数就是一个交叉熵函数
num_epochs, lr = 10, 0.1 #定义训练的轮次和学习率
updater = torch.optim.SGD(params, lr=lr) #定义一个优化器
对于网络我发现我对深度学习是真的不懂。
output = net(input)
loss(y,output)
output.backward()
update
都是这样的四步,给我记好!
多层感知机的简单实现
net = nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),nn.Linear(256, 10))
#对于这个网络层,第一步拉平,第二步进入第一个隐藏层,使用relu函数进行算术,使用Linear
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights);#定义一个函数初始化的方案会对线性层的权重初始化
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr=lr)
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
#非常之简单
几乎不需要多花笔墨去描述这个代码