【Pytorch】Transposed Convolution

在这里插入图片描述

文章目录

  • 1 卷积
  • 2 反/逆卷积
  • 3 MaxUnpool / ConvTranspose
  • 4 encoder-decoder
  • 5 可视化

学习参考来自:

  • 详解逆卷积操作–Up-sampling with Transposed Convolution

  • PyTorch使用记录

  • https://github.com/naokishibuya/deep-learning/blob/master/python/transposed_convolution.ipynb

1 卷积

输入
在这里插入图片描述
卷积核

在这里插入图片描述

步长为 1,卷起来形式如下

在这里插入图片描述
输出的每个结果和输入的 9 个数值有关系

更直观的写成如下展开的矩阵乘形式

在这里插入图片描述

在这里插入图片描述
填零和 stride 与 kernel size 有关

2 反/逆卷积

相比逆卷积 (Deconvolution),转置卷积 (Transposed Convolution) 是一个更为合适的叫法

上述过程反过来,输入的一个数值与输出的 9 个数值有关

在这里插入图片描述

把原来的 W W W 转置一下即可实现该功能,当然转置后的 W W W 也是需要去学习更新的

在这里插入图片描述

矩阵乘可以看到,输入的每个值影响到了输出的 9 个值

3 MaxUnpool / ConvTranspose

搞个代码简单的看看效果

"maxpool"
m = nn.MaxPool2d(kernel_size=2, stride=2, padding=0, return_indices=True)
input_data = torch.tensor([[[[1, 2, 8, 7],[3, 4, 6, 5],[9, 10, 16, 15],[13, 14, 12, 11]
]]], dtype=torch.float32)
print(input_data.shape)  # torch.Size([1, 1, 4, 4])out, indices = m(input_data)
print(out, "\n", indices)

output

tensor([[[[ 4.,  8.],[14., 16.]]]]) tensor([[[[ 5,  2],[13, 10]]]])

在这里插入图片描述

"maxuppooling"
n = nn.MaxUnpool2d(kernel_size=2, stride=2, padding=0)
out = n(out, indices, output_size=input_data.size())
print(out)

output

tensor([[[[ 0.,  0.,  8.,  0.],[ 0.,  4.,  0.,  0.],[ 0.,  0., 16.,  0.],[ 0., 14.,  0.,  0.]]]])

在这里插入图片描述

在使用 MaxUnpool 的时候要特别注意, 需要在 maxpool 的时候保存 indices. 否则会报错

下面看看其在网络中的简单应用

import torch.nn as nn
import torch"MaxUnpool"
class ConvDAE(nn.Module):def __init__(self):super().__init__()# input: batch x 3 x 32 x 32 -> output: batch x 16 x 16 x 16self.encoder = nn.Sequential(nn.Conv2d(3, 16, 3, stride=1, padding=1),  # batch x 16 x 32 x 32nn.ReLU(),nn.BatchNorm2d(16),nn.MaxPool2d(2, stride=2, return_indices=True))self.unpool = nn.MaxUnpool2d(2, stride=2, padding=0)self.decoder = nn.Sequential(nn.ConvTranspose2d(16, 16, 3, stride=2, padding=1, output_padding=1),nn.ReLU(),nn.BatchNorm2d(16),nn.ConvTranspose2d(16, 3, 3, stride=1, padding=1, output_padding=0),nn.ReLU())def forward(self, x):out, indices = self.encoder(x)  # torch.Size([1, 16, 16, 16])out = self.unpool(out, indices)  # torch.Size([1, 16, 32, 32])out = self.decoder(out)  # torch.Size([1, 3, 64, 64])return out
if __name__ == "__main__":DAE = ConvDAE()x = torch.randn((1, 3, 32, 32))DAE(x)

网络结构比较简单,encoder 降低图片分辨率至 1/2,通道数不变

unpool 反 max pooling 恢复图片分辨率

decoder 反卷积提升图片分辨率

4 encoder-decoder

再看一个稍微复杂的 encoder-decoder 结构

