Deep Learning with Pytorch 中文简明笔记 第六章 Using a neural network to fit the data
Deep Learning with Pytorch 中文简明笔记 第六章 Using a neural network to fit the data
Pytorch作为深度学习框架的后起之秀,凭借其简单的API和简洁的文档,收到了越来越多人的关注和喜爱。本文主要总结了 Deep Learning with Pytorch 一书第六章[Using a neural network to fit the data]的主要内容,并加以简单明了的解释,作为自己的学习记录,也供大家学习和参考。
文章目录
主要内容
- 非线性激活函数
- 使用Pytorch的nn模型
- 使用神经网络解决线性拟合问题
1. 人工神经单元
复杂函数的最基本的单元是神经单元
复杂函数就是多个神经单元的连接,最后展现出的形式就是函数的多层嵌套
深度学习中最简单的单元是线性操作+非线性激活函数,非线性激活函数的主要作用为
- 在模型内部,它允许输出函数在不同的值处具有不同的斜率
- 在模型最后,它具有将先前线性运算的输出集中到给定范围的作用
激活函数的类型很多,如
一般而言,激活函数是非线性且可微分的。并且激活函数有一段敏感区间,在这段区间中函数值的变化较为剧烈,同样也有一段不敏感区间,这段区间中函数值的变换较为缓和甚至几乎没有变化。
而对于参数学习而言,可以理解为调整非线性激活函数的offset和scale,使得更好的拟合数据。
2. Pytorch的nn模块
PyTorch具有专用于神经网络的子模块,叫做torch.nn模块。它包括了构建神经网络所需要的各种基本块。当模型需要一个列表或者一个字典组成的子模型时,PyTorch提供了nn.ModuleList和nn.ModuleDict。
PyToch对其子类nn.Module定义好了__call__()方法,使得其可以作为实例而调用。
# In[5]:
import torch.nn as nn
linear_model = nn.Linear(1, 1)
linear_model(t_un_val)
# Out[5]:
tensor([[0.6018], [0.2877]], grad_fn=<AddmmBackward>)
当对模型传入参数(数据)时,会调用模型的forward(),并且向其传入相同的参数。因此,不需要手动调用forward()函数。
y = model(x) # 正确
y = model.forward(x) # 错误
刚才使用到的线性模型nn.Linear,接受三个参数,分别为输入特征大小,输出特征大小和是否包含偏置项(默认为True)。我们可以使用weight和bias这两个属性来查看模型的参数详情。
# In[6]:
linear_model.weight
# Out[6]:
Parameter containing:
tensor([[-0.0674]], requires_grad=True)
# In[7]:
linear_model.bias
# Out[7]:
Parameter containing: tensor([0.7488], requires_grad=True)
按照刚才的方法传入参数,可以得到经过网络的结果。
# In[8]:
x = torch.ones(1) linear_model(x)
# Out[8]:
tensor([0.6814], grad_fn=<AddBackward0>)
如果需要传入一个batch的数据,则构成一个列向量输入进网络。
# In[9]:
x = torch.ones(10, 1)
linear_model(x)
下面使用这种方法定义模型和优化器,并使用nn.Module.parameters()方法访问模型参数
# In[10]:
linear_model = nn.Linear(1, 1)
optimizer = optim.SGD( linear_model.parameters(), lr=1e-2)
# In[11]:
linear_model.parameters()
# Out[11]:
<generator object Module.parameters at 0x7f94b4a8a750>
# In[12]:
list(linear_model.parameters())
# Out[12]:
[Parameter containing: tensor([[0.7398]], requires_grad=True), Parameter containing: tensor([0.7974], requires_grad=True)]
然后定义训练的loop
# In[13]:
def training_loop(n_epochs, optimizer, model, loss_fn, t_u_train, t_u_val, t_c_train, t_c_val):
for epoch in range(1, n_epochs + 1):
t_p_train = model(t_u_train)
loss_train = loss_fn(t_p_train, t_c_train)
t_p_val = model(t_u_val)
loss_val = loss_fn(t_p_val, t_c_val)
optimizer.zero_grad()
loss_train.backward()
optimizer.step()
if epoch == 1 or epoch % 1000 == 0:
print(f"Epoch {epoch}, Training loss {loss_train.item():.4f}," f" Validation loss {loss_val.item():.4f}")
对于损失函数,Pytorch也封装了MSELoss,不再需要手写损失函数了
# In[15]:
linear_model = nn.Linear(1, 1)
optimizer = optim.SGD(linear_model.parameters(), lr=1e-2)
training_loop( n_epochs = 3000, optimizer = optimizer, model = linear_model, loss_fn = nn.MSELoss(), t_u_train = t_un_train, t_u_val = t_un_val, t_c_train = t_c_train, t_c_val = t_c_val)
3. 最终的神经网络
我们在原来线性神经网络的基础上,加入激活函数
# In[16]:
seq_model = nn.Sequential( nn.Linear(1, 13), nn.Tanh(), nn.Linear(13, 1))
seq_model
# Out[16]:
Sequential(
(0): Linear(in_features=1, out_features=13, bias=True)
(1): Tanh()
(2): Linear(in_features=13, out_features=1, bias=True)
)
使用了nn.Sequential()做顺序封装。同样可以使用nn.Module.paramaters()方法查看参数
# In[17]:
[param.shape for param in seq_model.parameters()]
# Out[17]:
[torch.Size([13, 1]), torch.Size([13]), torch.Size([1, 13]), torch.Size([1])]
如果想分别查看weight和bias,可以使用nn.Module.named_paramaters()方法
# In[18]:
for name, param in seq_model.named_parameters():
print(name, param.shape)
# Out[18]:
0.weight torch.Size([13, 1])
0.bias torch.Size([13])
2.weight torch.Size([1, 13])
2.bias torch.Size([1])
如果想为网络中不同层次命名,则可以使用OrderedDict
# In[19]:
from collections import OrderedDict
seq_model = nn.Sequential(OrderedDict([
('hidden_linear', nn.Linear(1, 8)),
('hidden_activation', nn.Tanh()),
('output_linear', nn.Linear(8, 1))
]))
seq_model
# Out[19]:
Sequential(
(hidden_linear): Linear(in_features=1, out_features=8, bias=True)
(hidden_activation): Tanh()
(output_linear): Linear(in_features=8, out_features=1, bias=True)
)
# In[20]:
for name, param in seq_model.named_parameters():
print(name, param.shape)
# Out[20]:
hidden_linear.weight torch.Size([8, 1])
hidden_linear.bias torch.Size([8])
output_linear.weight torch.Size([1, 8])
output_linear.bias torch.Size([1])
如果使用了orderdict,则可以直接使用层次的名称来直接访问参数
# In[21]:
seq_model.output_linear.bias
# Out[21]:
Parameter containing: tensor([-0.0173], requires_grad=True)
本文地址:https://blog.csdn.net/pengwill97/article/details/107580063