SoftMax的简洁实现
import torch
from torch import nn
from torch.mm import init
import numpy as np
import sys
sys.path.append("...")
import d2lzh_pytorch as d2l
获取和读取数据
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
定义和初始化模型
softmax回归的输出层是一个全连接层。
每个batch样本的x的size为(batch_size,1,28,28)所以应该利用view将其变为(Batch_size,784)再送入全连接层。
num_inputs = 784
num_outputs = 10
class LinearNet(nn.Module):
def __init__(self,num_inputs,num_outputs):
super(LinearNet, self).__init__()
self.linear = nn.Linear(num_inputs, num_outputs)
def forward(self,x):
y = self.linear(x.view(x.shape[0],-1))
return y
net = LinearNet(num_inputs, num_outputs)
将x展评写为一个函数
def FlattenLayer(nn.Module):
def __init__(self):
super(FlattenLayer,self).__init__()
def forward(self,x):
return x.view(x.shape[0],-1)
定义模型
from collections import OrderedDict
net = nn.Sequential(
OrderDict([
('flatten',FlattenLayer()),
('Linear',nn.linear(num_inputs,num_outputs))
])
)
初始化模型参数
init.normal_(net.linear.weight,mean = 0,std = 0.01)
init.constant_(net.linear.bias, val = 0)
SoftMax和交叉熵函数
分开进行softmax计算和交叉熵损失函数可能会造成数值不稳定。
PyTorch提供了一个包括softmax和交叉熵损失计算得函数,数值稳定性更好。
loss = CrossEntropyLoss()
定义优化算法
optimizer = torch.optim.sgd(net.parameters(),lr = 0.1)
多层感知机
隐藏层
多层感知机在单层神经网络的基础上引入了一个到若各隐藏层。
多层感知机的隐藏层和输出层都是全连接层。
虽然引入了隐藏层,但是仍可等价为一个单层网络。
激活函数
添加再多的隐藏层,也只等效为一层,因为都是线性的。
只是对数据做了仿射变换。
解决方法是以内一个非线性变换。
这个非线性函数被称为激活函数
ReLu函数
RelU(x)= max(x,0)
只保留正数元素吗,将负数元素清零。
%matplotlib inline
import torch
import numpy as np
import matplotlib.pylab as plt
import sys
sys.path.append("...")
import d2lzh_pytorch as d2l
def xyplot(x_vals,y_vals,name):
d2l.set_figsize(figsize=(5.2.5))
d2l.plt.plot(x_vals.detach().numpy(),y_vals.detach().numpy())
d2l.plt.xlabel('x')
d2l.plt.ylabel(name + '(x)')
绘制一段ReLU函数
x = torch.arange(-8.0, 8.0, 0.1, requires_grad = True)
y = x.relu()
xyplot(x,y,'relu')
绘制relu导数的函数
y.sum().backward()
#加入sum因为只能对标量求导
xyplot(x, x.grad, 'grad of relu')