【笔记】大模型时代下做科研的四个思路 - 论文精读·52

news2024/12/25 23:47:22

视频地址:大模型时代下做科研的四个思路
在这里插入图片描述

相关大模型
CV: ViT(22B) , ViT-G(2B) from google
多模态:ViT-E(4B) from google
NLP:LLaMA(70B,130B,330B,651B) from Meta

提问:在模型越来越大的时代背景下,如何利用有限的资源做出一些科研工作。

回答:四个方向

1、Efficient(PEFT)
提升训练效率,这里以PEFT(parameter efficient fine tuning)为例
(做效率提升的(哪里慢提升哪里的速度,哪里heavy使其轻量级))

2、Existing stuff(pretrained model)、New directions
使用别人的预训练模型,新的研究方向(做新方向,避免撞车,竞争,刷榜)

3、plug-and-play
做一些即插即用的模块,例如模型的模块、目标函数、新损失函数、数据增强方法等等。(可以在不同领域应用)

4、Dataset,evaluation and survey
构建数据集、发表分析为主的文章或者综述论文。

大模型时代下做科研的四个思路

  • 第一个方向:Efficient(PEFT)
    • 1. AIM论文为例
    • 2. PEFT的方法
      • (1)adapter
      • (2)prompt tuning
    • 3. AIM模型设计
  • 第二个方向:Existing stuff(pretrained model)
    • 一些比较新的Topic
  • 第三个方向:plug-and-play
  • 第四个方向: Dataset,evaluation and survey

第一个方向:Efficient(PEFT)

1. AIM论文为例

通过论文AIM为例讲述如何进行PEFT,即在硬件资源有限时对大模型进行高效微调

论文地址:https://arxiv.org/abs/2302.03024
论文标题:AIM: Adapting Image Models for Efficient Video Action Recognition
标题翻译:调整图像模型以实现高效的视频动作识别

这篇论文是做视频动作识别,即视频理解的工作。

传统模型和论文改进的微调方法对比图:
在这里插入图片描述
之前的做法:

  1. 在已有的模型之上,单独增加时序处理模块,比如
    (1)在TSN中,先将视频劈成几段,然后将从这些视频中抽取出来的特征做一下加权平均。
    (2)在Temporal Shift Module(TSM)中,做的就是把模型的特征在Channel维度上,进行来回的shift操作,从而去模拟时序建模。
    (3)在最近的使用Transformer来做视频理解的工作里,像Time Transformer,就是先做Time Attention,再做Spatial Attention,也就是将Spatial 、Temporal分开来做。
  2. 将时间和空间的特征一起学,这里主要是3D网络,比如i3D,Transformer时代的Video Swing,就是把2D的这个Shifted Window变成3D的Shifted Window,总之,输入是3D的,模型也是3D的,是一个Joint Modeling的过程。

虽然之前的这些方法在效果是都非常的好,但是他们都有一个小小的问题,就是计算代价实在是太大,因为他们的模型,全都是需要Full Fine Tune的,就是整个模型的所有的参数都要拿下来,在这个视频数据集上去做Fine Tune,但是视频数据集的本身就比较大,数据的IO一般都有Bottleneck,然后模型本身也比较大,所以这个训练的Cost非常昂贵。
一般左边这种时间和空间分开的方法还好(一台8卡机需要3、4、5天完成一个模型的训练,但是若Bottleneck特别大的话就需要一周或者十天左右的时间),稍微轻量些。右边这种Joint的Video Model,比如大部分的3D网络或者Video Swing模型,他们的训练时间就非常感人了。但是这些模型还好,是因为他们利用了预训练的图像模型。所以,说白了,他们更多的还是在做一个Fine Tune。如果像视频领域,有些模型是从头开始训练(Train From Sketch),那这些模型就需要更长的时间了,比如MaskFit、Video MAE,这些最近的自监督的视频学习方法,他们的训练代价都是以周为计算单位的。一般情况下,想要复现他们的模型都很困难,更不要说是提出什么新模型且比他们的效果更好了。

这篇论文的研究动机来自于Clip,对比学习,虽然Clip作为一个图像模型,也能做视频动作识别的任务,且效果好的出奇。

思考:已经训练好的图像模型是否需要继续微调?

