激活函数
作用
在网路的中间层,允许输出函数在不同的值上具有不同的斜率,这些不同斜率的部分可以近似任意函数。
在网络的最后一层,可以将线性运算的输出限制在指定范围内。
具有的性质
非线性:非线性允许整个网络可以近似更复杂的函数。
可微:可以通过梯度来更新。
至少有一个敏感区域:输入中,细微的改变对输出有非常大的影响。
大部分是非敏感的区域:输入的改变对结果影响甚微。
输入为正或负无穷都有对应的上下界。
激活函数code
import math
math.tanh(-2.2)
线性模型
模型包
import torch.nn as nn
定义模型
linear_model = nn.Linear(1,1) #参数,输入特征数量,输出特征数量
linear_model.weight #查看模型权重,初始权重是随机的
linear_model.bias #查看偏置项,初始偏置项是随机的
模型预测
模型的输入神经元个数对应的是一批次数据中单个数据的维度,批次大小默认为第0维不用指定。因此若数据是1维的,那么输入神经元个数也为1。
x = torch.ones(1)
linear_model(x) #模型的输入期望第0维度是一批数据的数量,因此输出也是一个tensor列表形式,每个元素对应一个输出
x = torch.ones(10,1)
linear_model(x)
批次训练
t_c = [0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0]
t_u = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]
t_c = torch.tensor(t_c).unsqueeze(1)
t_u = torch.tensor(t_u).unsqueeze(1)
n_samples = t_u.shape[0]
n_val = int(0.2 * n_samples)
shuffled_indices = torch.randperm(n_samples)#将0~n_samples随机打乱后获得数字序列
train_indices = shuffled_indices[:-n_val]#从0到倒数第n_val-1个
val_indices = shuffled_indices[-n_val:]#从倒数第n_val个到最后
train_t_u = t_u[train_indices]
train_t_c = t_c[train_indices]
val_t_u = t_u[val_indices]
val_t_c = t_c[val_indices]
t_un_train = 0.1 * train_t_u
t_un_val = 0.1 * val_t_u
linear_model = nn.Linear(1,1) #输入为1维,默认第0维是batch大小,batch中每一个元素都是1维
optimizer = optim.SGD(linear_model.parameters(),lr=1e-2)
linear_model.parameters()
list(linear_model.parameters())
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}")
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=train_t_c,
t_c_val=val_t_c
)
print()
print(linear_model.weight)
print(linear_model.bias)
顺序模型
使用nn.Sequential来按照顺序添加模型。与keras不同的是在添加一个隐藏层后需要手动添加一个激活层。
seq_model = nn.Sequential( nn.Linear(1,13),
nn.Tanh(),
nn.Linear(13,1))
可以通过seq_model.parameters()来查看模型的所有参数以及其名字
[param.shape for param in seq_model.parameters()]
for name,param in seq_model.named_parameters():
print(name,param.shape)
定义中间层名字
OrderedDict
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
for name,param in seq_model.named_parameters():
print(name,param.shape)
seq_model.output_linear.bias
模型训练
optimizer = optim.SGD(seq_model.parameters(),lr=1e-3)
training_loop(
n_epochs=5000,
optimizer=optimizer,
model=seq_model,
loss_fn=nn.MSELoss(),
t_u_train=t_un_train,
t_u_val=t_un_val,
t_c_train=train_t_c,
t_c_val=val_t_c
)
print('output',seq_model(t_un_val))
print('answer',val_t_c)
print('hidden',seq_model.hidden_linear.weight.grad)
可视化
import matplotlib.pyplot as plt
t_range = torch.arange(20.,90.).unsqueeze(1)
fig = plt.figure(dpi=100)
plt.xlabel("Fahrenheit")
plt.ylabel("Celsius")
plt.plot(t_u.numpy(),t_c.numpy(),'o')
plt.plot(t_range.numpy(),seq_model(0.1 * t_range).detach().numpy(),'c-')
plt.plot(t_u.numpy(),seq_model(0.1*t_u).detach().numpy(),'kx')
标签:linear,val,模型,nn,pytorch,train,深度,model,seq
From: https://www.cnblogs.com/RedNoseBo/p/17574252.html