【深度学习】TCN,An Empirical Evaluation of Generic Convolutional【二】

news2024/11/24 8:46:30

文章目录

  • 膨胀卷积
      • 什么是膨胀卷积
      • 膨胀卷积公式
      • PyTorch代码
  • 从零开始手动实现一个1D膨胀卷积,不使用PyTorch的`nn.Conv1d`
      • 1. 基本概念
      • 2. 手动实现1D膨胀卷积
  • TCN结构
  • 如何使用TCN
      • 源码说明
        • 1. Chomp1d 类
        • 2. TemporalBlock 类
        • 3. TemporalConvNet 类
      • 使用方法

膨胀卷积

什么是膨胀卷积

膨胀卷积(Dilated Convolution),也称为空洞卷积(Atrous Convolution),是在标准卷积的基础上通过引入膨胀因子(dilation factor)来扩展感受野,而不增加参数数量或计算复杂度。膨胀卷积通过在滤波器的每两个元素之间插入空洞(即,零值)来实现这一点。

膨胀卷积公式

膨胀卷积的数学公式如下:

F ( s ) = ( x ∗ d f ) ( s ) = ∑ i = 0 k − 1 f ( i ) ⋅ x s − d ⋅ i F(s) = (x *_d f)(s) = \sum_{i=0}^{k-1} f(i) \cdot x_{s - d \cdot i} F(s)=(xdf)(s)=i=0k1f(i)xsdi

其中:

  • (x) 是输入信号。
  • (f) 是卷积滤波器。
  • (s) 是输出信号的位置。
  • (d) 是膨胀因子,表示滤波器元素之间的间隔。
  • (k) 是滤波器的大小。

当 (d=1) 时,膨胀卷积退化为标准卷积。

PyTorch代码

下面是一个使用PyTorch实现膨胀卷积的示例:

import torch
import torch.nn as nn

class DilatedConv1D(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, dilation):
        super(DilatedConv1D, self).__init__()
        self.dilated_conv = nn.Conv1d(
            in_channels=in_channels,
            out_channels=out_channels,
            kernel_size=kernel_size,
            dilation=dilation,
            padding=(kernel_size - 1) * dilation // 2
        )

    def forward(self, x):
        return self.dilated_conv(x)

# 示例输入
batch_size = 1
in_channels = 1
seq_length = 10

x = torch.randn(batch_size, in_channels, seq_length)

# 创建膨胀卷积层
dilated_conv_layer = DilatedConv1D(in_channels=1, out_channels=1, kernel_size=3, dilation=2)

# 前向传播
output = dilated_conv_layer(x)
print(output)

从零开始手动实现一个1D膨胀卷积,不使用PyTorch的nn.Conv1d

1. 基本概念

膨胀卷积的公式为:

y [ t ] = ∑ k x [ t − k ⋅ d ] ⋅ w [ k ] y[t] = \sum_{k} x[t - k \cdot d] \cdot w[k] y[t]=kx[tkd]w[k]

其中:

  • y [ t ] y[t] y[t] 是输出信号。
  • x [ t ] x[t] x[t] 是输入信号。
  • w [ k ] w[k] w[k] 是卷积核的权重。
  • d d d 是膨胀率。

2. 手动实现1D膨胀卷积

下面是手动实现1D膨胀卷积的Python代码:

import torch
import torch.nn as nn
import torch.nn.functional as F

class ManualDilatedConv1D(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, dilation=1):
        super(ManualDilatedConv1D, self).__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.kernel_size = kernel_size
        self.dilation = dilation

        # 初始化卷积核权重
        self.weight = nn.Parameter(torch.randn(out_channels, in_channels, kernel_size))
        self.bias = nn.Parameter(torch.randn(out_channels))

    def forward(self, x):
        batch_size, in_channels, length = x.shape
        assert in_channels == self.in_channels

        # 计算输出的长度
        out_length = length - (self.kernel_size - 1) * self.dilation

        # 初始化输出张量
        out = torch.zeros(batch_size, self.out_channels, out_length)

        # 对每个输出通道进行卷积
        for b in range(batch_size):
            for o in range(self.out_channels):
                for i in range(out_length):
                    sum = 0
                    for k in range(self.kernel_size):
                        sum += x[b, :, i + k * self.dilation] * self.weight[o, :, k]
                    out[b, o, i] = sum + self.bias[o]
        return out

# 示例参数
in_channels = 1
out_channels = 1
kernel_size = 3
dilation = 2

# 创建一个输入张量 (batch_size, channels, length)
input_tensor = torch.randn(1, in_channels, 10)

# 创建手动膨胀卷积层
manual_dilated_conv = ManualDilatedConv1D(in_channels, out_channels, kernel_size, dilation)