1、clip已经证明了即使ZeroShot(模型不变,直接在各个数据集上进行推理),它的效果也很好。即一个训练很好的图片模型从中提取视觉特征是有泛化性、有效的。

2、继续微调会导致灾难性遗忘。如果使用少量数据在大模型上微调,可能会直接过拟合,或者大模型的很多特征丢失。

结论:预训练的图像模型不需要继续微调。

因此,论文的做法是,尝试将模型参数锁住,在上面加一些时序处理模块、目标函数等修改周边的方式(即PEFT)让图片模型能够做视频理解的任务,不需要重新训练视频模型,省时省力。

接下来介绍两个比较普遍的PEFT的方法

2. PEFT的方法

(1)adapter

最早来自于这篇论文:

论文地址:https://arxiv.org/abs/1902.00751
论文标题:Parameter-Efficient Transfer Learning for NLP
标题翻译:用于NLP的参数高效转移学习

这篇论文是做NLP的。

注:最近,很多视觉和多模态这边使用的技术都是从NLP那边过来的,因为大家都用transformer做backbone,因此NLP这边的方法大概率都能迁移到视觉这边,比如这些parameter
efficient fine tuning的技术、in-context learning、instructor
GPT里的RLHF这些基于reinforcement learning的方法,都可以快速被运用到视觉里面。

Adapter层的结构,如下图右边所示:下采样FC层+非线性激活层+上采样FC层,加上残差连接。

Adapter layer就像一个即插即用的模块,可以插到transformer layer里的任何一个地方。

这里PEFT的方法是指,如下图左边所示,在Transformer中加入了两个adapter,分别是在attention和NLP后面,进行微调时,原来的Transformer的参数都是锁住的,只有adapter层的参数在学习。
在这里插入图片描述
adapter层参数量和大模型相比非常少,例如在175B的GPT3中使用LoRa,需要训练的参数只要万分之一。因此训练成本大幅降低。

(2)prompt tuning

prompt tuning是指可以任意调整提示词,这样的调整对最后的性能会有很大的影响,能否得到想要的结果,取决于有没有选择一个好的提示词。例如下图所示,不同的提示词对准确率的影响很大。

论文地址:https://arxiv.org/abs/2109.01134
论文标题:Learning to Prompt for Vision-Language Models
标题翻译:用于视觉模型的提示学习

在这里插入图片描述
无论是在分类任务还是在图像生成的任务里,prompt tuning对最后的性能影响是非常非常巨大的,你最后能否得到你想要的结果,很大程度上取决于你有没有选择一个很好的Prompt。

Prompt分为两种:
Hard Prompt:人工设置的提示词,不能修改也无法学习。设置这些需要一定的先验知识,但我们并不会总有这样的先验知识。
Soft Prompt:将提示词设置为一个可学习的向量。如上图中的v1,v2,…,vm,这和DETR里的learnable query一样,都是一个可学习的向量。

在整个模型的训练过程中,整个模型是锁住不动的,只根据最后的loss去调整Prompt。最后,希望学到的Prompt能够泛化到各种各样的情形里去。

如下面的总览图所示 ,它跟clip模型之前在做推理的过程中画起来是一模一样的,上面是文本的分支,一个prompt进文本编码器得到很多文本特征,下面是图像进图像编码器得到一个图像特征。然后将图像特征和这些文本特征去做相似度,看哪个最高选哪个。这个模型和clip的区别是,一是图片分支是在训练的,二是文本端(text encoder)的输入不再是固定的,而是一个可以学习的learnable context,模型优化的是这个context部分,而不是模型本身。这样既可以节省很多计算量,也可以避免在下游任务时手动设置提示词。
在这里插入图片描述

上述是prompt tuning或者说是Soft Prompt的最简单、最基本的一个形式。

上述还是在文本端的prompt,实际上还是一个多模态的工作,它有一个图像编码器,一个文本编码器,prompt在文本这边,更多的还是像一个NLP的工作。

将可学习的Prompt方法用到纯视觉任务中,做法如下图所示。

论文地址:https://arxiv.org/abs/2203.12119
论文标题:Visual Prompt Tuning
标题翻译:视觉提示调整

