0905PyTorch 神经网络基础

PyTorch 神经网络基础

层和块

  • nn.Sequentialnn.Module 可以嵌套使用
# 回顾一下多层感知机
import torch
from torch import nn
from torch.nn import functional as F
net = nn.Sequential(nn.Linear(20,256),nn.ReLU(),nn.Linear(256,10))
X = torch.rand(2,20)
net(X)

参数管理

  • 参数查看
  • 参数初始化
  • 自定义参数初始化
class MLP(nn.Module):
    def __init__(self):
        super().__init__()  # 调用父类的__init__函数
        self.hidden = nn.Linear(20,256)
        self.out = nn.Linear(256,10)
        
    def forward(self, X):
        return self.out(F.relu(self.hidden(X)))
    
# 实例化多层感知机的层,然后在每次调用正向传播函数调用这些层
net = MLP()
X = torch.rand(2,20)
net(X)

 在正向传播函数中执行代码
class FixedHiddenMLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.rand_weight = torch.rand((20,20),requires_grad=False)
        self.linear = nn.Linear(20,20)
    
    def forward(self, X):
        X = self.linear(X)
        X = F.relu(torch.mm(X, self.rand_weight + 1))
        X = self.linear(X)
        while X.abs().sum() > 1:
            X /= 2
        return X.sum()
    
net = FixedHiddenMLP()
X = torch.rand(2,20)
net(X)

  • 直接设置参数
  • 参数绑定

自定义层

  • 不带参数的层
# 构造一个没有任何参数的自定义层
import torch
import torch.nn.functional as F
from torch import nn

class CenteredLayer(nn.Module):
    def __init__(self):
        super().__init__()
        
    def forward(self, X):
        return X - X.mean()
    
layer = CenteredLayer()
print(layer(torch.FloatTensor([1,2,3,4,5])))

# 将层作为组件合并到构建更复杂的模型中
net = nn.Sequential(nn.Linear(8,128),CenteredLayer())
Y = net(torch.rand(4,8))
print(Y.mean())

# 带参数的图层
class MyLinear(nn.Module):
    def __init__(self, in_units, units):
        super().__init__()
        self.weight = nn.Parameter(torch.randn(in_units,units)) # nn.Parameter使得这些参数加上了梯度    
        self.bias = nn.Parameter(torch.randn(units,))

    def forward(self, X):
        linear = torch.matmul(X, self.weight.data) + self.bias.data
        return F.relu(linear)
    
dense = MyLinear(5,3)
print(dense.weight)

# 使用自定义层直接执行正向传播计算
print(dense(torch.rand(2,5)))
# 使用自定义层构建模型
net = nn.Sequential(MyLinear(64,8),MyLinear(8,1))
print(net(torch.rand(2,64)))

 

  • 带参数的层
# 参数绑定
shared = nn.Linear(8,8)
net = nn.Sequential(nn.Linear(4,8),nn.ReLU(),shared,nn.ReLU(),shared,nn.ReLU(),nn.Linear(8,1))  # 第2个隐藏层和第3个隐藏层是share权重的,第一个和第四个是自己的  
net(X)
print(net[2].weight.data[0] == net[4].weight.data[0])
net[2].weight.data[0,0] = 100
print(net[2].weight.data[0] == net[4].weight.data[0])

读写文件

 

  • 加载和保存张量
  • 加载和保存模型参数
# 加载和保存张量
import torch
from torch import nn
from torch.nn import functional as F

x = torch.arange(4)
torch.save(x, 'x-file')
x2 = torch.load("x-file")
print(x2)

#存储一个张量列表,然后把它们读回内存
y = torch.zeros(4)
torch.save([x,y],'x-files')
x2, y2 = torch.load('x-files')
print(x2)
print(y2)

# 写入或读取从字符串映射到张量的字典
mydict = {'x':x,'y':y}
torch.save(mydict,'mydict')
mydict2 = torch.load('mydict')
print(mydict2)

# 加载和保存模型参数
class MLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.hidden = nn.Linear(20,256)
        self.output = nn.Linear(256,10)
    
    def forward(self, x):
        return self.output(F.relu(self.hidden(x)))
    
net = MLP()
X = torch.randn(size=(2,20))
Y = net(X)

# 将模型的参数存储为一个叫做"mlp.params"的文件
torch.save(net.state_dict(),'mlp.params')

# 实例化了原始多层感知机模型的一个备份。直接读取文件中存储的参数
clone = MLP() # 必须要先声明一下,才能导入参数
clone.load_state_dict(torch.load("mlp.params"))
print(clone.eval()) # eval()是进入测试模式

