demo1
import torch
from torch import nn
# 全连接类
class Linear(nn.Module):
def __init__(self, in_dim, out_dim):
super(Linear, self).__init__()
# Parameter 为Tensor的构造方法,默认求导
# w b 为网络需要学习的参数
self.w = nn.Parameter(torch.randn(in_dim, out_dim))
self.b = nn.Parameter(torch.randn(out_dim))
# 前向传播的实现
def forward(self, x):
x = x.matmul(self.w) # x*w .matmul实现矩阵相乘
y = x + self.b.expand_as(x) # y = wx + b .expand_as 保证b和x的矩阵形状一致
return y
# 一
#两层感知机类
#nn.Module(自动学习参数)与nn.functional(不自动学习参数)都提供了很多网络层和函数功能。
# class Perception(nn.Module):
# def __init__(self, in_dim, hid_dim, out_dim):
# super(Perception, self).__init__()
# # 定义了两层全连接层 调用了上个函数Linear的子module
# self.layer1 = Linear(in_dim, hid_dim)
# self.layer2 = Linear(hid_dim, out_dim)
# def forward(self, x):
# x = self.layer1(x)
# y = torch.sigmoid(x) #使用sigmoid作为激活函数
# y = self.layer2(y)
# y = torch.sigmoid(y)
# return y
# 二 当layer1与layer2是直接传递的时候,使用nn.Sequential快速搭建
# nn.Sequential 像一个有序的列表,每层为列表中的一个元素
class Perception(nn.Module):
def __init__(self, in_dim, hid_dim, out_dim):
super(Perception, self).__init__()
self.layer = nn.Sequential(
nn.Linear(in_dim, hid_dim),
nn.Sigmoid(),
nn.Linear(hid_dim, out_dim),
nn.Sigmoid()
)
def forward(self, x):
y = self.layer(x)
return y
调用上述感知机网络
import torch
from torch import nn
from perception import Perception
import torch.nn.functional as F
perception = Perception(2, 3, 2) #实例化类 in_dim=2, hid_dim=3, out_dim=2
print(perception)
# Perception(
# (layer1): Linear()
# (layer2): Linear()
# )
# for name, parameter in perception.named_parameters():
# print(name, parameter)
data = torch.randn(4, 2) # 4个样本 每个样本两个维度
output = perception(data)
print(output)
# tensor([[0.9435, 0.8897],
# [0.9412, 0.8919],
# [0.9431, 0.8973],
# [0.9435, 0.9285]], grad_fn=<SigmoidBackward>)
# 损失函数
label = torch.Tensor([0, 1, 1, 0]).long() #设置标签
criterion = nn.CrossEntropyLoss() #实例化交叉熵类
loss_nn = criterion(output, label)
print(loss_nn)
# 也可以使用nn.functional 函数直接使用交叉熵函数
loss_functional = F.cross_entropy(output, label)
print(loss_functional)
demo2
from torch import nn
class MLP(nn.Module):
def __init__(self, in_dim, hid_dim1, hid_dim2, out_dim):
super(MLP, self).__init__()
self.layer = nn.Sequential(
nn.Linear(in_dim, hid_dim1),
nn.ReLU(),
nn.Linear(hid_dim1, hid_dim2),
nn.ReLU(),
nn.Linear(hid_dim2, out_dim),
nn.ReLU()
)
def forward(self, x):
x = self.layer(x)
return x
import torch
from mlp import MLP
from torch import optim
from torch import nn
model = MLP(28*28, 300, 200, 10)
print(model)
# 使用SGD优化器 学习率为0.01
# parameters 是有序字典
optimizer = optim.SGD(params=model.parameters(), lr=0.01)
for name, parameter in model.named_parameters():
print(name)
# layer.0.weight
# layer.0.bias
# layer.2.weight
# layer.2.bias
# layer.4.weight
# layer.4.bias
data = torch.randn(10, 28*28) #10张图 每一张图长和宽为28
output = model(data)
label = torch.Tensor([1, 0, 4, 7, 9, 3, 4, 5, 3, 2]).long()
# 求损失
criterion = nn.CrossEntropyLoss()
loss = criterion(output, label)
print(loss) #tensor(2.2858, grad_fn=<NllLossBackward>)
optimizer.zero_grad()# 清空梯度,在每次优化前都要使用该操作
loss.backward() #损失的反向传播
optimizer.step() #利用优化器进行梯度更新