在这里插入图片描述
图中蓝色部分是原来训练好的模型,红色是需要微调的prompt,加入Prompt tuning有两种方式:

1、VPT: Shallow,在输入端加入learnable的prompt。这和文本那边的处理方法相似。
具体来说,就是当你拥有一个图片的时候,先使用VIT将其打成patch,这些patch通过Embedding层的到输入的sequence。比如一开始是224*224的图片,达成patch之后,变成一个长度为196的token sequence,这个就是准备喂给transformer的输入,也就是图片中的E0。将E0看成文本端的class 那么或者是photo of class,我们很容易可以想到prompt应该加到它之前,这跟文本那边一模一样。此时,只有input的prompt是在学习的,剩下所有过程中的模型参数都是锁住的,最后的目标函数只用来优化这跟prompt,即图片中的P0.

2、VPT: Deep,在每一层的输入输出都加入learnable的prompt。

上述进行PEFT的共通性就是,当你有一个已经训练好的大模型的时候,是希望这个模型是锁住不动的,这样不光有利于训练,还有利于做部署,做下游任务的transfer,而且它的性能还不降,很多时候还不降反升。

huggingface上传了一个专门用来做PEFT的包:https://github.com/huggingface/peft

当你只有很少量的硬件或者当你的GPU内存不高的时候,如何去FineTune或者使用这些Billion scale的模型,可以试一下PEFT。

近期PEFT方法总结,从统一的观点进行归纳:
论文地址:https://arxiv.org/abs/2110.04366

回归正题

3. AIM模型设计

在这里插入图片描述

做视频理解的工作大致为以下三个方向:
(1)在SpatialBackbone上下文章(如上图c),
(2)在TemporalAnalysis上下文章(如上图d),
(3)怎么去学Joint Spatial Temporal Modeling(如上图e),
因此本文也是按照上述套路加的Adapter。

如上图所示,AIM模型就是在图b的ViT模型中加入图a的Adapter,共有图c、d、e三种方式:

1、Spatial Adaptation,只在S-MSA层后面加入Adapter,即不增加视频理解能力,只加一些学习的参数。
2、Temporal Adaptation,复用一个MSA层,在两个MSA层后面都加入Adapter,即让模型从Spatial和Temporal两个方向上进行学习,从而有时序建模的能力。
3、Joint Adaptation,在Temporal Adaptation的基础上,在MLP边上也加入Adapter,即让三个Adapter各司其职,使得优化问题更简单一些。