class autoencoder(nn.Module):def __init__(self):super(autoencoder, self).__init__()# -------# encode# -------self.encode1 = nn.Sequential(# 第一层nn.Conv1d(kernel_size=25, in_channels=1, out_channels=32, stride=1, padding=12), # (1,784)->(32,784)nn.BatchNorm1d(32), # 加上BN的结果nn.ReLU(),nn.MaxPool1d(kernel_size=3, stride=3, padding=1, return_indices=True), # (32,784)->(32,262))self.encode2 = nn.Sequential(# 第二层nn.Conv1d(kernel_size=25, in_channels=32, out_channels=64, stride=1, padding=12), # (32,262)->(64,262)nn.BatchNorm1d(64),nn.ReLU(),nn.MaxPool1d(kernel_size=3, stride=3, padding=1, return_indices=True), # (batchsize,64,262)->(batchsize,64,88))self.encode3 = nn.Sequential(nn.Linear(in_features=88*64, out_features=1024),nn.Linear(in_features=1024, out_features=30))# -------# decode# -------self.unpooling1 = nn.MaxUnpool1d(kernel_size=3, stride=3, padding=1) # (batchsize,64,262)<-(batchsize,64,88)self.unpooling2 = nn.MaxUnpool1d(kernel_size=3, stride=3, padding=1) # (32,784)<-(32,262)self.decode1 = nn.Sequential(# 第一层nn.ReLU(),nn.BatchNorm1d(64),nn.ConvTranspose1d(kernel_size=25, in_channels=64, out_channels=32, stride=1, padding=12), # (32,262)<-(64,262))# 第二层self.decode2 = nn.Sequential(nn.ReLU(),nn.BatchNorm1d(32), # 加上BN的结果nn.ConvTranspose1d(kernel_size=25, in_channels=32, out_channels=1, stride=1, padding=12), # (1,784)<-(32,784))self.decode3 = nn.Sequential(nn.Linear(in_features=30, out_features=1024),nn.Linear(in_features=1024, out_features=88*64))def forward(self, x):# encodex = x.view(x.size(0),1,-1) # 将图片摊平 torch.Size([1, 1, 784])x,indices1 = self.encode1(x) # 卷积层 torch.Size([1, 32, 262])x,indices2 = self.encode2(x) # 卷积层 torch.Size([1, 64, 88])x = x.view(x.size(0), -1) # 展开 torch.Size([1, 5632])x = self.encode3(x) # 全连接层 torch.Size([1, 30])# decodex = self.decode3(x) # torch.Size([1, 5632])x = x.view(x.size(0), 64, 88)  # torch.Size([1, 64, 88])x = self.unpooling1(x, indices2)  # torch.Size([1, 64, 262])x = self.decode1(x)  # torch.Size([1, 32, 262])x = self.unpooling2(x, indices1) # torch.Size([1, 32, 784])x = self.decode2(x)  # torch.Size([1, 1, 784])return xif __name__ == "__main__":x = torch.randn((1, 1, 28, 28))autoencoder = autoencoder()autoencoder(x)

结构草图如下所示

请添加图片描述

主要展示的是 nn.ConvTransposenn.MaxUnpool 的运用,nn.MaxUnpool 要记得 indices

应用主要是 1d,2d 同理可以拓展

5 可视化

简单的实验,输入 MNIST 原始图片,conv+max pooling 下采样,maxunpooling+transposed conv 回原图,看看效果

载入相关库,载入数据集

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
import numpy as np
import cv2
import matplotlib.pyplot as plt
# Device configuration
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# Hyper-parameters
num_epochs = 5
batch_size = 100
learning_rate = 0.001# MNIST dataset
train_dataset = torchvision.datasets.MNIST(root='./',train=True,transform=transforms.ToTensor(),download=True)
test_dataset = torchvision.datasets.MNIST(root='./',train=False,transform=transforms.ToTensor())
# Data loader
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False)

图像可视化的前期工作

def imshow(img):npimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))

搭建神经网络,及其初始化

