深度学习 + 论文详解: TCN_时间卷积网络_原理与优势

论文链接

p.s. TCN stands for Temporal Convolutional Network. 它是除了 RNN architecture 之外的第二种可以分析时间性数据的架构

更多文章将在公众号:AI 算法辞典 首发!

前言

RNN 从最一开始发展以来,经过不断的演进与迭代,把原先难以实施 backpropagation 的难题用上了 LSTM 改良版的 RNN model 解决了,并且 LSTM 再经过简化后发展出来的 GRU 也能基本上保持一定良好的准确率,故在我们的知识中,甚至是一些机器学习的教科书中,已经反射性的把 RNN 列为解决序列问题的工具,但是就在最近的公开论文中提到,作为 CNN 家族的其中一个成员:TCN,在各项数据集中成功的击败了当下的王者 RNN 成为新的序列 data 分析方面的橋楮。

为了测试 TCN 的结果是否只有偏向性,论文中使用的测试数据涵盖了下面几种数据集类型:

  1. Polyphonic music model
  2. Words and character-level language model
  3. Synthetic stress tests

结果也证实了在上面各种类型领域的数据中,TCN 都得到了比 RNN 更为准确的结果。这里附上使用了 pytorch 作为框架的 python 代码写出来的 TCN 模型 [点击此处进入 GitHub] 。深入研究运算肌里后,发现到即使在理论上 LSTM 可以调整记忆门使得该被记得的东西永远留在单元里面,但在现实里反而 TCN 可以更实在的留住长远以前的记忆,并且整个框架设计上比 LSTM 更为简单和精确。这样的事实也不得不让我们重新思考 CNN 在序列数据集的角色定位。

追本朔源,其实在 1990 年代就已经有科学家们使用 CNN 作为序列资料的分析工具,在语音分析,语言分析等方向都有许多尝试,只是在还没有好的范式模型出现前,RNN 就已经拔得头畴成为了新的 Sequential Data Analysis 的宠儿。不过自从 LSTM 在 1997 年问世以来,研究者对其改进的结果总是无法有一个飞跃性的突破,到了 2017 年人们深入研究 RNN 的模型算法过程后,甚至给除了“If there were architectures much better than the LSTM, then they were not trivial to find.”和“None of the variants can improve upon the standard LSTM architecture significantly.”等结论,这也足以说明 RNN 在序列分析中遇到的瓶颈。

 

Temporal Convolutional Networks (TCN)

作为一个新的序列分析 model 它的特点主要有两个:

  1. 其卷积网络层层之间是有因果关系的,意味着不会有“漏接”的历史信息或是未来数据的情况发生,即便 LSTM 它有记忆门,也无法完完全全的记得所有的历史信息,更何况要是该信息无用了就会逐渐被遗忘。
  2. 这个 model 的架构可以伸缩自如的调整成任何长度,并可以根据输出端需要几个接口就 mapping 成对应的样子,这点和 RNN 的框架意思相同,非常的 flexible。

TCN. Sequence modeling

最大的亮点就是可以根据一个已知序列出现的先后顺序去评判未来的 t 时间点上,什么东西出现的可能性更合适,下面是给定的两个已知基本假设:

  • input sequence: x0, x1, x2, ..., xT
  • output sequence: y0, y1, y2, ..., yT

input sequence 即为历史资料,整个机制就是创造一个 formulism 能够根据历史资料去推断新的可能信息是什么:

  • Y0, Y1, Y2, ..., YT = f(x0, x1, x2, ..., xT)      ............ (1)

预测出来之后就需要对应的一个评判机制去评价预测结果的好坏,并基于这个机制去 train 整个模型,也就是 loss function,train 的方法就是 Gradient Descent 和 backpropagation:

  • L(y0, y1, y2, ..., yT, f(x0, x1, x2, ..., xT)) --> minimum ............ (2)

但是根据论文描述,这样的架构只能够看到“历史信息”,在某种程度上是不直接符合序列问题的核心原则的,序列资料的每一个元素都应该是可以被用来预测未来元素的其中一个要素之一。即便 LSTM 有 bidirectional 的机制可以让我们向前向后同时看,然后再做拼接,但它总体而言还是非“一统的整体”。

TCN. Causal Convolutions

为了建构出上面提到的 TCN 两个特点,其采用了对应机制分别是如下:

  1.  Causal Convolutions 思维可以用来应付“不漏接”的初衷,卷积层在 t 时间的 output 只与当层和前一个层的元素做卷积,这个方法与 1989 年的 time delay neural network 类似。
  2. 1D 的 fully-convolutional network (FCN) ,让每个输出层都可以保持和输入层一样多的长宽被继续传递,使用的手法是 zero padding,和之前的 CNN architecture 建构方法如出一辙。
  • 具体的 TCN = 1D FCN + causal convolutions ............ (3)

