当前位置: 首页 > wzjs >正文

厚街东莞网站建设搜索引擎收录查询工具

厚街东莞网站建设,搜索引擎收录查询工具,如何做一个商城类型的网站,公司网址怎么查询目录 模型构造 层和块 自定义块 顺序块 在正向传播函数中执行代码 混合搭配各种组合块的方法 参数管理 参数访问 目标参数 一次性访问所有参数 从嵌套块收集参数 初始化参数 内置初始化 对某些块应用不同的初始化方法 自定义初始化 参数绑定 自定义层 将层作为组…

目录

模型构造

层和块

自定义块

 顺序块

在正向传播函数中执行代码

混合搭配各种组合块的方法

参数管理

参数访问

目标参数

一次性访问所有参数

从嵌套块收集参数

 初始化参数

内置初始化

对某些块应用不同的初始化方法

 自定义初始化

参数绑定

自定义层

将层作为组件合并构建更复杂的模型中

带参数的层

读写文件

加载和保存张量

存储一个张量列表,然后把他们读回内存

写入或读取从字符串映射到张量的字典

加载和保存模型参数


模型构造

层和块

首先,我们回顾一下多层感知机

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))# 生成一个随机的input
X = torch.rand(2, 20)
net(x)  # 得到output

functional里面定义了一些没有包括参数的一些函数,之后会讲如何使用,刨个坑在这~ 

nn.Sequential定义了一种特殊的Module,在PyTorch中,Module是一个很重要的概念

自定义块

任何一个层,任何一个神经网络,都应该是Module的一个子类

下面自定义了一个MLP,实现了和刚刚一样的函数

class MLP(nn.Module):  # 是nn.Module的子类,继承之后会得到很多好用的函数def __init__(self):super().__init__()  # 调用父类,这样在初始化weight等的时候就可以直接全部弄好self.hidden = nn.Linear(20, 256)self.out == nn.Linear(256, 10)def forward(self, X):return self.out(F.relu(self.hidden(X))) # 直接通过nn.module里面实现的ReLU来激活

所有的Module都有两个比较重要的函数:

  • __init__:定义需要哪些类、哪些参数
  • forward:前向函数,用来写给定输入,如何操作来前向运算传输

实例化多层感知机的层,然后在每次调用正向传播函数时调用这些层

net = MLP() # 实例化我们刚刚创建的类
net(X) # 把输入丢进去,最后得出一个2*10的矩阵

 顺序块

让我们来实现以下nn.Sequential,其实很简单

class MySequential(nn.Module):def __init__(self, *args): # 接收一个list of input argumentssuper().__init__() # 调用父类的初始化函数for block in args: # 对所有传入的层(称为block)放入一个特殊的容器里面# 放进_modules[],pytorch就知道里面都是我们需要的层,其实是一个按序排的字典,所以我们按序给它插入,将本身作为keyself._modules[block] = blockdef forward(self, X):for block in self._modules.values(): # 因为是排过序的,所以会和我们调用的顺序是一样的X = block(X)return Xnet = MySquential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
net(X)

在正向传播函数中执行代码

当Sequential无法满足我们的时候,我们还可以做更多灵活的定义,比如如下代码所示

class FixedHiddenMLP(nn.Module):def __init__(self):super().__init__()# 这个随机的weight不参与训练,因为不计算梯度self.rand_weight = torch.rand((20, 20), requires_grad = false)self.linear = nn.Linear(20, 20)# 里面可以写任何你想做的函数! 任何!比Sequential更灵活!!def forward(self, X):X = self.linear(X)# mm:矩阵乘法X = F.relu(torch.mm(X, self.rand_weight) + 1)# 回头二次调用线性函数X = self.linear(X)while X.abs().sum() > 1:X /= 2    # 一直除2,除到你很小为止return X.sum()net = FixedHiddenMLP()
net(X)

混合搭配各种组合块的方法

另一种灵活的方法就是:嵌套使用!因为无论是层、Sequential等都是nn.Module的子类,其实是可以很灵活的嵌套使用的

没任何意义,只是一个举例

class NestMLP(nn.Module):def __init__(self):super.__init__()self.net = nn.Sequential(nn.Linear(20, 64), nn.ReLU(),nn.Linear(64,32), nn.ReLU())self.linear = nn.Linear(32, 16)def forward(self, X):return self.linear(self.net(X))  # 一个Sequential和Linear的嵌套chimera = nn.Sequentisl(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP())    # 再套一层!
chimera(X)

参数管理

当我们把模型定义好之后我们要如何访问我们的参数呢?

我们首先关注具有单隐藏层的多层感知机

import torch
from torch import nn# 一个单隐藏层MLP
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size = (2, 4))
net(X)

参数访问

# stare_dict():理论上他就是_Modules
print(net[2].statc_dict())

我们会看到这样的输出:

OrderedDict([('weight', tensor([[-0.1351, -0.0821, 0.2084, 0.2804, -0.2748, 0.0061, 
0.1729, -0.3424]])), ('bias', tensor([-0.3389]))])

可以简单把nn.Sequential当成python的一个list,那我们的net[2]就会拿到我们刚刚定义net时候的第三个层,也就是nn.Lunear(8, 1),最后的输出层

目标参数

我们也可以直接去访问一个具体的参数

print(type(net[2],bias))  # 打印最后一层偏移
print(net[2].bias)
print(net[2].bias.data)  # 只访问值,他还有个梯度,可以通过.grad来访问梯度值

输出: 

<class 'torch.nn.parameter.Parameter'>  # 类型是Parameter:是一个可以优化的参数
Parameter containing
tensor([-0.3389], required_grad = Trye)
tensot([-0.3389])

一次性访问所有参数

print(*[(name, param.shape) for name, param in net[0].named_parameters()])
print(*[(name, param.shape) for name, param in net.named_parameters()])

输出:

(‘weight’, torch.Size([8, 4]))('bias', torch.Size([8]))
('0.weight', torch.Size([8, 4]))('0.bias', torch.Size([8]))('2.weight', 
torch.Size([1, 8]))('2.bias', torch.Size([1]))

 因为1是ReLU,是没有参数的,所以拿不出来

当我们有名字之后,我们可以通过名字来获取参数

net.state_dict()['2.bias'].data

 输出:

tensor([-0.3389])

从嵌套块收集参数

当我们模型里面出现了嵌套我们要如何访问参数呢?

def block1():return nn.Sequential(nn.Linear(4,8), nn.ReLU(), nn.Linear(8, 4),nn.ReLU())# 嵌套了四个block1
def block2():net = nn.Sequential()for i in range(4):net.add_module(f'bock {i}', block1())    # 我自己传了个字符串给你,就不是0123了return netrgnet = nn.Sequential(block2(), nn.Linear(4, 1))
rgnet(X)
print(rgnet)

输出: 

首先外层是一个Sequential,第0个元素也是Sequential(我们的block2),block2里面的block 0元素又是一个Sequential(block1),所以整个网络是一个三个Sequential的嵌套

所以可以通过print大概看出网络长什么样子 。当然这是个简单网络,如果是复杂网络的话,print看起来就没有那么方便

复杂模型可以一个block一个block看,这样对于模型结构也有好处

 初始化参数

如何修改默认的参数

内置初始化

def init_normal(m): # m:每次传入一个Moduleif type(m) == nn.Linear:nn.init.normal_(m.weight, mean = 0, std = 0.01) # 对weight初始化,下划线跟在后面表示这是一个替换函数,不是返回一个值nn.init.zeros_(m.bias)   # bias赋0net.apply(init_normal) # apply:对net里面所有的Module去调用这个函数,遍历一遍

apply:给你一个方式让你去遍历整个神经网络去做一些事情

对某些块应用不同的初始化方法

def xavier(m):if type(m) == nn.Linear:nn.init.xavier_uniform_(m.weight) # 一个xavier初始化def init_42(m):if type(m) == nn.Linear:nn.init.constant_(m.weight, 42)net[0].apply(xavier)
ner[2].applu(init_42)

 自定义初始化

def my_init(m):if type(m) == nn.Linear:print("Init",*[(name, param.shape) for name, param in m.named_parameters()][0])nn.init.uniform_(m.weight, -10, 10)m.weight.data *= m.weight.data.abs() >= 5net.apply(my_init)

当然还有一些更暴力的办法:

# 直接拎出来改值
net[0].weight.data[:] += 1
net[0].weight.data[0, 0] = 42

参数绑定

讲一个小应用,有时候我们会希望在不同层里面共享权重的时候,可以做一个参数绑定 

shared = nn.Linear(8, 8)
# 可以理解成:第一个隐藏层和第二个隐藏层是同一个层!
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), shared, nn.ReLU(), shared,nn.ReLU(), nn.Linear(8, 1))
net(X)
print(net[2].weight.data[0] == net[4].weight.data[0])  # 比较shared
net[2].weight.data[0, 0] = 100
print(net[2].weight.data[0] == net[4].weight.data[0])  # 改第三层,第五层也被修改# 输出
tensor([True, True, True, True, True, True, True, True])
tensor([True, True, True, True, True, True, True, True])

自定义层

构造一个没有任何参数的自定义层

class CenteredLayer(nn.Module):def __init__(self):    # python3不写这个函数会自己加上super().__init__()def forward(self, X):return X - X.mean()layer = CenteredLayer()
layer(torch.FloatTensor([1, 2, 3, 4, 5]))# 输出
tensor({[-2., -1., 0., 1., 2.])

将层作为组件合并构建更复杂的模型中

net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())Y = net(torch.rand(4, 8))
Y.mean()# 输出
tensor(-2.7940e-09, grad_fn = <MeanBackward0>)

带参数的层

通过nn.Parameter()把初始化的值包起来就行了

class MyLinear(nn.Module):def __init__(self, in_units, units):    # in_units:输入大小 units:输出大小super().__init__()# Parameter:给你梯度加上,再给你一个合适的名字,就干这点事情self.weight = nn.Parameter(torch.randn(in_units, units))self.bias = nn.Parameter(torch.randn(units,))def forward(self, X):# matmul:矩阵乘法linear = torch.matmul(X, self.weight.data) + self.bias.datareturn F.relu(linear)dense = MyLinear(5, 3)
dense.weight# 输出
Parameter containing:
tensor([[1.1537, -0.2809, 1.2778],[-0.7972, 0.8573, -0.6472],[0.6014, -2.0051, -0.3640],[1.3730, 0.5488, 1.1121],[-1.0814, 1.5180, -0.2057]], requires_grad = True)

读写文件

简而言之就是,你训练好的东西怎么存下来

加载和保存张量

x = torch.arange(4)
torch.save(x, 'x-file')  # 把这个向量x,存入当前目录下,文件名为x-filex2 = torch.load("x-file")
x2# 输出
tensor([0, 1, 2, 3])

存储一个张量列表,然后把他们读回内存

我们不单单可以只存一个向量,还可以存一个list,然后读取

y = torch.zeros(4)
torch.save([x, y], 'x-files')
x2, y2 = torch.load('x-files')
(x2, y2)# 输出
(tensor([0, 1, 2, 3]), tensor([0., 0., 0., 0.]))

写入或读取从字符串映射到张量的字典

可以存list,那我们存一个字典也很正常叭!

mydict = {'x' : x, 'y' : y}
torch.save(mydict, 'mydict')
mydict2 = torch.load('mydict')
mydict2# 输出
{'x': tensor([0, 1, 2, 3]), 'y': tensor([0., 0., 0., 0.])}

加载和保存模型参数

那我有一个MLP我要怎么办?

首先我们要明白,对于一个神经网络,我们应该存什么东西?

因为我们PyTorch是没有办法把整个网络模型存下来的,相较于Tensorflow有一定局限性

其实我们要存的是模型的权重参数!

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)

那我们要怎么存呢?

记得我们可以用state_dict()来得到我们所有的参数的字符串对吧!

那我们将模型的参数存储为一个叫做”mlp.params“的文件

torch.save(net.state_dict(), 'mlp.params')

那我们怎么load回来呢??

实例化了原始多层感知机模型的一个备份。直接读取文件中存储的参数

如果你真的要在别的地方load这个模型的话,你不光要把.params文件带走,你还得把网络的定义带走!!

因为你首先要声明生成一个网络出来

声明一个新的clone实例化MLP,这个时候网络参数已经被随机初始化过了,但是我们不用管

用load_state_dict来overwrite掉我们初始化的参数

clone = MLP()
# load():从本地文件读取参数;load_state_dict():把参数加载到模型
clone.load_state_dict(torch.load("mlp.params"))
clone.eval()# 输出
MLP((hidden): Linear(in_features = 20, out_features = 256, bias = True)(output): Linear(in_features = 256, out_features = 10, bias = True)
)
http://www.dtcms.com/wzjs/252492.html

相关文章:

  • 模板之家html5seo排名优化表格工具
  • 怎么制作自己的网页网站首页搜索关键词查询工具
  • 淘宝网站的建设搜索引擎优化的含义
  • 大连 找人做网站手机网站优化排名
  • 国外网站建设视频教学搭建网站教程
  • 房产网站建设批发网站统计分析工具的主要功能
  • 做网站用eclipse吗百度总部
  • 个人备案做门户网站太原搜索引擎优化招聘信息
  • 上海市建设教育网站网站服务器搭建与管理
  • 图片网站怎么做排名一般网站推广要多少钱
  • 牙克石网站建设线上平台推广方案
  • 网站四对联广告代码网络公司是做什么的
  • 建设网站要不要投资钱深圳seo公司排名
  • 企业网站怎么建设新品怎么推广效果最好
  • 软件开发与网站建设市场调研与分析
  • 外贸汽车网站免费制作小程序平台
  • 西安比较好的网络公司关键词优化资讯
  • 泰州网站制作推广百度的营销推广模式
  • 云存储做网站网站收录大全
  • 泉州网站开发人员小米的推广软文
  • 上海比较好的外包公司seo排名教程
  • 李沧做网站公司广州seo推广公司
  • 海淘网站主要关键词重庆seo小z博客
  • 宝安做网站怎么样免费百度下载
  • 潍坊做网站的电话谷歌chrome浏览器
  • 咸宁网站定制百度网页版链接
  • 去泰国做赌博发网站站长素材音效
  • 如何做测评视频网站网上全网推广
  • 合肥seo优化外包公司seo工资
  • 医院网站建设 不足网上哪里接app推广单