# 搭建网络
class CNNMNIST(nn.Module):def __init__(self):super(CNNMNIST,self).__init__()self.conv1 = nn.Conv2d(in_channels=1,out_channels=1,kernel_size=3,stride=1,padding=0)self.pool1 = nn.MaxPool2d(kernel_size=2,stride=2,padding=0,return_indices=True)self.unpool1 = nn.MaxUnpool2d(kernel_size=2,stride=2,padding=0)self.unconv1 = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)def forward(self,x):# encodeout = self.conv1(x)  # torch.Size([100, 1, 26, 26])out,indices = self.pool1(out)  # torch.Size([100, 1, 13, 13])# deocdeout = self.unpool1(out,indices,output_size=out1.size())  # torch.Size([100, 1, 26, 26])out = self.unconv1(out)  # torch.Size([100, 1, 28, 28])return out# 网络的初始化
model = CNNMNIST().to(device)
print(model)

output

CNNMNIST((conv1): Conv2d(1, 1, kernel_size=(3, 3), stride=(1, 1))(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(unpool1): MaxUnpool2d(kernel_size=(2, 2), stride=(2, 2), padding=(0, 0))(unconv1): ConvTranspose2d(1, 1, kernel_size=(3, 3), stride=(1, 1))
)

网络训练与保存

# 定义优化器和损失函数
criterion = nn.MSELoss(reduction='mean')
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# 进行训练
model.train()
total_step = len(train_loader)
for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):# Move tensors to the configured deviceimages = images.to(device)# Forward passoutputs = model(images)loss = criterion(outputs, images)# Backward and optimizeoptimizer.zero_grad()loss.backward()optimizer.step()if (i+1) % 100 == 0:# 计算Lossprint('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, total_step, loss.item()))"save model"
torch.save(model, "model.pkl")

output

Epoch [1/5], Step [100/600], Loss: 0.0764
Epoch [1/5], Step [200/600], Loss: 0.0549
Epoch [1/5], Step [300/600], Loss: 0.0457
Epoch [1/5], Step [400/600], Loss: 0.0468
Epoch [1/5], Step [500/600], Loss: 0.0443
Epoch [1/5], Step [600/600], Loss: 0.0452
Epoch [2/5], Step [100/600], Loss: 0.0445
Epoch [2/5], Step [200/600], Loss: 0.0427
Epoch [2/5], Step [300/600], Loss: 0.0407
Epoch [2/5], Step [400/600], Loss: 0.0432
Epoch [2/5], Step [500/600], Loss: 0.0414
Epoch [2/5], Step [600/600], Loss: 0.0413
Epoch [3/5], Step [100/600], Loss: 0.0415
Epoch [3/5], Step [200/600], Loss: 0.0420
Epoch [3/5], Step [300/600], Loss: 0.0425
Epoch [3/5], Step [400/600], Loss: 0.0413
Epoch [3/5], Step [500/600], Loss: 0.0416
Epoch [3/5], Step [600/600], Loss: 0.0414
Epoch [4/5], Step [100/600], Loss: 0.0401
Epoch [4/5], Step [200/600], Loss: 0.0409
Epoch [4/5], Step [300/600], Loss: 0.0418
Epoch [4/5], Step [400/600], Loss: 0.0412
Epoch [4/5], Step [500/600], Loss: 0.0407
Epoch [4/5], Step [600/600], Loss: 0.0405
Epoch [5/5], Step [100/600], Loss: 0.0411
Epoch [5/5], Step [200/600], Loss: 0.0412
Epoch [5/5], Step [300/600], Loss: 0.0406
Epoch [5/5], Step [400/600], Loss: 0.0407
Epoch [5/5], Step [500/600], Loss: 0.0409
Epoch [5/5], Step [600/600], Loss: 0.0401

模型载入,可视化结果

"load model"
model = torch.load("model.pkl")"visual"
dataiter = iter(train_loader)
images, lables = dataiter.next()imshow(torchvision.utils.make_grid(images, nrow=10))
plt.show()images = images.to(device)# Forward pass
outputs = model(images)
imshow(torchvision.utils.make_grid(outputs.cpu().squeeze(0), nrow=10))
plt.show()

MNIST 多图的可视化,可以借鉴借鉴,核心代码为 torchvision.utils.make_grid

部分输入
请添加图片描述
部分输出
请添加图片描述

换成纯卷积的失真率更少

class CNNMNIST(nn.Module):def __init__(self):super(CNNMNIST,self).__init__()self.conv1 = nn.Conv2d(in_channels=1,out_channels=1,kernel_size=3,stride=1,padding=0)self.conv2 = nn.Conv2d(in_channels=1,out_channels=1,kernel_size=2,stride=2,padding=0)self.unconv1 = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=2, stride=2, padding=0)self.unconv2 = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)def forward(self,x):# encodeout = self.conv1(x)  # torch.Size([100, 1, 26, 26])out = self.conv2(out)  # torch.Size([100, 1, 13, 13])# deocdeout = self.unconv1(out)  # torch.Size([100, 1, 26, 26])out = self.unconv2(out)  # torch.Size([100, 1, 28, 28])return out

输入
请添加图片描述

输出
请添加图片描述

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

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

相关文章

每天五分钟计算机视觉:Inception网络是由多个Inception模块构成

本文重点 inception从另一种角度来提升训练结果:能更高效的利用计算资源,在相同的计算量下能提取到更多的特征,从而提升训练结果。可以简单的理解为Inception 网络是由一个一个的Inception模块构建成的,我们来看一下。 Inception模块 如上就是Inception模块的 通过一个1…

采埃孚4D成像雷达拆解

1 基本信息 品牌&#xff1a;海外Tier1采埃孚 • 应用&#xff1a;上汽飞凡中高端纯电平台 • 数量&#xff1a;单车2个&#xff0c;安装在前后保内部 • 最远探测距离&#xff1a;350米 拆解来看&#xff0c;4D雷达主要可以分为4个部分&#xff0c;分别为数字接口板及结构件…

JAVA对文档加密

当 Word 文档中包含无法公开的机密信息时&#xff0c;我们可以对其进行加密&#xff0c;使其在没有密码的情况下无法打开。本文将向您介绍如何使用 Spire.Doc for Java 加密 Word 文档和移除 Word 密码保护。 加密 Word 文档删除 Word 密码保护 安装 Spire.Doc for Java 首先…

eclipse连接mysql数据库(下载eclipse,下载安装mysql,下载mysql驱动)

前言&#xff1a; 使用版本&#xff1a;eclipse2017&#xff0c;mysql5.7.0&#xff0c;MySQL的jar建议使用最新的&#xff0c;可以避免警告&#xff01; 1&#xff1a;下载安装&#xff1a;eclipse&#xff0c;mysql在我之前博客中有 http://t.csdnimg.cn/UW5fshttp://t.csdn…

云上丝绸之路| 云轴科技ZStack成功实践精选(西北)

古有“丝绸之路” 今有丝绸之路经济带 丝路焕发新生&#xff0c;数智助力经济 云轴科技ZStack用“云”护航千行百业 沿丝绸之路&#xff0c;领略西北数字化。 古丝绸之路起点-陕西 集历史与现代交融&#xff0c;不仅拥有悠久的历史文化积淀&#xff0c;而且现代化、数字化发…

【setDS】牛客小白月赛83 E

登录—专业IT笔试面试备考平台_牛客网 题意 思路 首先&#xff0c;一个必要步骤是把它转化为两个序列&#xff0c;这样就变成了一个序列DS问题 我们的答案是一个位置 pos 后面还有多少位置和这个位置的颜色相同&#xff0c;考虑得到这个答案我们需要维护什么东西 我们只需要…

Jmeter,提取响应体中的数据:正则表达式、Json提取器

一、正则表达式 1、线程组--创建线程组&#xff1b; 2、线程组--添加--取样器--HTTP请求&#xff1b; 3、Http请求--添加--后置处理器--正则表达式提取器&#xff1b; 4、线程组--添加--监听器--查看结果树&#xff1b; 5、线程组--添加--取样器--调试取样器。 响应体数据…

Axure动态面板的使用以及示例分享

目录 一. 什么是动态面板 二. 动态面板教程——以轮播图为例 2.1 创建动态面板 2.2 动态面板自适应大小 2.3 重复状态&#xff0c;将图片导入 2.4 添加交互事件——图片切换 2.5 效果展示 三. 多方式登录示例展示 四. 后台主界面左侧菜单栏示例展示 一. 什么是动态面板…

【C语言】C的面向对象

一、BREW接口实现 高通的BREW&#xff08;Binary Runtime Environment for Wireless&#xff09;是一个早期为手机设备开发的应用程序平台&#xff0c;用于开发在CDMA手机上运行的软件。尽管这个平台目前已经不太流行&#xff0c;但是在其使用高峰时期&#xff0c;开发者需要使…

