深度学习笔记(3)读懂代码

深度学习笔记(3)读懂代码和小试牛刀


一、如何读代码和读代码

1 下载的代码怎么看

首先找到我们的一个入口函数Train.py运行来debug

训练参数:
--name cifar10-100_500 # 训练名称
--dataset cifar10 # 数据集
--model_type ViT-B_16 # 模型类型
--pretrained_dir checkpoint/ViT-B_16.npz # 预训练模型路径

把上面这些训练参数复制一下
在这里插入图片描述
把脚本形参那里展开 复制到那里。
然后去找main函数,按ctrl点进去,去看main函数里面有什么,你会看到一些变量参数。
在这里插入图片描述
然后下拉到下面实际执行的第一行代码那里,打个断点。然后去点右上角debug,
下面这段代码是设备的初始化,判断你是否有GPU,如果没有就使用cpu,gpu是几张卡等等。然后就是训练的所有的数据和模型都传到这个设备里面去。

  # Setup CUDA, GPU & distributed training
    if args.local_rank == -1:#单机训练
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")#判断是否有GPU
        args.n_gpu = torch.cuda.device_count()#GPU数量
    else:  #
        torch.cuda.set_device(args.local_rank)#设置GPU
        device = torch.device("cuda", args.local_rank)#
        torch.distributed.init_process_group(backend='nccl',
                                             timeout=timedelta(minutes=60))
        args.n_gpu = 1
    args.device = device

这是日志设置,很多代码都是差不多的,用的时候现查就好了。

 # Setup logging
    logging.basicConfig(format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
                        datefmt='%m/%d/%Y %H:%M:%S',
                        level=logging.INFO if args.local_rank in [-1, 0] else logging.WARN)
    logger.warning("Process rank: %s, device: %s, n_gpu: %s, distributed training: %s, 16-bits training: %s" %
                   (args.local_rank, args.device, args.n_gpu, bool(args.local_rank != -1), args.fp16))

下面是设置种子,我们在训练模型的时候,很多时候咱们是做一个随机初始化但是现在遇到一个问题,我调参后参数变了,但是我初始化的权重也变了,那么测试后的结果,到底是因为你参数导致的,还是因为你的权重参数初始化好导致的会说不清楚,这时候设置个随机种子,但是每次随机结果都是固定的,所以我们要设置个随机种子。

# Set seed
    set_seed(args)

你进去看随机种子的函数,以后用到的时候直接复制粘贴,因为所有项目都这么做的,不用太探究是因为什么。这几行代码很多年都不变了,就直接复制粘贴就可以了。

def set_seed(args):
    random.seed(args.seed)
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    if args.n_gpu > 0:
        torch.cuda.manual_seed_all(args.seed)


这段代码是传入参数,初始化参数,具体参数是什么呢?

 # Model & Tokenizer Setup
    args, model = setup(args)

点下看到的如下图:
在这里插入图片描述

可以在调试模式下按去看定义这函数的代码:

def setup(args):
    # Prepare model
    config = CONFIGS[args.model_type]

    num_classes = 10 if args.dataset == "cifar10" else 100

    model = VisionTransformer(config, args.img_size, zero_head=True, num_classes=num_classes)
    model.load_from(np.load(args.pretrained_dir))
    model.to(args.device)
    num_params = count_parameters(model)

    logger.info("{}".format(config))
    logger.info("Training parameters %s", args)
    logger.info("Total Parameter: \t%2.1fM" % num_params)
    print(num_params)
    return args, model

model = VisionTransformer(config, args.img_size, zero_head=True, num_classes=num_classes)这行代码比较重要 点进去看构造函数怎么做的。
在看源码的时候,先找类下面的forward打上断点。 类似这种
在这里插入图片描述
比如下面这段代码

class VisionTransformer(nn.Module):
    def __init__(self, config, img_size=224, num_classes=21843, zero_head=False, vis=False):
        super(VisionTransformer, self).__init__()
        self.num_classes = num_classes#分类个数
        self.zero_head = zero_head
        self.classifier = config.classifier

        self.transformer = Transformer(config, img_size, vis)#Transformer初始化
        self.head = Linear(config.hidden_size, num_classes)

    def forward(self, x, labels=None):
        x, attn_weights = self.transformer(x)
        print(x.shape)
        logits = self.head(x[:, 0])
        print(logits.shape)

        if labels is not None:
            loss_fct = CrossEntropyLoss()
            loss = loss_fct(logits.view(-1, self.num_classes), labels.view(-1))
            return loss
        else:
            return logits, attn_weights

