需要导入函数: import torch.nn.functional as F
使用 F.one_hot() 方式对标签进行编码。
注意: F.one_hot()的参数必须是一维向量,所以如果是一个矩阵,需要一个一个来one-hot编码。
并且, ont_hot()参数必须是张量,所以前面一个for循环先将矩阵转换成张量.
for i in range(len(mnist_train)):
train_Y[i] = torch.tensor(train_Y[i])
test_Y[i] = torch.tensor(test_Y[i])
import torch.nn.functional as F
num_class = 10
for i in range(len(mnist_train)):
train_Y[i] = F.one_hot(train_Y[i], num_classes=num_class )
test_Y[i] = F.one_hot(test_Y[i], num_classes=num_class )
矩阵的flatten操作:
t = torch.tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]],
[[9, 10],
[11, 12]]])
torch.flatten(input, start_dim=0, end_dim=-1) → Tensor 默认开始为0维,结束-1维度
torch.flatten(t)
注意: flatten()的参数是一个数据 , 不能是多个数据
得到:
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
初始化参数;
for l in range(1,L):
parameters["W"+str(l)] = np.random.randn(layers_dims[l],layers_dims[l-1])* 0.01
parameters["b"+str(l)] = np.zeros((layers_dims[l], 1))
创建网络层,先定义一个类,继承 nn,Module基类, 定义一个构造函数并且调用父类的构造函数, 父类构造函数的第一个默认参数是子类名称,第二个默认参数是self
之后在子类构造函数中定义自己的网络层即可, 需要几层,就写几层,如 Rule啊,Dropout都写在构造函数中。
需要重写forward(self,x)函数,x表示训练数据x, 在前向传播函数中,调用网络层进行前向传播, 如果需要迭代多次,记得每次清空梯度值。
import torch.nn as nn //导入网络层
class LinerNet(nn.Module):
def __init__(self,n_feature):
super(LinerNet,self).__init__()
self.linear = nn.Linear(n_feature,1)
def forward(self,x):
y = self.linear(x)
return y
num_imputs = 2
net = LinerNet(num_imputs)
print(net)
使用nn.Sequential()搭建网络。
Sequential 是一个有序的容器,网络层按照在传入Sequential的顺序依次添加到计算图中
写法一:
net = nn.Sequential(
nn.Linear(num_inputs, 1)
#此处还可以传入其他层
)
方法二:
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
#net.add_module........添加其他层
方法三:
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
('linear', nn.Linear(num_inputs,1))
#添加其他层......
]))
print(net)可以得到网络结构
查看每一层网络参数值:
for param in net.parameters():
print(param)
模型初始化方法;
我们通过init.normal_方法把权重初始化为均值为0,标准差为0.01的正态分布。
偏差初始化为0
from torch.nn import init
init.normal_(new[0].weiight , mean=0, std=0.01)
init.constant_(net[0].bias , val =0)
定义损失函数 :
Pytorch在nn中提供了各种损失函数,这些损失函数可以看作是一种特殊的层,Pytorch也将这些损失函数实现为nn.Module的子类, 下面使用它提供的均方误差损失作为模型损失函数。
loss = nn.MSELoss()
定义优化函数:
torch.optim模块提供了很多常用的优化算法, SGD, Adam等, 下面创建一个用于优化net所有参数的优化器,并指定学习率为0.03的小批量梯度下降
import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.03)
print(optimizer)
我们可以为不同子网络设置不同的学习率
optimizer = optim.SGD([
#如果对某个参数不指定学习率,就使用最外层默认的学习率
{'params' : net.subnet1.parameters()}, #lr=0.03,是外层默认的
{'params' : net.subnet2.parameters(), 'lr' = 0.01}
], lr=0.03) //这里的lr=0.03是外层的 lr
训练模型:
num_epoch = 3
for epoch in range(1, num_epochs+1):
for X, y in data_iter:
output = net(X)
l = loss(output, y.view(-1,1))
optimizer.zero_grad()
l.backward()
optimizer.step()
print("epoch %d, loss: %f" %(epoch,l.item()))
我们可以分别比较学习到的模型参数和真实的模型参数。 我们从net获得需要的层,并访问其weight 和偏差bias。
dense = net[0]
print(true_w, dense.weight) true_w和true_b是在训练之前初始化的参数
print(true_b, dense.bias)
总结:
torch.utils.data模块提供了有关数据处理的工具
torch.nn模块定义了大量神经网络层
torch.nn.init模块定义了各种初始化方法
torch.optim模块提供了模型参数初始化的各种方法
model = NeuralNetwork().to(device) print(model
进行预测: X = torch.rand(1, 28, 28, device=device) logits = model(X) pred_probab = nn.Softmax(dim=1)(logits) y_pred = pred_probab.argmax(1) print(f"Predicted class: {y_pred}")
import torch import torchvision.models as modelstorch.save(model, 'model.pth')model = torch.load('model.pth')