如何手动实现pytorch卷积的填充 torch.nn.functional.padinput,padding_size,mode ='constant',value = 0: tensorflow.padinput,padding_size,mode ='CONSTANT',name = None,constant_values = 0 output_size =input_size-1 stride +kerenel_size-1

如何解决如何手动实现pytorch卷积的填充 torch.nn.functional.padinput,padding_size,mode ='constant',value = 0: tensorflow.padinput,padding_size,mode ='CONSTANT',name = None,constant_values = 0 output_size =input_size-1 stride +kerenel_size-1

我试图将一些pytorch代码移植到tensorflow 2.0,并且很难弄清楚如何在两者之间转换卷积函数。这两个库处理填充的方式是症结所在。基本上,我想了解如何手动生成pytorch在后台进行的填充,以便将其转换为tensorflow。

如果我不进行任何填充,下面的代码将起作用,但是一旦添加任何填充,我就无法弄清楚如何使这两种实现相匹配。

output_padding = SOME NUMBER
padding = SOME OTHER NUMBER
strides = 128

tensor = np.random.rand(2,258,249)
filters = np.random.rand(258,1,256)

out_torch = F.conv_transpose1d(
    torch.from_numpy(tensor).float(),torch.from_numpy(filters).float(),stride=strides,padding=padding,output_padding=output_padding)

def pytorch_transpose_conv1d(inputs,filters,strides,padding,output_padding):
    N,L_in = inputs.shape[0],inputs.shape[2]
    out_channels,kernel_size = filters.shape[1],filters.shape[2]
    time_out = (L_in - 1) * strides - 2 * padding + (kernel_size - 1) + output_padding + 1
    padW = (kernel_size - 1) - padding
    
    # HOW DO I PAD HERE TO GET THE SAME OUTPUT AS IN PYTORCH
    inputs = tf.pad(inputs,[(?,?),(?,?)])

    return tf.nn.conv1d_transpose(
        inputs,tf.transpose(filters,perm=(2,0)),output_shape=(N,out_channels,time_out),strides=strides,padding="VALID",data_format="NCW")

out_tf = pytorch_transpose_conv1d(tensor,output_padding)
assert np.allclose(out_tf.numpy(),out_torch.numpy())

解决方法

填充


要在 Pytorch Tensorflow 之间翻译卷积和转置卷积函数(使用填充 padding ),我们需要先了解F.pad()tf.pad()函数。

torch.nn.functional.pad(input,padding_size,mode ='constant',value = 0):

  • padding size:从last dimension开始逐步描述填充某些输入尺寸所用的填充大小。
  • 仅填充输入张量的last dimension,然后pad的格式为((padding_left,padding_right)
  • 填充last 3 dimensions(padding_left,padding_right,padding_top,padding_bottom,padding_front,padding_back)

tensorflow.pad(input,padding_size,mode ='CONSTANT',name = None,constant_values = 0)

  • padding_size:是形状为[n,2]的整数张量,其中n是张量的秩。对于输入的每个维度D,paddings [D,0]指示在该维度中张量的内容之前要添加多少个值,而paddings [D,1]指示在该维度中张量的内容之后要添加多少个值。

这是代表F.pad和tf.pad 等效项的表,以及输入张量的输出张量
[[[1,1],[1,1]]]的形状为(1,2,2)

enter image description here


卷积填充


现在让我们转到卷积层中的PyTorch填充

  1. F.conv1d(input,...,padding,...):

    • 填充控制both sides上隐式填充的数量,以填充点数。
    • padding=(size)应用F.pad(input,[size,size]),即填充最后一个尺寸,其尺寸(尺寸,大小)等于tf.pad(input,[[0,0],[0,size]])
  2. F.conv2d(input,...,padding,...):

    • padding=(size)应用F.pad(input,size,size]),即填充最后2 个维度,其(大小,大小)等于tf.pad(input,size],size]])
    • padding=(size1,size2)应用F.pad(input,[size2,size2,size1,size1]),它等效于tf.pad(input,[size1,size1],size2]])

转置卷积中的填充


转置卷积层中的PyTorch填充

  1. F.conv_transpose1d(input,...,padding,output_padding,...):
    • dilation * (kernel_size - 1) - padding填充将添加到输入中每个维度的both侧。
    • Padding卷积中的
    • transposed可被视为分配fake的{​​{1}}输出
    • removed控制添加到输出形状一侧的其他尺寸
    • 检查 this 以了解output_paddingtranspose convolution期间到底发生了什么。
    • 这是计算转置卷积输出大小的公式:

output_size =(input_size-1) stride +(kerenel_size-1)+ 1 + output_padding-2 padding


代码


转置卷积

pytorch

结果

import torch
import torch.nn as nn
import torch.nn.functional as F
import tensorflow as tf
import numpy as np

# to stop tf checkfailed error not relevent to actual code
import os
os.environ["CUDA_DEVICE_ORDER"]    = "PCI_BUS_ID"   
os.environ["CUDA_VISIBLE_DEVICES"] = "1"




def tconv(tensor,filters,output_padding=0,padding=0,strides=1):
    '''
    tensor         : input tensor of shape (batch_size,channels,W) i.e (NCW)
    filters        : input kernel of shape (in_ch,out_ch,kernel_size)
    output_padding : single number must be smaller than either stride or dilation
    padding        : single number should be less or equal to ((valid output size + output padding) // 2)
    strides        : single number
    '''
    bs,in_ch,W = tensor.shape
    in_ch,k_sz = filters.shape
    
    out_torch = F.conv_transpose1d(torch.from_numpy(tensor).float(),torch.from_numpy(filters).float(),stride=strides,padding=padding,output_padding=output_padding)
    out_torch = out_torch.numpy()
 
    # output_size = (input_size - 1)*stride + (kerenel_size - 1) + 1 + output_padding - 2*padding
    # valid out size -> padding=0,output_padding=0 
    # -> valid_out_size =  (input_size - 1)*stride + (kerenel_size - 1) + 1
    out_size  = (W - 1)*strides + (k_sz - 1) + 1 

    # input shape -> (batch_size,W,in_ch) and filters shape -> (kernel_size,in_ch) for tf conv
    valid_tf  = tf.nn.conv1d_transpose(np.transpose(tensor,axes=(0,1)),np.transpose(filters,axes=(2,1,0)),output_shape=(bs,out_size,out_ch),strides=strides,padding='VALID',data_format='NWC')
    # output padding
    tf_outpad = tf.pad(valid_tf,output_padding],0]])
    # NWC to NCW
    tf_outpad = np.transpose(tf_outpad,(0,1))

    # padding -> input,begin,shape -> remove `padding` elements on both side
    out_tf    = tf.slice(tf_outpad,padding],[bs,tf_outpad.shape[2]-2*padding])

    out_tf    = np.array(out_tf)

    print('output size(tf,torch):',out_tf.shape,out_torch.shape)
    # print('out_torch:\n',out_torch)
    # print('out_tf:\n',out_tf)
    print('outputs are close:',np.allclose(out_tf,out_torch))



tensor  = np.random.rand(2,7)
filters = np.random.rand(1,3)
tconv(tensor,output_padding=2,padding=5,strides=3)

一些有用的链接:

  1. 火炬'SAME'卷积

  2. pytorch transpose转换如何工作

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-