论文阅读1-TFDNet
论文阅读-TFDNet
作者表示在看了这么多文章,发现现有模型没有充分学习time
frequency信息,并且认为时域和频域的学习都相当重要。然后提出了这个模型叫做TIme-Frequency
Enhanced Decomposed Network。
文章中还提到了一个channel wise effects的东西,简答查了一下,是从卷积的颗粒度来的,就是维度更小了
image-20240206123340086
结构非常简单:
第一部分:预处理,分解序列并归一化
归一化采用了一种叫做可逆示例归一化的方法(RevIN) 论文链接:pdf
(openreview.net)
image-20240206214534524
分解公式比较简单,分成了趋势和季节趋势:
AvgPool表示移动平滑操作,Padding使原时间序列长度保持不变
下面一层设计用来捕获两种分解的时间序列的多分辨率的时域特征和频域特征: 其\(S_1……S_n\)代表不同窗口的长度,也就是不同分辨率
STFT(短期傅里叶变换): \(X\)为归一化后的序列 ...
搓OS-day8
手搓OS-day8
同步
本篇仅仅是实现同步问题,如果你问同步问题是什么,在应付考研的时候怎么搞,我也不介意写一手()
在OS中同步的理解是非常抽象的,抽象就抽象在和我们日常的理解完全不一样。在我们日常生活中讲同步,往往是这样一个情景;
同步率100%
嗯,所以在计算机领域中,我们也会习惯性的认为同步嘛,就是两个某种主体做着一样的动作(好怪),而在计算机领域中我们平时理解的同步其实是一种比较特殊的并行。
先来一个别扭且不恰当的比喻,首先必须说明我们生活中的活动有些是瞬间完成的,有些是需要一定时间的,下面是不太正常比喻:(①)有一个前来买瓜,(②)该人询问这瓜多少钱并(③)表示“你这瓜是瓜皮子是金子做的还是瓜粒子是金子做的“,(④)然后一刀捅穿了瓜摊老板,
(⑤)传出了阵阵”萨日朗“。
火红的萨日朗
上面的小故事由五个步骤组成,所有的情节发生都是有因果关系的,因此不能出现顺序的变化,不可能在捅穿老板之前就传出“萨日朗”,也不能在找茬之前就捅穿(不许抬杠),这种必须按照一定顺序去执行(需要完全执行一步,才能执行下一步)的故(程)事(序),就是同步。 ...
手搓OS-番外1
手搓OS-内联汇编
有一说一(起手式),虽然我们在平时写代码时几乎就不会写什么汇编(毕竟咱是写软件的,什么底层,什么硬件就该交给专业的人去搞),但是这对我们阅读代码,理解运行还是很有必要的(我就是想学会)
汇编语言
首先,简单回忆一下汇编语言,虽然这块是真的多,简单总结一下吧。
为了能理解汇编语言的作用方式,我们需要先回忆C语言的运行方式,这个在之前粗浅的写过,C语言要经过预处理-编译-汇编-链接多个步骤,才能形成一个可执行的二进制程序代码。这次不搞hello
world了,换个简单易读的,我们来写一个两个数求和的程序:
1234567#include <stdio.h>int main(){ int a=0,b=0; a=b+1; return 0;}
这套玩法我们其实已经非常熟悉了,编译但不链接,然后反编译:
1234567891011 0: f3 0f 1e fa endbr64 4: 55 push %rbp 5: 48 89 e ...
搓OS-day7
手搓OS-day7
现代处理器互斥实现
互斥(mutual exclusion)就不必多说了,简单点说就是不能同时访问。
实现互斥的基本假设:
不能同时读写内存
指令为不可打断的原子指令
函数通过内存屏障顺序不可优化
自旋锁(Spinlock)
自旋可以认为是一种循环等待的状态,即为忙等,维基百科是这么说的:
In software engineering, a spinlock is a lock that causes a thread trying to acquire it to simply wait in a loop ("spin") while repeatedly checking whether the lock is available.
我们在之前学习操作系统的时候,貌似记得忙等并不是一种很好的策略,忙等会让CPU无效工作,导致CPU利用率降低。
然而,我们之前学习时并没有提到其优点,因为一直是忙等(即运行态)所以线程不会进入阻塞态,也就没有了切换的上下文开销。
OK,现在基本的概念问题解决了,下面就要开始深入实现了,结合之前的互 ...
不得不知道的实用数据结构算法(二)
不得不知道的实用数据结构算法(二)
依旧是简单总结,主要还是一个思路上的应对问题,不去探讨实现细节,有机会单独讨论实现细节(毕竟我忘得差不多了)。
链表
首先先回忆链表的定义,以及其基本操作:
12345678#include <stdio.h>#include <stdlib.h>typedef struct Node{ int data; struct Node* next;}Node;
我们经常会去比较顺序表与链表的优劣,令我们印象最深刻的往往是插入算法的比较,下面列个表格比较一下基本操作的时间复杂度:
顺序表
链表
随机存取
O(1)
不能实现
插入
O(n)
O(1)
删除
O(n)
O(1)
遍历
O(n)
O(n)
相对顺序表而言,链表的操作貌似更快,但是也更有挑战性,因为没有了随机存取的特性,导致链表在获取元素时是很麻烦的,但是,往往这种拧巴的东西就很喜欢出题。
技巧一:双(多)指针
这个方法与其说叫做一 ...
搓OS-day6
手搓OS-day6
并行实验
最长公共子序列(LCS)问题
区分子序列与子串:子序列是可以剔除部分中间不相等的部分,而子串必须是连续的。
这个问题是不能采用暴力遍历的,因为时间复杂度高的可怕,要采用动态规划的方法,而动态规划的最重要的就是找到状态转移函数
性质以及状态转移函数
现有两个序列X[]和Y[],长度分别为m和n,lcs()函数为求最长公共子序列长度的函数。
性质1:如果串的最后一个元素相同,例如:if (X[m-1]==Y[n-1]),那么其最长子序列长度,则在剩余的m-1与n-1个元素的最长子序列加一,公式表现为:
1if(X[m-1]==Y[n-1]) lcs(X,Y,m,n)=lcs(X,Y,m-1,n-1)+1;
性质2:如果串的最后一个元素不相同,例如,if(X[m-1]!=Y[n-1]),则取下面两种情况的最大值:
删除X的最后一个元素,然后求X和Y的子序列长度
删除Y的最后一个元素,然后求X和Y
从公式上表达为:
12if(X[m-1]!=Y[n-1])lcs(X,Y,m,n)=max(lcs(X,Y,m-1,n),lcs(X ...
搓OS-day5
手搓OS-day5
咕咕,做一个老鸽子真的是太舒服了(雾)。这里我先提出一个操作系统公共厕所说()。众所周知,厕所是一种紧俏资源(CPU计算资源),只能独占,这里我们做一个抽(恶)象(心)的假设,人们是可以容忍临时换人的(状态机),有了这个现(逆)实(天)模型,后面就容易理解了。
复习
并发
并发,指的是一个时间段内两个进程同时运行(往往是交替的),而不是完全的同时,以人类视角来看并发是相当恶心的,带入一下上边的模型就能体会到。
而与并发常混淆的是并行,并行是我们可以理解的,也就是两个不同的进程(不只是进程)在同时刻处于运行态,但是放在上面的模型中,如果只有一个坑位,显然并行也是不行的,这也就是一般操作系统课程中常常考虑的单处理机。
这里画一个图就懂了:
并发与并行
可能有些基础薄弱的同学要问了,处理机和CPU有什么区别吗?
这个还是有一点区别的,处理机,顾名思义,是个处理什么玩意的机器,所以他是处理什么的呢,处理的是数据和程序,实际上,处理机是一个除去外设的一个计算机,而处理器就是CPU,处理机包含处理器:
image-202401142221 ...
不得不知道的实用数据结构算法(一)
不得不知道的实用数据结构算法(一)
新坑说开就开,就是这么随(不)心(知)所(死)欲(活),这个系列实际上是针对数据结构中的一些低时间复杂度的常用模板or思考方式的总结,ok,今天先进行的是线性表。
线性表
定义:
123456789# include <stdio.h>typedef ElemType int;struct typedef SeqList{ ElemType *data; // 按道理这里应该有很多实现方法,比如直接上一个数组,通过宏定义最大数组长度 int size; int capacity;}SeqList;
123456789101112131415# include <stdio.h># define MAXSIZE 100typedef ElemType int;struct typedef SeqList{ ElemType data[MAXSIZE]; int length;}SeqList;void init(SeqList *l){ ...
搓OS-day4
手搓OS-day4
今天才是真真的操作系统的部分,并发控制,今天要学习的是多线程编程库(没怎么看,少更)。
复习:进程与线程
进程:运行的一个程序以及其已经在计算机中的所拥有的资源的和(理解型说法,并不准确),进程是资源分配的基本单位。PCB用于标志进程的存在。此外关于进程还存在进程间通信问题,进程特性,进程切换等问题。
就我个人理解为何要引入进程概念,是为了管理资源分配的问题,不只是空间资源还有计算资源,因为计算机的资源是紧俏的(当然也有机制限制),并不能满足所有的所有的程序同时运行(当然这里限制在单核处理器)。但是由于应用有要求,需要发展出能在人难以感知的情况下”同时“运行(并发),而进程恰好通过把资源与程序进行耦合(不知道用词好不好,类似一个搭积木的感觉)既保护了程序状态,又实现了程序运行的切换。
当人们线程用出来了甜头,想要进一步榨干计算机资源(bushi),然后就有了线程,线程就是榨干计算资源的(),但是线程并不是资源分配的单位。
多线程编程
貌似并不难
12345678910111213#include "thread.h"void Th ...
搓OS-day3
手搓OS-day3
挺过了昨天的抽(硬)象(件)玩意,今天终于要迎来美丽的实战了(很能绷的住),下面我们要迎接大量的操作系统概念,虽然俺可能描述不清楚,但是我相信代码的力量,从现在要挑战编程能力惹。我尽可能拆开代码记录我的编程心路(阿门
worship)
架构
这里老师采用了一个分层的方式设计的架构,在硬件上通过一个Abstract
Machine抽象出了部分API,这好处是显而易见的,就类似一个虚拟平台,对跨硬件是很有帮助的,显然Abstract的很多汇编我是不会写的,但是老师帮忙搭建好了(感恩)
简单架构
搓不动了,先放一放,研究一下设备无关编程(菜,哭)
断言的重要性
这个和我们在JAVA中接触过的单元测试有些相似,说他重要体现在快速定位错误(不是运行错误)的重要性上
断言基本用法:
123#include <assert.h>assert(bool exppression) //显然这里传入一个bool量,但想起int中0和非0分别代表false和true
使用场景:
在函数入口做合法性检查
将assert(0)放在绝对不 ...