Y_clone = clone(X)
print(Y_clone == Y)

 

 

Numpy与Torch对比

Numpy 是处理矩阵等数据的模块,会使用多核加速运算。而 PyTorch 就是神经网络中的 Numpy,是 Torch(张量)的类型,张量的维度可以大于 2。

下面举例说明 Numpy 和 Torch 的一些区别:

# 首先引入包
import torch
import numpy as np

# 创造一个numpy的数据,reshape成2行3列
np_data = np.arange(6).reshape((2, 3))
# 将numpy转换为torch中tensor的数据
torch_data = torch.from_numpy(np_data)
# 将tensor转换为numpy的数据
tensor2array = torch_data.numpy()

print(
	'\nnumpy', np_data,
    '\ntorch', torch_data,
    '\ntensor2array', tensor2array,
)

 进行矩阵相乘的操作:

data = [[1, 2], [3, 4]]
tensor = torch.FloatTensor(data)
# 将data变为numpy的data
data = np.array(data)
print(
	'\nnumpy:', np.matmul(data, data), # 矩阵相乘
    # 或使用:
    # '\nnumpy:', data.dot(data),
    '\ntorch:', torch.mm(tensor, tensor)
    # 而在torch中使用dot给出的答案不一样
    # '\nnumpy:', tensor.dot(tensor), # torch将结果展平:1×1+2×2+3×3+4×4
)

Variable 变量
我们介绍一些 PyTorch 的细节内容(神经网络的细节变化),tensor 与 Variable 的不同之处。

torch 是用 tensor 来计算的,神经网络的参数都是 Variable 变量的形式,将 tensor 数据放到 Variable 变量中,用变量来更新神经网络中的参数。

import torch
from torch.autograd import Variable

tensor = torch.FloatTensor([[1, 2], [3, 4]])
# requires_grad为是否涉及到反向传播过程,True会计算反向传播梯度
variable = Variable(tensor, requires_grad=True)
print(tensor)
print(variable)

# 进行一些计算
t_out = torch.mean(tensor*tensor) # x^2
v_out = torch.mean(variable*variable)
print(t_out)
print(v_out)

 只有在反向传播时才会有差别,而 tensor 不能反向传播,而 variable 可以,为搭建图的信息。我们对 v_out 进行反向传递,而 variable 会受影响,因为这是一套体系,结点间相互联系。

v_out.backward() # 误差的反向传递
# v_out = 1/4*sum(var*var)
# d(v_out)/d(var) = 1/4*2*variable = variable/2
print(variable.grad) # 查看反向传播后的梯度更新值
print(variable) # 可以看variable中的信息
print(variable.data) # variable包含哪些data
# 如果要转换成numpy,则需先将variable转换为tensor
print(variable.data.numpy())

 激励函数


我们的任务通常是非线性的,因此需要用激励函数将线性的转换为非线性的。激励函数让神经网络可以描述非线性问题的步骤,使神经网络变得更强大。

Torch 中的激励函数有很多, 不过我们平时要用到的就这几个 relu, sigmoid, tanh, softplus

将神经网络输出的结果代入到激励函数中,输出一个新的结果,是一种非线性化手段。

引入神经网络模块和画图模块

import torch
import torch.nn.functional as F # nn是神经网络模块
from torch.autograd import Variable
import matplotlib.pyplot as plt # python 的可视化模块

首先生成数据

x =torch.linspace(-5, 5, 200) # -5到5的线段中取200个点
x = Variable(x)
# torch的数据格式无法被matplot识别,要转换为numpy
x_np = x.data.numpy()

激励函数。softplus 做概率图,分类概率,不能被线图呈现

y_relu = F.relu(x).data.numpy()
y_sigmoid = F.sigmoid(x).data.numpy()
y_tanh = F.tanh(x).data.numpy()
y_softplus = F.softplus(x).data.numpy()
画图
plt.figure(1, figsize=(8, 6))
plt.subplot(221)
plt.plot(x_np, y_relu, c='red', label='relu')
plt.ylim((-1, 5))
plt.legend(loc='best')

plt.subplot(222)
plt.plot(x_np, y_sigmoid, c='red', label='sigmoid')
plt.ylim((-0.2, 1.2))
plt.legend(loc='best')

plt.subplot(223)
plt.plot(x_np, y_tanh, c='red', label='tanh')
plt.ylim((-1.2, 1.2))
plt.legend(loc='best')

plt.subplot(224)
plt.plot(x_np, y_softplus, c='red', label='softplus')
plt.ylim((-0.2, 6))
plt.legend(loc='best')

plt.show()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值