# 前向传播
output_tensor = manual_dilated_conv(input_tensor)

print(output_tensor)

TCN结构

在这里插入图片描述

import torch
import torch.nn as nn
from torch.nn.utils import weight_norm


class Chomp1d(nn.Module):
    def __init__(self, chomp_size):
        super(Chomp1d, self).__init__()
        self.chomp_size = chomp_size

    def forward(self, x):
        return x[:, :, :-self.chomp_size].contiguous()


class TemporalBlock(nn.Module):
    def __init__(self, n_inputs, n_outputs, kernel_size, stride, dilation, padding, dropout=0.2):
        super(TemporalBlock, self).__init__()
        self.conv1 = weight_norm(nn.Conv1d(n_inputs, n_outputs, kernel_size,
                                           stride=stride, padding=padding, dilation=dilation))
        self.chomp1 = Chomp1d(padding)
        self.relu1 = nn.ReLU()
        self.dropout1 = nn.Dropout(dropout)

        self.conv2 = weight_norm(nn.Conv1d(n_outputs, n_outputs, kernel_size,
                                           stride=stride, padding=padding, dilation=dilation))
        self.chomp2 = Chomp1d(padding)
        self.relu2 = nn.ReLU()
        self.dropout2 = nn.Dropout(dropout)

        self.net = nn.Sequential(self.conv1, self.chomp1, self.relu1, self.dropout1,
                                 self.conv2, self.chomp2, self.relu2, self.dropout2)
        self.downsample = nn.Conv1d(n_inputs, n_outputs, 1) if n_inputs != n_outputs else None
        self.relu = nn.ReLU()
        self.init_weights()

    def init_weights(self):
        self.conv1.weight.data.normal_(0, 0.01)
        self.conv2.weight.data.normal_(0, 0.01)
        if self.downsample is not None:
            self.downsample.weight.data.normal_(0, 0.01)

    def forward(self, x):
        out = self.net(x)
        res = x if self.downsample is None else self.downsample(x)
        return self.relu(out + res)


class TemporalConvNet(nn.Module):
    def __init__(self, num_inputs, num_channels, kernel_size=2, dropout=0.2):
        super(TemporalConvNet, self).__init__()
        layers = []
        num_levels = len(num_channels)
        for i in range(num_levels):
            dilation_size = 2 ** i
            in_channels = num_inputs if i == 0 else num_channels[i-1]
            out_channels = num_channels[i]
            layers += [TemporalBlock(in_channels, out_channels, kernel_size, stride=1, dilation=dilation_size,
                                     padding=(kernel_size-1) * dilation_size, dropout=dropout)]

        self.network = nn.Sequential(*layers)

    def forward(self, x):
        return self.network(x)

如何使用TCN

以下是如何使用上述Temporal Convolutional Network (TCN) 代码的详细讲解和步骤:

源码说明

1. Chomp1d 类

Chomp1d类用于从输入的末端裁剪指定大小的时间步长。

class Chomp1d(nn.Module):
    def __init__(self, chomp_size):
        super(Chomp1d, self).__init__()
        self.chomp_size = chomp_size

    def forward(self, x):
        return x[:, :, :-self.chomp_size].contiguous()
2. TemporalBlock 类

TemporalBlock类构建了一个基础的时间卷积模块,包括两个卷积层,每个卷积层后都有一个Chomp1d、ReLU激活函数和Dropout。

class TemporalBlock(nn.Module):
    def __init__(self, n_inputs, n_outputs, kernel_size, stride, dilation, padding, dropout=0.2):
        super(TemporalBlock, self).__init__()
        self.conv1 = weight_norm(nn.Conv1d(n_inputs, n_outputs, kernel_size,
                                           stride=stride, padding=padding, dilation=dilation))
        self.chomp1 = Chomp1d(padding)
        self.relu1 = nn.ReLU()
        self.dropout1 = nn.Dropout(dropout)

        self.conv2 = weight_norm(nn.Conv1d(n_outputs, n_outputs, kernel_size,
                                           stride=stride, padding=padding, dilation=dilation))
        self.chomp2 = Chomp1d(padding)
        self.relu2 = nn.ReLU()
        self.dropout2 = nn.Dropout(dropout)

        self.net = nn.Sequential(self.conv1, self.chomp1, self.relu1, self.dropout1,
                                 self.conv2, self.chomp2, self.relu2, self.dropout2)
        self.downsample = nn.Conv1d(n_inputs, n_outputs, 1) if n_inputs != n_outputs else None
        self.relu = nn.ReLU()
        self.init_weights()

    def init_weights(self):
        self.conv1.weight.data.normal_(0, 0.01)
        self.conv2.weight.data.normal_(0, 0.01)
        if self.downsample is not None:
            self.downsample.weight.data.normal_(0, 0.01)

    def forward(self, x):
        out = self.net(x)
        res = x if self.downsample is None else self.downsample(x)
        return self.relu(out + res)
3. TemporalConvNet 类

TemporalConvNet类将多个TemporalBlock组合在一起,形成完整的TCN模型。

class TemporalConvNet(nn.Module):
    def __init__(self, num_inputs, num_channels, kernel_size=2, dropout=0.2):
        super(TemporalConvNet, self).__init__()
        layers = []
        num_levels = len(num_channels)
        for i in range(num_levels):
            dilation_size = 2 ** i
            in_channels = num_inputs if i == 0 else num_channels[i-1]
            out_channels = num_channels[i]
            layers += [TemporalBlock(in_channels, out_channels, kernel_size, stride=1, dilation=dilation_size,
                                     padding=(kernel_size-1) * dilation_size, dropout=dropout)]

        self.network = nn.Sequential(*layers)

    def forward(self, x):
        return self.network(x)

使用方法

  1. 准备输入数据
    TCN适用于一维序列数据,如时间序列。输入数据的形状应该是(batch_size, num_inputs, sequence_length)

  2. 初始化模型
    定义模型的输入通道数num_inputs,每一层的输出通道数列表num_channels,卷积核大小kernel_sizedropout比例。

num_inputs = 10  # 输入通道数,例如10个特征
num_channels = [16, 32, 64]  # 每个TemporalBlock的输出通道数
kernel_size = 2
dropout = 0.2

model = TemporalConvNet(num_inputs, num_channels, kernel_size, dropout)
  1. 训练模型
    使用PyTorch常规的训练步骤,定义损失函数和优化器,然后进行前向传播、计算损失、反向传播和参数更新。
# 示例:随机生成输入数据
batch_size = 8
sequence_length = 30
input_data = torch.randn(batch_size, num_inputs, sequence_length)

# 模型输出
output = model(input_data)
print(output.shape)  # 输出形状为(batch_size, num_channels[-1], sequence_length)

batch_size, num_inputs, 和 sequence_length 是与输入数据和模型有关的参数。以下是对它们的详细解释:

  • batch_size:

    • 表示每次输入模型的样本数量。
    • 例如,如果你有1000个样本数据,并且你希望每次输入模型进行训练时处理32个样本,那么batch_size将是32。
    • 这个参数通常用于加速训练过程,并使得计算更高效,因为可以利用并行计算。
  • num_inputs:

    • 表示输入数据的特征数量或通道数。
    • 在时间序列数据中,通常每个时间步可能包含多个特征。例如,如果你的时间序列数据在每个时间步包含温度和湿度两个特征,那么num_inputs将是2。
    • 对于一维时间序列数据,如果每个时间步只有一个值(如单变量时间序列),则num_inputs为1。
  • sequence_length:

    • 表示时间序列的长度,即每个样本中包含的时间步数。
    • 例如,如果你有一个每天记录温度的时间序列数据,记录了30天的数据,那么sequence_length将是30。
    • 这个参数决定了输入数据的时间维度长度。
  1. 定义损失函数和优化器
    可以使用MSELoss或其他适合具体任务的损失函数。
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 示例:随机生成目标数据
target_data = torch.randn(batch_size, num_channels[-1], sequence_length)

# 前向传播
output = model(input_data)

# 计算损失
loss = criterion(output, target_data)

# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()

print('Loss:', loss.item())

以上是如何使用Temporal Convolutional Network (TCN)代码的详细步骤和示例。通过这些步骤,你可以定义并训练一个TCN模型来处理一维序列数据。

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

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

相关文章

Unity 3D 物体的Inspector面板

1、Transform:位置、旋转、大小 2、Mesh Filter:物体的形状 3、Mesh Renderer:物体渲染(物体的衣服) 4、Collider:碰撞体

python错题(1)

字典中min,max最后比较的是键,输出的是键

python12 元组类型

元组用 () 声明,注意如果只有一个元素时要在元素后面加个 逗号, 否则不是类型就不是元组了。 声明方式2内置函数声明 data tuple(helloworld); 元组是不可变列表, 元组可以使用序列的所有功能。具体可以看我以前序列的文章 元组里的元素可以是多种数据类…

Python爬虫JS逆向进阶课程

这门课程是Python爬虫JS逆向进阶课程,将教授学员如何使用Python爬虫技术和JS逆向技术获取网站数据。学习者将学习如何分析网站的JS代码,破解反爬虫机制,以及如何使用Selenium和PhantomJS等工具进行模拟登录和数据抓取。课程结合实例演练和项目…

物流货运单怎么打印,佳易王货物运单打印查询统计管理系统操作教程

物流货运单怎么打印,佳易王货物运单打印查询统计管理系统操作教程 一、前言 以下软件操作教程以,佳易王物流货运单管理软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 软件操作教程 1、物流开单点击导航栏 物流开单…

C++ 58 之 计算器案例

虚函数,vitual function C动态多态性是通过虚函数来实现的,虚函数允许子类(派生类)重新定义父类(基类)成员函数,而子类(派生类)重新定义父类(基类)虚函数的做…

非接触式装配监控技术实现对装配工作站操作的实时动作识别和定位

当今快速发展的工业领域,智能制造作为第四次工业革命的核心,正引领着生产方式的革新。智能制造的关键在于实时监控和数据分析,这不仅能优化生产流程,还能显著提升产品质量和生产效率。其中,装配操作的实时监控对于制造…

配置Linux DNS服务器作为自己的windows 的 DNS服务器和 配置遇到的问题

安装DNS 库 和 DNS工具: # bind 是用于创建 dns服务的, bind-utils是用于测试DNS服务的工具 yum -y install bind bind-utils配置主配置文件: # 下载好后就已经有DNS服务,但是需要你自己去配置DNS服务信息# 配置主配置文件 [rootl…

Parallelize your massive SHAP computations with MLlib and PySpark

https://medium.com/towards-data-science/parallelize-your-massive-shap-computations-with-mllib-and-pyspark-b00accc8667c (能翻墙直接看原文) A stepwise guide for efficiently explaining your models using SHAP. Photo by Pietro Jeng on Unsplash Int…

ThinkPHP邮件发送配置教程?怎么配置群发?

ThinkPHP邮件发送安全性如何保障?ThinkPHP如何实现? 无论是用户注册后的验证邮件,还是订单处理的通知邮件,都需要一个可靠的邮件发送机制。AokSend将详细介绍如何在ThinkPHP框架中配置邮件发送功能,并带您逐步了解其中…

第十九篇——信噪比:历史有真相嘛?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 对于信噪比的理解,通过历史是否有真相这个故事来表达信号和噪…

Docker Jenkins(改错版本)

Devops:它强调开发(Development)和运维(Operations)团队之间的协作.实现更快,更可靠的软件交付部署. JenKins是一个开源的自动化服务器,广泛用于构建,测试和部署软件项目.它是持续集成(CI)和持续交付/部署(CD)的工具.JenKins是实现DevOps实践的重要工具. 前端项目部署一般流程:…

CTFshow-web sql注入

Web171 1 在题目中可以看到查询语句为 "select username,password from user where username !flag and id ".$_GET[id]." limit 1;"; 直接使用万能密码 查到了所有用户 获得flag Web172 0 可以看到返回逻辑显示 如果返回的查询数据中username不等于fl…

【JavaEE精炼宝库】多线程(6)线程池

目录 一、线程池的概念及优势 1.1 线程池的概念: 1.2 线程池的优势: 二、工厂模式 三、标准库中的线程池 3.1 标准库线程池参数解释: 3.1.1 corePoolSize | maximumPoolSize: 3.1.2 keepAliveTime | unit: 3.1…

String常用方法详解

auth:别晃我的可乐 date:2024年06月16日 比较大小 equals(Object obj): 用于比较字符串内容是否相等。compareTo(String anotherString): 按字典顺序比较两个字符串。 String str1 "hello"; String str2 "world";boolean isEqual …

Python-random模块

一、random模块的用法 import randomprint(random.random()) # 不需要传参,random 返回0-1随机小数print(random.uniform(1, 10)) # 需要传参,返回参数区间的随机小数print(random.randint(-100, 100)) # 需要传参,返回参数区间的随机整数…

APP抓包渗透测试首尝试

前言 文章分为两大部分,一是介绍抓取app数据包的常用方法,二是结合笔者所接触的授权项目,对抓取的app数据包转传统Web渗透测试的小分享。通过阅读文章分享内容,读者能快速了解app渗透测试方式,初步入门APP抓包渗透测试…

禁止methtype联网

mathtype断网_如何禁止mathtype联网-CSDN博客https://blog.csdn.net/qq_41060221/article/details/128144783

03-QTWebEngine中使用qtvirtualkeyboard

qt提供了 virtualKeyboard 虚拟键盘模块,只需要在在main函数中最开始加入这样一句就可以了 qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); 但是在使用的时候遇到了一些问题: 1、中文输入的时候没有输入提示 Qvirt…