我会看到类的名字是VisionTransformer,然后再看我的输入是啥,输入有一个x,把鼠标放x,会看它的一个维度。
在这里插入图片描述
可以看到维度是16是bach大小,3是rgb,224是h和w,H:Height,高度,表示图像垂直维度的像素数 W:Width,宽度,表示图像水平维度的像素数

再比如这段代码

class Transformer(nn.Module):
    def __init__(self, config, img_size, vis):
        super(Transformer, self).__init__()
        self.embeddings = Embeddings(config, img_size=img_size)
        self.encoder = Encoder(config, vis)

    def forward(self, input_ids):
        embedding_output = self.embeddings(input_ids)
        encoded, attn_weights = self.encoder(embedding_output)
        return encoded, attn_weights

点进input_ids
在这里插入图片描述
embedding操作,就是卷积输入是3,意思就是输入是个彩色图,输出每个位置得到 768 位向量。把一张输入图像展开展开成一个序列。

二、时间序列

1.一些基本概念

1.傅里叶变换 目的:将时域(即时间域)上的信号转变为频域(即频率域)上的信号,随着域的不同,对同一个事物的了解角度也就随之改变,因此在时域中某些不好处理的地方,在频域就可以较为简单的处理。
举个声音的例子
假如是一个声源始终发出440hz的A音,那么它的波形是这样的。每秒440次震荡,D音的结构是相同的,只是每秒节拍数变少了。那两个声音同时发出时,压强是怎么样的呢

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3fc2718d99b441b294b89318e26f7b3b.png在这里插入图片描述
重叠时,产生了很高的气压,而其它时刻又会互相抵消 、
在这里插入图片描述
加入更多音调的时候就更复杂了。那么我们在听音乐时,把音乐分解成简单的音调显然更容易理解。

在这里插入图片描述
那么先从最简单的说起,单一音调的音频是这样的,假设它每秒只有三拍,我们能轻松画出图像。
在这里插入图片描述
那么我们把这个图像抽象到一个圆上,也就是圆心到图像上的距离等于这个时刻的图像高度,而上面的图像是三拍每秒,下面的图像是每秒转半圈。当然,我们也可以加快圆旋转的速度。
在这里插入图片描述
但是,当他们频率都一样的时候,就会出现这种情况,高处的点出现在圆右侧,低处的点出现在左侧。也就是说当频率不一样的时候,这个图像的质心会在圆心处,但是一样的时候 ,质心会在右侧
在这里插入图片描述
那么,也就是说,每过3秒钟,质心会有一次飞跃的变化
在这里插入图片描述
同样的,频率为两秒的波形是这样的
在这里插入图片描述

然而你把这两个频率加在一起就变成这样的
在这里插入图片描述

2.timesnet (时间序列通用模型)

transformer等只针对原始数据,只针对原始序列去做的,原始序列当中给你提供信息毕竟是有限的,原来你的任务当中只能这一原始序列去做,那可能还是有些局限的。我们要分析这个时间序列,从一个新的维度,新的维度是什么呢?叫做多周期。任务里边可能肯定会有很多周期在发生不同的变化,每个周期要做自己的事,你就当做每个因素在做自己的一个事儿。然后他说这些个周期会有重叠,而且会相互影响的。对于每一个周期来说,我们发现了在每个周期的变化当中,不光是受它周围的点影响的,还受它相邻的周期的一个影响。这篇论文构建了一个周期内的一个变化,一个周期间的一个变化两种序列,但是1D 的时间序列很难去捕捉这两种类型的信息。,因此把研究对象转换到 2D 的空间当中,这是这篇论文的重点。
其实就是构建一个表,每一行代表不同周期同相位的过程。 每一列代表同周期内的一个变换。实现通过傅里叶变换实现。在这里插入图片描述
注意时间序列上每一个点,它并不是一个值,每一个点它是一个向量。比如说每一个点我都知道这个人身高、年龄、体重,第一个点我知道身高、年龄、体重,第二点、第三个点、第四个点都有这些个指标。
timesnet 就是一共有t个点,每个点有c个特征,原始的一个 1D时间序列就可以表示成 t 乘c的 一个矩阵,要想考虑我们周期性的变换,我们需要先得一个周期是多少,通过傅立叶变换来分析。
做好傅里叶变换后就得到一个2d的矩阵,然后进行一个填充,为啥要填充呢,因为有的周期除不开,一旦除不开就要加一个padding

具体代码
源码里是脚本怎么办?打开.sh脚本比如

在这里插入图片描述
把参数复制过来
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值