只是 TCN 也有一个缺点,如果要让 model 能把非常久远的元素内容也纳入其中考虑的话,那么神经网络的深度就必须也跟着很深才可以,好在借助现在的 GPU 并行运算处理的速度,可以轻松的完成如此“深邃”的计算框架。

TCN. Dilated Convolutions

一个正常的 CNN 都是可以被反向训练的 model ,但是如果考虑的历史信息多了,使得神经网络的深度大了,就需要一个新的解决办法:Dilated Convolutions 来解决反向训练的问题,下面是 TCN 结构的示意图:

Dilated Convolutions 运作在 s 元素上,并有一个 filter: {0, 1, 2, ..., k-1} 其内部的元素都是实数 R,公式描述如下:

 

 

 

 

 

 

 

 

 

<think>好的,我现在要解决用户在IAR编译器中遇到的错误:“incomplete type is not allowed”。首先,我需要理解这个错误的含义和常见原因。根据我的知识库,这个错误通常发生在代码中使用了未完全定义的类型,比如结构体或联合体声明了但未定义,或者前向声明了某个类型但没有提供完整的定义。 首先,我应该检查用户代码中是否有结构体或联合体的声明但没有定义的情况。比如,如果有一个结构体声明为`struct MyStruct;`,但没有后续的完整定义,那么在需要该结构体大小或成员的地方,编译器就会报这个错误。这时候,需要用户补全结构体的定义,包括成员变量。 其次,检查是否在头文件中只声明了类型而没有包含定义。例如,如果在头文件中使用前向声明,但在使用该类型的源文件中没有包含实际的定义头文件,这也会导致错误。此时,需要确保在使用类型的地方包含了正确的头文件,或者将前向声明替换为完整的定义。 另外,还要考虑typedef的问题。如果用户使用了typedef创建别名,但原始类型未完全定义,同样会引发错误。例如,`typedef struct MyStruct MyType;`之后,如果尝试使用MyType但MyStruct尚未定义,就会出错。需要确保在使用typedef之前,原始类型已经被完整定义。 此外,数组声明中的类型不完整也是一个常见原因。比如声明数组时,如果元素类型未完全定义,编译器无法确定数组的大小,导致错误。需要检查数组声明中的类型是否已经完整定义。 可能还有其他情况,比如在C和C++混合编程时,如果没有正确使用extern "C",或者在头文件中遗漏了必要的包含,也可能导致类型不完整。需要用户检查这些方面。 接下来,我需要将这些可能的原因整理成清晰的解决步骤,并给出具体的代码示例,帮助用户理解如何修改。同时,根据用户提供的引用内容,虽然引用[1]和引用[2]是关于其他错误的,但用户可能希望看到类似的结构,即分点说明解决方案,并引用相关资源。 最后,生成相关问题,帮助用户进一步了解可能相关的编译错误,比如类型未定义、前向声明问题等。这样用户可以有更全面的认识,预防其他类似错误的发生。</think>### IAR编译器错误'incomplete type is not allowed'解决方案 该错误表示代码中使用了**未完全定义的类型**,编译器无法确定其内存布局或成员信息。以下是具体原因及解决方法: #### 1. 结构体/联合体未定义完整 若声明了结构体但未定义成员,在实例化时会报错: ```c struct MyStruct; // 前向声明不完整 struct MyStruct var; // 错误:使用未完成类型 ``` **解决方案**:补全类型定义 ```c struct MyStruct { int id; char name[20]; }; ``` #### 2. 头文件包含缺失 当跨文件使用类型时,需确保定义可见: ```c // file.h struct Data; // 前向声明 // file.c struct Data { // 实际定义 int value; }; ``` **解决方案**:在使用该类型的文件中包含定义头文件 ```c #include "file.c" // 包含实际定义 ``` #### 3. typedef别名问题 使用typedef时原始类型必须完整: ```c typedef struct Node NodeT; // 前向声明 NodeT* ptr; // 允许指针声明 NodeT instance; // 错误:不完整类型 ``` **解决方案**:先完成类型定义再typedef ```c struct Node { int data; struct Node* next; }; typedef struct Node NodeT; ``` #### 4. 数组声明不完整 数组元素类型必须完全定义: ```c struct Element; struct Element arr[10]; // 错误:元素类型未定义 ``` **解决方案**: ```c struct Element { int type; float value; }; struct Element arr[10]; // 合法 ``` #### 调试建议 1. 在IAR工程中搜索错误行号定位问题代码 2. 使用Go to Definition功能追踪类型定义 3. 检查所有头文件包含链 4. 确认没有循环依赖的头文件 编译器需要知道类型的完整信息才能: - 计算sizeof大小 - 分配内存空间 - 访问成员变量 - 进行类型对齐 [^1]: 类似类型转换错误可参考浮点转整型的类型适配问题。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值