vue2 tailwindcss jit模式下热更新失效

按照网上教程安装的tailwindcss&#xff0c;但是修改类名后热更新的时候样式没有生效&#xff0c;参考了大佬的文章&#xff0c;解决了该问题。 安装cross-env 修改前 "dev": " vue-cli-service serve", 修改后 "dev": "cross-env TAILWIN…

动手学深度学习-自然语言处理-预训练

词嵌入模型 将单词映射到实向量的技术称为词嵌入。 为什么独热向量不能表达词之间的相似性&#xff1f; 自监督的word2vec。 word2vec将每个词映射到一个固定长度的向量&#xff0c;这些向量能更好的表达不同词之间的相似性和类比关系。 word2vec分为两类&#xff0c;两类…

PPT插件-好用的插件-放映笔、绘图板-大珩助手

放映笔 幻灯片放映时&#xff0c;工具在幻灯片的左下方&#xff0c;本工具在幻灯片的右侧&#xff0c;可以移动&#xff0c;可以方便在右侧讲课时候使用 绘图板 可在绘图板上写签名、绘制图画、写字等等&#xff0c;点画笔切换橡皮擦&#xff0c;点插入绘图&#xff0c;将背景…

车载以太网笔记

文章目录 以太网协议分层协议中间设备子网掩码物理层测试内容比较杂,后续会整理。 以太网协议分层 协议 中间设备

智能高效|AIRIOT智慧货运管理解决方案

随着全球贸易的增加和消费需求的不断扩大&#xff0c;货运行业面临更大的压力&#xff0c;传统货运行业运输效率低下、信息不透明&#xff0c;往往存在如下的运维问题和管理痛点&#xff1a; 无法实时定位和追踪信息&#xff1a;无法提供实时的货物位置信息&#xff0c;以便随…

布局前沿技术,紫光展锐推动6G创新融合发展

随着5G进入规模化商用阶段&#xff0c;6G研究已在全球范围内拉开帷幕。2023年6月&#xff0c;ITU发布了《IMT面向2030及未来发展的框架和总体目标建议书》&#xff0c;在升级5G三大应用场景的同时&#xff0c;扩展出三个跨领域场景&#xff0c;形成6G的六大应用场景&#xff0c…

Axios入门案例——后端学习

目录 后端准备 导入依赖 解决跨域 User实体类 DemoController测试接口 前端准备 项目结构 axios.js axios.html 开始测试 后端结果 前端结果 后端准备 导入依赖 案例会用到以下的三个依赖。 <dependency><groupId>org.springframework.boot</gro…

WIFI标签注册流程

WIFI桌牌 K: 注册键&#xff0c;R: 复位键 长按K键不动&#xff0c;绿灯长亮&#xff0c;再按一下R键&#xff0c;等待绿灯快闪后就可以松开按键&#xff0c;绿灯变慢闪&#xff0c;设备即可进入配置注册模式。 4.2寸WiFi标签 右键: 注册键&#xff0c;背后键: 复位键 长按右…

Github 2023-12-16开源项目日报Top10

根据Github Trendings的统计&#xff0c;今日(2023-12-16统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目2非开发语言项目2TypeScript项目1Jupyter Notebook项目1Go项目1PHP项目1JavaScript项目1C#项目1 精…

LeetCode:2415. 反转二叉树的奇数层(层次遍历 Java)

目录 2415. 反转二叉树的奇数层 题目描述&#xff1a; 实现代码与解析&#xff1a; BFS 原理思路&#xff1a; 2415. 反转二叉树的奇数层 题目描述&#xff1a; 给你一棵 完美 二叉树的根节点 root &#xff0c;请你反转这棵树中每个 奇数 层的节点值。 例如&#xff0c;…

【JVM从入门到实战】(七)运行时数据区的组成

运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域&#xff0c;称之为运行时数据区。 《Java虚拟机规范》中规定了每一部分的作用 线程不共享&#xff1a;程序计数器、虚拟机栈、本地方法栈 线程共享&#xff1a;方法区&#xff0c;堆 1. 程序计数器(Program Count…