从基础到卷积神经网络(第13天)

1. PyTorch 神经网络基础

1.1 模型构造

1. 块和层

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

import torch 
from torch import nn
from torch.nn import functional as Fnet = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))X = torch.rand(2, 20) # 生成随机输入(批量大小=2, 输入维度=20)
net(X) # 输出(批量大小=2, 输出维度=10)

在这里插入图片描述

2. 自定义块

自定义MLP实现上一节的功能

class MLP(nn.Module): # 定义nn.Mudule的子类def __init__(self): super().__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))) # X-> hidden-> relu-> out

实例化MLP的层,然后再每次调用正向传播函数时调用这些层

net = MLP()
net(X)

在这里插入图片描述

3. 实现Sequential类

class MySequential(nn.Module):def __init__(self, *args):super().__init__()for block in args:self._modules[block] = blockdef forward(self, X):for block in self._modules.values():X = block(X)return Xnet = MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
net(X)

在这里插入图片描述

4. 在正向传播中执行代码

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) # 输入和随机权重做矩阵乘法 + 1(偏移)-》激活函数X = self.linear(X)while X.abs().sum() > 1: # 控制X小于1X /= 2return X.sum() # 返回一个标量net = FixedHiddenMLP()
net(X)

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

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)) # 输入-> net-> linear中chimera = nn.Sequential(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP()) # (32, 16)->(16, 20) ->(20, 1)
chimera(X)

在这里插入图片描述
总结:
1、在init中写各种层
2、在前向函数中调用init中各种层
有很强的灵活性

1.2 参数构造

具有单隐藏层的MLP

import torch
from torch import nnnet = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size=(2, 4))
net(X)

在这里插入图片描述
参数访问

print(net[2].state_dict()) # 拿到nn.Linear的相关参数

在这里插入图片描述
访问目标参数

print(type(net[2].bias))
print(net[2].bias)
print(net[2].bias.data)
net[2].weight.grad == None # 梯度是否为0,因为此时还没有计算,所以没有梯度

在这里插入图片描述
一次访问所有参数

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

输出没有block1是因为第二层是ReLU是没有参数的
在这里插入图片描述

net.state_dict()['2.bias'].data # 访问最后一层的偏移

在这里插入图片描述
从嵌套块收集参数

def block1():return nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 4), nn.ReLU())def block2(): # block2嵌套4个block1net = nn.Sequential()for i in range(4): net.add_module(f'block {i}', block1()) return netrgnet = nn.Sequential(block2(), nn.Linear(4, 1))
rgnet(X)

在这里插入图片描述

print(rgnet) # 查看网络结构

在这里插入图片描述
内置初始化

def init__normal(m): # 传入的moduleif type(m) == nn.Linear: # 如果传入的是全连接层nn.init.normal_(m.weight, mean=0, std=0.01) # 内置初始化,均值为0方差为1,.normal_替换函数不返回nn.init.zeros_(m.bias) # 所有的bias赋0net.apply(init__normal) # 对神经网络模型net中的所有参数进行初始化,使用init_normal()函数对参数进行随机初始化
net[0].weight.data[0], net[0].bias.data[0]

在这里插入图片描述

def init_constant(m):if type(m) == nn.Linear:nn.init.constant_(m.weight, 1) # 将m.weight初始常数化为1nn.init.zeros_(m.bias)net.apply(init_constant)
net[0].weight.data[0], net[0].bias.data[0]

在这里插入图片描述
不建议权重全部常数化,会导致所有向量向一致的方向发展

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

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) # 第一个层用xavier初始化
net[2].apply(init_42) # 第二个层用init_42进行初始化
print(net[0].weight.data[0])
print(net[2].weight.data)

在这里插入图片描述
自定义初始化

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() >= 5 # 对大于等于5的位置进行保留,小于5的位置进行置零操作net.apply(my_init) # 使用my_init对net进行初始化
net[0].weight[:2]

在这里插入图片描述
直接进行替换

net[0].weight.data[:] += 1
net[0].weight.data[0, 0] = 42
net[0].weight.data[0]

在这里插入图片描述
参数绑定(在不同的网络之间共享权重的方法)

shared = nn.Linear(8, 8)
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), shared, nn.ReLU(), shared,  # 2和4层共享权重nn.ReLU(), nn.Linear(8, 1))
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])

1.3 自定义层

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

import torch
import torch.nn.functional as F
from torch import nnclass CenteredLayer(nn.Module): # 层也是nn.Module的子类def __init__(self):super().__init__()def forward(self, X):return X - X.mean()layer = CenteredLayer()
layer(torch.FloatTensor([1, 2, 3, 4, 5]))

在这里插入图片描述
将层作为组件合并到构建更复杂的模型

net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())Y = net(torch.rand(4, 8))
Y.mean() # 不会真等于0是因为存在浮点的误差

带参数的图层

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.datareturn F.relu(linear)dense = MyLinear(5, 3) # 输入是5.输出是3
dense.weight

使用自定义层直接执行正向传播计算

dense(torch.rand(2, 5))

使用自定义层构建模型

net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1))
net(torch.rand(2, 64))

1.4 读写文件

加载和保存张量

import torch 
from torch import nn
from torch.nn import functional as Fx = torch.arange(4) # 构造长为4的向量
torch.save(x, 'x-file') # 把x存在当前文件目录下x2 = torch.load("x-file") # 从指定的文件路径("x-file")加载一个PyTorch模型或张量
x2

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

y = torch.zeros(4)
torch.save([x, y], 'x-file')
x2, y2 = torch.load('x-file')
(x2, y2)

在这里插入图片描述
写入或读取从字符串映射到张量的字典

mydict = {'x' : x, 'y' : y}
torch.save(mydict, 'mydict')
mydict2 = torch.load('mydict')
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")) # 从指定的文件路径("mlp.params")加载一个PyTorch模型的参数,并将这些参数应用到一个新的模型实例(clone)上
clone.eval()

在这里插入图片描述
验证

Y_clone = clone(X)
Y_clone == Y

在这里插入图片描述

使用GPU

查看gpu

!nvidia-smi

查询可用gpu的数量

import torch
from torch import nntorch.cuda.device_count()

计算设备

import torch
from torch import nntorch.device('cpu'), torch.cuda.device('cuda')

这两个函数允许我们在请求的GPU不存在的情况下运行代码

def try_gpu(i=0):  """如果存在,则返回gpu(i),否则返回cpu()。"""if torch.cuda.device_count() >= i + 1:return torch.device(f'cuda:{i}')return torch.device('cpu')def try_all_gpus():  """返回所有可用的GPU,如果没有GPU,则返回[cpu(),]。"""devices = [torch.device(f'cuda:{i}') for i in range(torch.cuda.device_count())]return devices if devices else [torch.device('cpu')]try_gpu(), try_gpu(10), try_all_gpus()

查看张量所在的设备,默认是在cpu上

x = torch.tensor([1, 2, 3])
x.device

存储在GPU上

X = torch.ones(2, 3, device=try_gpu())
X
Y = torch.rand(2, 3, device=try_gpu())
Y

计算X+Y,要决定在哪里执行这个操作,如果不在同一个gpu要执行拷贝

Z = X.cuda(0)
Y + Z

神经网络和GPU

net = nn.Sequential(nn.Linear(3, 1))
net = net.to(device=try_gpu()) # 将cpu上创建好的网络挪到gpu上net(X)

确认模型参数存储在同一个GPU上

net[0].weight.data.device

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/105443.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

容器化应用程序管理与分发工具集 | 开源专题 No.34

kubernetes/kubernetes Stars: 101.7k License: Apache-2.0 Kubernetes 是一个开源系统,用于管理跨多个主机的容器化应用程序。它提供了部署、维护和扩展应用程序的基本机制。Kubernetes 借鉴了 Google 在大规模运行生产负载方面十五年的经验,并结合了社…

Qt 中图像的绘制

Qt中的绘图类 以下是常见的绘图类 绘图QPainterQBrushQFontQPenQColorQPaintDeviceQGLFramebufferObjectQGLPixelBufferQOpenGLPaintDeviceQPagedPaintDeviceQPdfWriterQPrinterQPaintDeviceWindowQOpenGLWindowQRasterWindowQRasterWindowQRasterWindowQImageQPictureQPixma…

【Excel】【latex】将EXCEL中单元格的计算关系还原为公式,用c#重构

在excel中,将很多个单元格,及其内部的公式,用文本的形式复制出来 Ctrl ~将 Excel 切换到公式视图,可以看到单元格中的公式,而不是公式的结果。 像平常一样复制和粘贴单元格。粘贴时,会看到的是单元格中的…

Android studio控制台 输出乱码解决方法

在AS的安装目录,找到 studio64.exe.vmoptions 文件, 用编辑器打开文件,在最后面加上下面的代码: -Defile.encodingUTF-8然后 重启AS。 注意: 下面两种方式也能打开studio64.exe.vmoptions 文件,但是需要确…

【ELK 使用指南】ELK + Filebeat 分布式日志管理平台部署

ELK和EFLK 一、前言1.1 日志分析的作用1.2 需要收集的日志1.3 完整日志系统的基本特征 二、ELK概述2.1 ELK简介2.2 为什么要用ELK?2.3 ELK的组件 三、ELK组件详解3.1 Logstash3.1.1 简介3.1.2 Logstash命令常用选项3.1.3 Logstash 的输入和输出流3.1.4 Logstash配置文件 3.2 E…

log4cpp封装成独立的类(单例模式)

一、编译安装 二、封装使用 头文件Logger.h: #ifndef DISTRIBUTED_LOGGER_H_ #define DISTRIBUTED_LOGGER_H_#include <string> #include <log4cpp/Category.hh>class Logger{ public:bool init(const std::string& log_conf_file);static Logger* instance…

关于网络协议的若干问题(四)