注:MSA是多头自注意力(MultiHead Self-Attention,S-MSA和T-MSA共享权重,但维度不同。

效果如下图所示,只用14M参数的AIM模型效果已经高过之前121M的模型。
在这里插入图片描述
总之,在视频工作中,使用PEFT(parameter efficient fine tuning)后,大部分的实验一台8卡机就能完成,短则半天,长则三四天。

除了PEFT(parameter efficient fine tuning),其实前几年比较火的,就是怎么把Attention做成Efficient Attention,比如Learn FormerPerformer等这些Attention的近似,最近还出了一个更好的,叫Flash Attention,更省内存,而且效果也非常的好。

第二个方向:Existing stuff(pretrained model)

有两点:
1、不要碰预训练模型。巧妙使用别人的预训练模型,从而达到去做FewShot,ZeroShot,或者最多Fine Tuning的实验。
2、新的研究方向。

通过这篇论文讲述这两点是如何运用的:

论文地址:https://arxiv.org/abs/2207.05027
论文标题:Unsupervised Semantic Segmentation with Self-supervised Object-centric Representations

从标题就可以看出这两点技巧:

1、这里的Self-supervised是指使用了预训练好的DINO、DeepUSPS、BASNet等网络
2、这里做的方向是Object-centric Learning,属于蓬勃发展的题目,玩家不多、数据集不大。
在这里插入图片描述

我们也知道,这些所谓的Unsupervised其实都不是真的Unsupervised,实际上是通过认为设计了一些任务或者label,让模型去学习。
这里也不例外,你如果想学习一个Segmentation的网络,肯定是需要某种程度上的Mask Information。这个Mask Information是借鉴了Saliency Detection的工作,如DeepUSPS,即可以直接给定一张图片,然后它可以给你生成这张图片里那些比较有显著性物体的Mask是长什么样,虽然有些糙,也不准确,但也算是有个起始点了,有一些Mask信息了。

上图展示了如何使用几个预训练好的模型,在无监督的情况下找到新的物体,步骤如下:

1、通过预训练模型DeepUSPS找到一些显著性物体的Mask。
例如,图片中的篮球可以得到一个圆形的Mask

2、根据Mask将图片中的对应物体抠出来,并调整大小为224*224。
例如,将图片中的篮球抠出来并放大

3、然后将步骤2得到的图片通过预训练模型DINO返回一个1024*1024的特征(global representation)。

4、将所有的特征进行聚类Clustering,这样就可以通过无监督学习得到这些物体的分类ID。
注:聚类只能将相同的物体分类到一起,但并不知道具体是什么物体。

5、将图片和对应的分类ID去训练一个语义分割网络(Semantic segmentation network)。(可以是PSP.NET、DeepLab V3)
注:这里相当于一个有监督的学习,标签来自于步骤4

6、一张图片可能有多个物体,所以加一个Self-training,多做几个轮回。

这样就可以从图片中找到物体了。

一些比较新的Topic

(1)Causality Learning (因果学习)
(2)Hinton之前提出的Feedforward Network,FFNet
(3)Language 那边的In-Context Learning
(4)Chain of Thought Prompting,就是Aston前几期讲过的AI鼓励师,COT

第三个方向:plug-and-play

做一些通用的、即插即用的模块,在一个设定的范围内,加入了这样的模块后,能够有一个统一的涨点,并且能给出合适的分析,就非常有说服力了。通过MixGen论文讲述如何加入模块:

论文地址:https://arxiv.org/abs/2206.08358
论文标题:MixGen: A New Multi-Modal Data Augmentation

文本的模型都很大,图片的模型相对来说小一些,但是自注意力的参数是可以共享的,所以尝试用文本大模型来蒸馏图片小模型

注:模型蒸馏:使用训练集训练出来一个完整复杂的teacher模型,然后设计一个小规模的student模型,再固定teacher模型的权重参数,然后使用训练集和teacher模型的输出同时对student模型进行训练,此时就需要设计一系列loss,让student模型在蒸馏学习的过程中逐渐向teacher模型的表现特性靠拢,使得student模型的预测精度逐渐逼近teacher模型。

为什么之前图片模型不做数据增强?

1、图片模型训练时已经用了很多图片了,不需要再做数据增强。
’2、或者做了数据增强,但是将其中的Color Jittering和Random Filp去掉了,因为这两个对图片的变化会导致图片和文本不匹配。

例如:图片有白色的狗和绿色的树,只对图片做Color Jittering会导致颜色变化,图片中不再是白色的狗,但是文本依然是白色的狗,这样文本和图片就不匹配了。

图片这边的做法,如果想保留所有的信息,尽量不去毁坏他原来的东西,一个比较天然的选择就是Mixup,Mixup就是把两张图片线性地插值到一起。

论文的做法:既然目标是尽可能保留更多信息,这里的做法很简单粗暴,就是直接将两个句子拼接在一起,这样就可以做到不丢失信息的情况下得到新的训练样本。

例如下图,将两个图片通过数据增强得到第三个图片,同时将两个图片的文本进行拼接得到第三个图片的文本。即在图片上做Mixed Up,在文本上做Concate。
在这里插入图片描述
这个是在数据处理的时候做的,即在Data Loader里完成的,无论你换什么方法,比如Vilt、ALBAF、BEIT等,或者换什么Codebase,比如Pytorch、TensorFlow等都无所谓,只要在Data Loader把这一步加进去就行,其他什么都不用改,真的算是即插即用,而且能获得普遍的提升。

审稿人的建设性提议:在下游任务只有少量数据时进行数据增强。

第四个方向: Dataset,evaluation and survey

这个方向是对计算资源要求最少的。
构建数据集、发表分析为主的文章或者综述论文,这里举了两篇论文为例。

以数据集为主的big detection,将三个数据集整合到一起:

论文地址:https://arxiv.org/abs/2203.13249
论文标题:BigDetection: A Large-scale Benchmark for Improved Object Detector Pre-training

上述论文是一个非常大的目标检测的数据集,目标检测是一个非常实用的任务。这篇论文是将三个已有的数据集(LVIS、Open Image、Object 365)合到一起,当然不是简单的合到一起,因为每个数据集的class也不是完全一样的,所以需要考虑怎么去merge这些class或者怎么去重新分布这些类别。而且根据你的这个任务需求,你到底是想做预训练还是下游任务,你到底是想target哪一个domain,这个也决定了你这个物体的类别到底该多细粒度,这些都是可以做的研究方向。总之,这个big detection最后处理完,就是一个有600类的目标检测数据集,里面有超过340万的训练图片,有3600万个bounding box annotation,算是当时最大的一个目标检测数据集了,而且在上面可以预训练各种各样的目标检测器。因为训练数据多,所以训练出来的目标检测器的泛化能力和few shot的能力都非常好。

这个数据集比较新,刷的人也比较少,可以在这个数据集上面做一些out of distribution的分析、robustness的分析、few shot zero shot的各种各样的分析或者测评,都是不错的研究方向。

视频动作检测的综述论文:

论文地址:https://arxiv.org/abs/2012.06567
论文标题:A Comprehensive Study of Deep Video Action Recognition

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

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

相关文章

【接口测试】微信小程序接口自动化的实现方案

背景 前几天看到有人问微信小程序怎么进行接口自动化,所以想把自己如何进行微信小程序接口自动化的方法分享下。 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html这是微信小程序的登陆流程,小程序登陆需要在小程序…

un-app-手机号授权登录-授权框弹不出情况

前言 手机号授权是获取用户信息api停用之后,经常使用的api。但是此api也是有很多坑 手机号授权会出现调用不起来的情况,这是因为小程序后台没有进行微信认证导致的 手机号授权调用不起来-没有微信认证 来到小程序后台-设置-基本设置-下拉找到微信认证…

【ModelSim】查看波形图(Wave)和数据流图(DataFlow),以4-bit计数器为例

▚ 00 预备条件 📢 本项目包括两个Verilog文件:测试文件counter.v和激励文件testbench.v;可从此处点击HERE获取。 🎮 Windows10系统 🔮 ModelSim SE-64 2020.4 ▚ 01 启动ModelSim 有两种方式可以打开ModelSim&a…

vue下载与部分指令详解

目录 vue 下载地址 前端框架 MVC与MVVM框架 Vue使用 Vue.js指令 ​编辑 v-if v-else v-show v-on v-model(表单绑定) v-bind v-for v-text v-model 指令扩展 vue 下载地址 官方入门:https://cn.vuejs.org/ API 文档&#…

如何给网站或者后端服务免费且快速的进行配置HTTPS,配置ssl证书

前言 现在部署的网站用的大多都是https协议的,还有的平台你要是想发布自己的网站就必须得是https的协议,如果不使用ssl的话,那就不让你使用.就比如微信,支付宝等的产品,不用的话就不让你使用他们的平台.不过还好很多服务厂商都提供了免费ssl证书可以进行配置 今天的情况比较特殊…

常用电子元器件基础知识

目录 一、电阻 二、电容 三、电感 四、保险丝 五、二极管 一、电阻 概念:顾名思义,就是增加电流通过的阻力的。 就像是在水渠中放入东西,能阻止水的顺利通过也是一个道理。 基于电阻的电气特性,电阻在电路中主要有以下四个…

Solidity 小白教程:11. 构造函数和修饰器

Solidity 小白教程:11. 构造函数和修饰器 这一讲,我们将用合约权限控制(Ownable)的例子介绍solidity语言中构造函数(constructor)和独有的修饰器(modifier)。 构造函数 构造函数&…

栈与队列(JAVA)

单调栈&#xff1a; 下一个更大元素。 题目意思如图所示&#xff1a; 单调栈图解&#xff1a; class Solution {public int[] nextGreaterElement(int[] nums1, int[] nums2) {Stack<Integer>stacknew Stack<>();int res[]new int[nums2.length];int ans[]new int…

为什么要使用Token

传统的session认证 我们知道&#xff0c;http协议是一种无状态的协议&#xff0c;这就意味着当用户向我们的应用提供了用户名和密码进行用户认证&#xff0c;那么在下一次登录的时候&#xff0c;用户还要再进行验证&#xff0c;因为根据http协议&#xff0c;浏览器并不知道是谁…

Shipping mode --为省电而生

关于shipping mode 相信很多做消费类电子产品的硬件工程师对这对英文耳熟能详。日常家用的手机&#xff0c;电脑&#xff0c;电子手表都用到了这项技术。 shipping mode可译为运输模式&#xff0c;又或者船运模式&#xff0c;其技术的实现主要依靠于电子产品中的充电管理芯片。…

Java自学网站推荐--全网最靠谱

原文网址&#xff1a;Java自学网站推荐--全网最靠谱_IT利刃出鞘的博客-CSDN博客 简介 网上有各种Java学习网站&#xff0c;本文推荐的这个Java网站全网最靠谱&#xff0c;质量远超其他所有网站。 这个网站是&#xff1a;自学精灵&#xff0c;这是全网最强的Java学习网站&…

SpringBootWeb请求-响应

HTTP请求 前后端分离 在这种模式下&#xff0c;前端技术人员基于"接口文档"&#xff0c;开发前端程序&#xff1b;后端技术人员也基于"接口文档"&#xff0c;开发后端程序。 由于前后端分离&#xff0c;对我们后端技术人员来讲&#xff0c;在开发过程中&a…

机器学习算法详解2:线性回归

机器学习算法详解2&#xff1a;线性回归 前言 ​ 本系列主要对机器学习上算法的原理进行解读&#xff0c;给大家分享一下我的观点和总结。 本篇前言 ​ 本篇对线性回归的算法原理进行解读。 目录结构 文章目录 机器学习算法详解2&#xff1a;线性回归1. 引子2. 原理3. 特点4. 问…

如何使用SQL SERVER的OpenQuery

如何使用SQL SERVER的OpenQuery 一、OpenQuery使用说明二、 OpenQuery语法2.1 参数说明2.2注解 三、示例3.1 执行 SELECT 传递查询3.2 执行 UPDATE 传递查询3.3 执行 INSERT传递查询3.4 执行 DELETE 传递查询 一、OpenQuery使用说明 在指定的链接服务器上执行指定的传递查询。 …

领域驱动设计:DDD 关键概念

文章目录 领域和子域核心域、通用域和支撑域通用语言限界上下文实体值对象聚合聚合根设计聚合 DDD 的知识体系提出了很多的名词&#xff0c;像&#xff1a;领域、子域、核心域、通用域、支撑域、限界上下文、聚合、聚合根、实体、值对象等等&#xff0c;非常多。 领域和子域 …

每日一题(两数相加)

每日一题&#xff08;两数相加&#xff09; 2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 思路 思路&#xff1a; 由于链表从头开始向后存储的是低权值位的数据&#xff0c;所以只需要两个指针p1和p2&#xff0c;分别从链表的头节点开始遍历。同时创建一个新的指针new…

记录窗体关闭位置(从窗体上次关闭的位置启动窗体)

从上次关闭位置启动窗体 基础类 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq;namespace WindowsFormsApp1 {public class Reg{public static voi…

OpenCV 12(图像直方图)

一、图像直方图 直方图可以让你了解总体的图像像素强度分布&#xff0c;其X轴为像素值&#xff08;一般范围为0~255&#xff09;&#xff0c;在Y轴上为图像中具有该像素值像素数。 - 横坐标: 图像中各个像素点的灰度级. - 纵坐标: 具有该灰度级的像素个数. 画出上图的直方图: …

算法刷题记录-其他类型(LeetCode)

57 57. Insert Interval 思路 模拟 用指针去扫 intervals&#xff0c;最多可能有三个阶段&#xff1a; 不重叠的绿区间&#xff0c;在蓝区间的左边有重叠的绿区间不重叠的绿区间&#xff0c;在蓝区间的右边 逐个分析 不重叠&#xff0c;需满足&#xff1a;绿区间的右端&…

第 2 章 线性表 ( 双链循环线性表(链式存储结构)实现)

1. 背景说明 2. 示例代码 1) status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H#define CHECK_NULL(pointer) if (!(pointer)) { \printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR…