机器学习进阶之 时域/时间卷积网络 TCN 概念+由来+原理+代码实现

2023-05-16

TCN 从“阿巴阿巴”到“巴拉巴拉”

  • TCN的概念(干嘛来的!能解决什么问题)
  • TCN的父母(由来)
  • TCN的原理介绍
  • 上代码!

1、TCN(时域卷积网络、时间卷积网络)是干嘛的,能干嘛

  • 主要应用方向:

时序预测、概率预测、时间预测、交通预测

2、TCN的由来

ps:在了解TCN之前需要先对CNN和RNN有一定的了解。

  • 处理问题:

是一种能够处理时间序列数据的网络结构,在特定条件下,效果优于传统的神经网络(RNN、CNN等)。

3、TCN的原理介绍

TCN 的网络结构

请添加图片描述

一、TCN的网络结构主要由上图构成。本文分为左边和右边两部分,首先是左边

Dilated Causal Conv ---> WeightNorm--->ReLU--->Dropout--->Dilated Causal Conv ---> WeightNorm--->ReLU--->Dropout

很明显这个可以分为

(Dilated Causal Conv ---> WeightNorm--->ReLU--->Dropout)*2

ok,下面我们对这四个逐个进行讲解,如有了解可以选择跳读

1、Dilated Gausal Conv

中文名:膨胀因果卷积

膨胀因果卷积可以分为膨胀因果卷积三部分。

卷积是指 CNN中的卷积,是指卷积核在数据上进行的一种滑动运算操作;

膨胀是指 允许卷积时的输入存在间隔采样,其和卷积神经网络中的stride有相似之处,但也有很明显的区别

图片说明:

请添加图片描述

因果是指 第i层中t时刻的数据,只依赖与(i-1)层t时刻及其以前的值的影响。因果卷积可以在训练的时候摒弃掉对未来数据的读取,是一种严格的时间约束模型。

图片说明:

请添加图片描述

​ (ps:没有加入膨胀卷积)

2、WeightNorm

权重归一化

对权重值进行归一化,如果有想仔细研究归一化过程&归一化公式的,可以点击链接进行学习

点击

优点:

1、时间开销小,运算速度快!

2、引入更少的噪声

3、WeightNorm是通过重写深度网络的权重来进行加速的,没有引入对minibatch的依赖

3、ReLU()

激活函数的一种

优点:

1、可以使网络的训练速度更快

2、增加网络的非线性,提高模型的表达能力

3、防止梯度消失,

4、使网络具有稀疏性等

公式:

在这里插入图片描述

概述图:

ReLU 函数

4、Dropout()

Dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。

优点:防止过拟合,提高模型的运算速度

二、最后是右边-残差连接

右边是一个1*1的卷积块儿,不仅可以使网络拥有跨层传递信息的功能,而且可以保证输入输出的一致性。

三、TCN的优点:

1、并行性

2、可以很大程度上避免梯度消失和梯度爆炸

3、感受野更大,学习到的信息更多

4、从零coding

import os
import sys
import paddle
import paddle.nn as nn
import numpy as np
import pandas as pd
import seaborn as sns
from pylab import rcParams
import matplotlib.pyplot as plt
from matplotlib import rc
import paddle.nn.functional as F
from paddle.nn.utils import weight_norm
from sklearn.preprocessing import MinMaxScaler
from pandas.plotting import register_matplotlib_converters
from sourceCode import TimeSeriesNetwork
sys.path.append(os.path.abspath(os.path.join(os.getcwd(), "../..")))

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

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


class TemporalBlock(nn.Layer):
    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))
        # Chomp1d is used to make sure the network is causal.
        # We pad by (k-1)*d on the two sides of the input for convolution,
        # and then use Chomp1d to remove the (k-1)*d output elements on the right.
        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.set_value(
            paddle.tensor.normal(0.0, 0.01, self.conv1.weight.shape))
        self.conv2.weight.set_value(
            paddle.tensor.normal(0.0, 0.01, self.conv2.weight.shape))
        if self.downsample is not None:
            self.downsample.weight.set_value(
                paddle.tensor.normal(0.0, 0.01, self.downsample.weight.shape))

    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 TCNEncoder(nn.Layer):
    def __init__(self, input_size, num_channels, kernel_size=2, dropout=0.2):
        # input_size : 输入的预期特征数
        # num_channels: 通道数
        # kernel_size: 卷积核大小
        super(TCNEncoder, self).__init__()
        self._input_size = input_size
        self._output_dim = num_channels[-1]

        layers = nn.LayerList()
        num_levels = len(num_channels)
        # print('print num_channels: ', num_channels)
        # print('print num_levels: ',num_levels)
        # exit(0)
        for i in range(num_levels):
            dilation_size = 2 ** i
            in_channels = input_size if i == 0 else num_channels[i - 1]
            out_channels = num_channels[i]
            layers.append(
                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 get_input_dim(self):
        return self._input_size



    def get_output_dim(self):
        return self._output_dim

    def forward(self, inputs):
        inputs_t = inputs.transpose([0, 2, 1])
        output = self.network(inputs_t).transpose([2, 0, 1])[-1]
        return output


class TimeSeriesNetwork(nn.Layer):

    def __init__(self, input_size, next_k=1, num_channels=[256]):
        super(TimeSeriesNetwork, self).__init__()

        self.last_num_channel = num_channels[-1]

        self.tcn = TCNEncoder(
            input_size=input_size,
            num_channels=num_channels,
            kernel_size=3,
            dropout=0.2
        )

        self.linear = nn.Linear(in_features=self.last_num_channel, out_features=next_k)

    def forward(self, x):
        tcn_out = self.tcn(x)
        y_pred = self.linear(tcn_out)
        return y_pred
'''
我努力把自己塑造成悲剧里面的男主角,
把一切过错推到你的身上,
让你成为万恶的巫婆,
丧心病狂
可是我就是一个正常的人,
有悲有喜,
有错有对,
走到今天这个地步,
我们都有责任,
直到现在我还没有觉得我失去了你
你告诉我,我失去你了么?
'''
def config_mtp():
    sns.set(style='whitegrid', palette='muted', font_scale=1.2)
    HAPPY_COLORS_PALETTE = ["#01BEFE", "#FFDD00", "#FF7D00", "#FF006D", "#93D30C", "#8F00FF"]
    sns.set_palette(sns.color_palette(HAPPY_COLORS_PALETTE))
    rcParams['figure.figsize'] = 14, 10
    register_matplotlib_converters()

def read_data():
    df_all = pd.read_csv('./data/time_series_covid19_confirmed_global.csv')
    # print(df_all.head())

    # 我们将对全世界的病例数进行预测,因此我们不需要关心具体国家的经纬度等信息,只需关注具体日期下的全球病例数即可。

    df = df_all.iloc[:, 4:]
    daily_cases = df.sum(axis=0)
    daily_cases.index = pd.to_datetime(daily_cases.index)
    # print(daily_cases.head())

    plt.figure(figsize=(5, 5))
    plt.plot(daily_cases)
    plt.title("Cumulative daily cases")
    # plt.show()

    # 为了提高样本时间序列的平稳性,继续取一阶差分
    daily_cases = daily_cases.diff().fillna(daily_cases[0]).astype(np.int64)
    # print(daily_cases.head())

    plt.figure(figsize=(5, 5))
    plt.plot(daily_cases)
    plt.title("Daily cases")
    plt.xticks(rotation=60)
    plt.show()
    return daily_cases

def create_sequences(data, seq_length):
    xs = []
    ys = []
    for i in range(len(data) - seq_length + 1):
        x = data[i:i + seq_length - 1]
        y = data[i + seq_length - 1]
        xs.append(x)
        ys.append(y)
    return np.array(xs), np.array(ys)

def preprocess_data(daily_cases):
    TEST_DATA_SIZE,SEQ_LEN = 30,10
    TEST_DATA_SIZE = int(TEST_DATA_SIZE/100*len(daily_cases))
    # TEST_DATA_SIZE=30,最后30个数据当成测试集,进行预测
    train_data = daily_cases[:-TEST_DATA_SIZE]
    test_data = daily_cases[-TEST_DATA_SIZE:]
    print("The number of the samples in train set is : %i" % train_data.shape[0])
    print(train_data.shape, test_data.shape)

    # 为了提升模型收敛速度与性能,我们使用scikit-learn进行数据归一化。
    scaler = MinMaxScaler()
    train_data = scaler.fit_transform(np.expand_dims(train_data, axis=1)).astype('float32')
    test_data = scaler.transform(np.expand_dims(test_data, axis=1)).astype('float32')

    # 搭建时间序列
    # 可以用前10天的病例数预测当天的病例数,为了让测试集中的所有数据都能参与预测,我们将向测试集补充少量数据,这部分数据只会作为模型的输入。
    x_train, y_train = create_sequences(train_data, SEQ_LEN)
    test_data = np.concatenate((train_data[-SEQ_LEN + 1:], test_data), axis=0)
    x_test, y_test = create_sequences(test_data, SEQ_LEN)

    # 尝试输出
    '''
    print("The shape of x_train is: %s"%str(x_train.shape))
    print("The shape of y_train is: %s"%str(y_train.shape))
    print("The shape of x_test is: %s"%str(x_test.shape))
    print("The shape of y_test is: %s"%str(y_test.shape))
    '''
    return x_train,y_train,x_test,y_test,scaler

# 数据集处理完毕,将数据集封装到CovidDataset,以便模型训练、预测时调用。
class CovidDataset(paddle.io.Dataset):
    def __init__(self, feature, label):
        self.feature = feature
        self.label = label
        super(CovidDataset, self).__init__()

    def __len__(self):
        return len(self.label)

    def __getitem__(self, index):
        return [self.feature[index], self.label[index]]

def parameter():
    LR = 1e-2

    model = paddle.Model(network)

    optimizer = paddle.optimizer.Adam(
        learning_rate=LR, parameters=model.parameters())

    loss = paddle.nn.MSELoss(reduction='sum')
    model.prepare(optimizer, loss)



config_mtp()
data = read_data()
x_train,y_train,x_test,y_test,scaler = preprocess_data(data)
train_dataset = CovidDataset(x_train, y_train)
test_dataset = CovidDataset(x_test, y_test)
network = TimeSeriesNetwork(input_size=1)

# 参数配置
LR = 1e-2

model = paddle.Model(network)

optimizer = paddle.optimizer.Adam(learning_rate=LR, parameters=model.parameters()) # 优化器

loss = paddle.nn.MSELoss(reduction='sum')
model.prepare(optimizer, loss) # Configures the model before runing,运行前配置模型

# 训练
USE_GPU = False
TRAIN_EPOCH = 100
LOG_FREQ = 20
SAVE_DIR = os.path.join(os.getcwd(),"save_dir")
SAVE_FREQ = 20

if USE_GPU:
    paddle.set_device("gpu")
else:
    paddle.set_device("cpu")

model.fit(train_dataset,
    batch_size=32,
    drop_last=True,
    epochs=TRAIN_EPOCH,
    log_freq=LOG_FREQ,
    save_dir=SAVE_DIR,
    save_freq=SAVE_FREQ,
    verbose=1 # The verbosity mode, should be 0, 1, or 2.   0 = silent, 1 = progress bar, 2 = one line per epoch. Default: 2.
    )




# 预测
preds = model.predict(
        test_data=test_dataset
        )

# 数据后处理,将归一化的数据转化为原数据,画出真实值对应的曲线和预测值对应的曲线。
true_cases = scaler.inverse_transform(
    np.expand_dims(y_test.flatten(), axis=0)
).flatten()

predicted_cases = scaler.inverse_transform(
  np.expand_dims(np.array(preds).flatten(), axis=0)
).flatten()
print(true_cases.shape, predicted_cases.shape)
# print (type(data))
# print(data[1:3])
# print (len(data), len(data))
# print(data.index[:len(data)])
mse_loss = paddle.nn.MSELoss(reduction='mean')
print(paddle.sqrt(mse_loss(paddle.to_tensor(true_cases), paddle.to_tensor(predicted_cases))))

print(true_cases, predicted_cases)

如果需要数据欢迎下方评论,同时也可以私信获取。

千万不要忘了点赞、评论、收藏,对我真的很重要偶~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器学习进阶之 时域/时间卷积网络 TCN 概念+由来+原理+代码实现 的相关文章

随机推荐

  • C语言——基础查漏补缺(二):《C程序设计试题汇编》应试概念总结

    相关文章 xff1a C语言 基础查漏补缺 xff08 一 xff09 xff1a 超长文帮你理清一些概念 C语言 基础查漏补缺 xff08 三 xff09 xff1a 谭浩强红书刷题笔记大杂烩 C语言 基础查漏补缺 xff08 四 xff
  • 6. 用冒泡法实现对10个整数按从小到大的顺序排序输出

    用冒泡法实现对10个整数按从小到大的顺序排序输出 xff08 完成sort1函数 xff09 span class hljs comment include lt stdio h gt span span class hljs keywor
  • Python图形绘制

    文章目录 前言一 turtle海龟绘图二 Python图形绘制三 绘画小黄人习题巩固 前言 海龟绘图很适合用来引导孩子学习编程 最初来自于 Wally Feurzeig Seymour Papert 和 Cynthia Solomon 于
  • 一个项目带你走进软件测试2

    文章目录 前言一 前期准备二 第一阶段1 熟悉软件项目2 阅读测试计划 三 第二阶段1 根据需求规格说明书设计测试用例2 执行测试用例3 提交bug 三 第三阶段关于项目面试问答 文档下载地址 前言 该项目针对在线的项目 xff08 鹏保宝
  • 查看ubuntu版本

    方法1 xff1a 使用命令 xff1a cat proc version 查看 proc目录下记录的当前系统运行的各种数据 version记录的版本信息可以直接通过cat查看到 xff0c 还可以看到我的gcc版本呢 Linux vers
  • 【接口自动化】接口报错500问题解决

    问题呈现 xff1a Python 43 requests接口报错返回500 xff08 后端没进行相关校验 xff0c 直接返回500 xff09 解决探索 xff1a Python 43 request生成的数据放在postman跑 x
  • 【部署教程入门级别】开源会议室小程序部署

    文章目录 前言一 项目整体二 前要准备1 安装Python 开发环境2 安装redis非关系数据库3 安装mysql服务器和客户端4 安装git工具5 安装微信开发工具6 Github或Gitee注册账号 三 正式部署1 pull源码2 部
  • Python批量获取高校基本信息

    文章目录 前言一 需求二 分析三 处理四 运行效果 前言 为了更好的掌握数据处理的能力 xff0c 因而开启Python网络爬虫系列小项目文章 小项目小需求驱动 xff0c 每篇文章会使用两种以上的方式 xff08 Xpath Bs4 Py
  • Python爬取各大外包网站需求

    文章目录 前言一 需求二 分析三 处理四 总结 前言 为了更好的掌握数据处理的能力 xff0c 因而开启Python网络爬虫系列小项目文章 小项目小需求驱动总结各种方式 页面源代码返回数据 xff08 Xpath Bs4 PyQuery 正
  • Python获取重庆市农场品行情

    文章目录 前言一 需求二 分析三 运行 前言 本系列文章来源于真实的需求本系列文章你来提我来做本系列文章仅供学习参考 one Leave a message at the end of the article two Get wechat
  • Python获取中国大学MOOC某课程评论及其参与人数

    文章目录 前言一 需求二 分析三 运行结果 前言 本系列文章来源于真实的需求本系列文章你来提我来做本系列文章仅供学习参考 一 需求 1 课程参加人数 2 课程学员名称及其评论 二 分析 首先查看网页源代码是否有需要的数据 课程参加人数 课程
  • Python项目之中国数据可视化

    文章目录 关键词一 做什么二 怎么做1 获取数据 amp amp 处理数据2 数据库设计 amp amp 存储数据3 开发后端接口4 前端页面编写 三 效果展示四 总结 关键词 PythonDjangoPython网络爬虫echarts可视
  • 关于text段、data段和bss段

    根据APUE xff0c 程序分为下面的段 xff1a text data initialized bss stack heap data bss text text段在内存中被映射为只读 xff0c 但 data和 bss是可写的 bss
  • Android 穿山甲广告联盟接入

    一 SDK接入 参考官方接入文档 xff0c 基于穿山甲版本号 3 1 0 0 导入 aar 及 SDK 依赖的 jar 包 将本 SDK 压缩包内的 open ad sdk aar 复制到 Application Module libs
  • linux下的so、o、lo、a、la文件的区别

    o 编译的目标文件 a 静态库 xff0c 其实就是把若干o文件打了个包 so 动态链接库 共享库 lo 使用libtool编译出的目标文件 xff0c 其实就是在o文件中添加了一些信息 libtool主要的一个作用是在编译大型软件的过程中
  • TypeError: only size-1 arrays can be converted to Python scalars

    正在愉快写代码的我 xff1f xff1f xff1f xff1f xff1f xff1f xff1f xff1f xff1f xff1f xff1f 源代码也很简单 之后可以解决 xff0c 比如 再比如 xff1a 但是那样究竟为什么不
  • 隶属度函数

    隶属度函数 介绍 xff1a 定义 若对论域 xff08 研究的范围 xff09 U中的任一元素x xff0c 都有一个数A x 0 xff0c 1 与之对应 xff0c 则称A为U上的模糊集 xff0c A x 称为x对A的隶属度 当x在
  • python 统计 list 大于 某值/0 的数量

    在列表的处理中 xff0c 我们经常要统计大于某值的数量 xff0c 每次都要写一段长长的代码 xff0c 对于刷LeetCode的人来说是难以忍受的 xff0c 那么有没有一种方法 xff0c 可以直接不用循环 xff0c 或者一行代码可
  • 模糊综合评价-----层次分析法AHP

    模糊综合评价 层次分析法AHP 文首先读 xff1a 最近有个课题需要用到模糊综合评价 xff0c 笔者也是收集了各方资料 xff0c 最后发现某乎上的一篇文章 xff0c 简单 系统 详细的同时不乏简单易懂和深度见解 xff0c 这边li
  • 机器学习进阶之 时域/时间卷积网络 TCN 概念+由来+原理+代码实现

    TCN 从 阿巴阿巴 到 巴拉巴拉 TCN的概念 xff08 干嘛来的 xff01 能解决什么问题 xff09 TCN的父母 xff08 由来 xff09 TCN的原理介绍上代码 xff01 1 TCN xff08 时域卷积网络 时间卷积网