1、QUIC 是一个精巧的协议&#xff0c;它有哪些特性&#xff1f; 答&#xff1a;QUIC 还有其他特性&#xff0c;一个是快速建立连接。另一个是拥塞控制&#xff0c;QUIC 协议当前默认使用了 TCP 协议的 CUBIC&#xff08;拥塞控制算法&#xff09;。 CUBIC 进行了不同的设计&…

Hadoop问题:start-all.sh显示未找到命令

在sbin文件夹下是start-all.sh可以运行的&#xff0c;但是到了别的文件夹下就不行了&#xff0c;于是想到了是文件路径问题&#xff0c;因为hadoop环境是和java环境一起配置的导致sbin写成了bin 解决办法&#xff1a; 打开.bashrc配置hadoop的环境变量 sudo vim ~/.bashrc …

nodejs+vue教学辅助管理系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

Folium 笔记:使用PopUp突出subzone的空间分布

0 效果图 点开某一个区域后&#xff0c;内容是这个区域的用地类型分布 1 读取数据 import folium import matplotlib.pyplot as plt import re import geopandas as gpd subzonegpd.read_file(MasterPlan2019PlanningAreaBoundaryNoSea.geojson) subzone 2 提取subzone 信息 …

从零开始的stable diffusion

stable diffusion真的是横空出世&#xff0c;开启了AIGC的元年。不知你是否有和我一样的困惑&#xff0c;这AI工具好像并不是那么听话&#xff1f; 前言 我们该如何才能用好stable diffusion这个工具呢&#xff1f;AI究竟在stable diffusion中承担了什么样的角色&#xff1f;如…

分享一个查询OpenAI Chatgpt key余额查询的工具网站

OpenAI Key 余额查询工具 欢迎使用 OpenAI Key 余额查询工具网站&#xff01;这个工具可以帮助您轻松地验证您的 OpenAI API 密钥&#xff0c;并查看您的余额。 http://tools.lbbit.top/check_key/ 什么是 OpenAI Key 余额查询工具&#xff1f; OpenAI Key 余额查询工具是一…

PCL点云处理之包含坐标、颜色信息的PFHRGB点特征直方图计算(二百一十六)

PCL点云处理之包含坐标、颜色信息的PFHRGB点特征直方图计算(二百一十六) 一、算法介绍二、代码实现一、算法介绍 在前文中计算了点特征直方图PFH,利用了点云的三维坐标信息,这里介绍考虑颜色信息的PFHRGB特征计算,对于该特征的使用可能有更好的效果,下面是具体的实现方法…

Java--基本语法

一、java转义字符 \t&#xff1a;一个制表符&#xff0c;实现对齐的功能\n&#xff1a;换行符\\&#xff1a;一个 \\"&#xff1a;一个“\&#xff1a;一个\r&#xff1a;一个回车 二、注释 单行注释&#xff1a; // 内容多行注释&#xff1a;/* 内容 */文档注释&#…

python实现图像的直方图均衡化

直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分配图像中的像素值&#xff0c;使得图像的像素值分布更加均匀&#xff0c;增强图像的对比度&#xff0c;从而改善图像的视觉效果。 直方图均衡化的过程如下&#xff1a; 灰度转换&#xff1a;如果图像是彩色…

手写单例模式

一、单例模式的定义 定义&#xff1a; 确保一个类只有一个实例&#xff0c;并提供该实例的全局访问点。 这样做的好处是&#xff1a;有些实例&#xff0c;全局只需要一个就够了&#xff0c;使用单例模式就可以避免一个全局使用的类&#xff0c;频繁的创建与销毁&#xff0c;耗…

露营装备经营商城小程序搭建

近几年露营人群逐渐增加&#xff0c;相应的装备商也多了起来&#xff0c;各种分类商品在一定程度上销量都非常不错&#xff0c;然而传统线下门店经营方面&#xff0c;面对的痛点也不少。 通过【雨科】平台搭建露营装备商城&#xff0c;让客户多场景平台随时购物&#xff0c;多流…

【Java学习之道】线程的概念与作用

引言 今天我们将探索多线程编程的基础概念和作用。对于初学者来说&#xff0c;掌握多线程编程是迈向Java高级技能的重要一步。通过本章的学习&#xff0c;你将了解线程是什么以及它在程序开发中的重要性&#xff0c;为你进一步深入学习和实际工作打下坚实的基础。让我们一起来…

基于SpringBoot的旅游网站开题报告

一、选题背景 随着旅游业的蓬勃发展和人们对旅游需求的增长&#xff0c;开发一个基于Spring Boot的旅游网站具有重要的意义。传统的旅行社模式逐渐不能满足人们个性化、多样化的旅游需求&#xff0c;因此开发一个在线旅游网站能够为用户提供更加便捷、灵活、个性化的旅游服务&…

《向量数据库指南》——Milvus Cloud和Elastic Cloud 特性对比

随着以 Milvus 为代表的向量数据库在 AI 产业界越来越受欢迎,诸如 Elasticsearch 之类的传统数据库和检索系统也开始行动起来,纷纷在快速集成专门的向量检索插件方面展开角逐。 例如,在提供类似插件的传统数据库中,Elasticsearch 8.0 首屈一指,推出了包括向量插入和最相似…