0%

情景一:想寻找某一方向近些年发表的论文。Kimi就会非常贴心地将文章名称,文章简介,链接甚至是代码汇总。
情景二:如果你查阅了几篇文献,需要根据文章内容写文献综述,那么可以直接将文档丢给它。

常用prompt

  1. 请分析本篇文章(附上文件),并尽量具体地用中文给出以下信息:文章的题目、期刊名及IF、发表作者及单位、摘要;
  2. 请分析文章研究背景及该领域目前的最新进展,给出本文解决的关键问题及创新点;
  3. 请按照文章展开的思路,总结作者所运用的实验方法,以及该方法得出的实验结果,包括主要数据结果描述、对照实验讨论;
  4. 请对文章最终结论进行总结,并详细解释文章末尾的作用机制图;
  5. 请分析文章的不足或可改进之处,以及这篇文章的启示和指导意义;

这次周赛依然只做出了三题:
T1-10min 2wa
T2-5min
T3-17min 1wa
复盘一下:

T1

https://leetcode.cn/problems/make-array-elements-equal-to-zero/

题面

给你一个整数数组 nums 。
开始时,选择一个满足 nums[curr] == 0 的起始位置 curr ,并选择一个移动 方向 :向左或者向右。
此后,你需要重复下面的过程:

  • 如果 curr 超过范围 [0, n - 1] ,过程结束。
  • 如果 nums[curr] == 0 ,沿当前方向继续移动:如果向右移,则 递增 curr ;如果向左移,则 递减 curr 。
  • 如果 nums[curr] > 0:
    • 将 nums[curr] 减 1 。
    • 反转 移动方向(向左变向右,反之亦然)。
    • 沿新方向移动一步。
      如果在结束整个过程后,nums 中的所有元素都变为 0 ,则认为选出的初始位置和移动方向 有效 。
      返回可能的有效选择方案数目。
  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100
  • 至少存在一个元素 i 满足 nums[i] == 0 。

分析

由于数据量比较小,很多人都是模拟做的。但是模拟的代码也比较复杂,涉及到左右方向转换。所以可以找下规律,发现当nums[i] == 0的时候,如果左右两边的数的和相等,那么就可以往两个方向任选一个方向走即可。于是直接这样写了,然后wa了。

其实还可以发现,当左右两边的数的和 suml和sumr,如果|suml - sumr| == 1 ,那么也能成立,但是只能往大的一边走。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
int countValidSelections(vector<int>& nums) {
int n = nums.size();
int sum = 0;
for(auto x: nums) sum += x;
int cur = 0;
int ans = 0;
for(int i = 0; i < n; i ++ ) {
cur += nums[i];
if(nums[i] == 0) {
if(cur == sum - cur) ans += 2; // 左右两边相等
else if(abs(cur - (sum - cur)) == 1) ans += 1; // 左右两边差1
}
}
return ans;
}
};

T2

https://leetcode.cn/problems/zero-array-transformation-i/

题面

给定一个长度为 n 的整数数组 nums 和一个二维数组 queries,其中 queries[i] = [li, ri]
对于每个查询 queries[i]

  • 在 nums 的下标范围 [li, ri] 内选择一个下标子集。
  • 将选中的每个下标对应的元素值减 1。

零数组 是指所有元素都等于 0 的数组。
如果在按顺序处理所有查询后,可以将 nums 转换为 零数组 ,则返回 true,否则返回 false
数组的 子集 是对数组元素的选择(可能为空)。

分析

差分数组模版题,每个位置都有对应操作完的最大值,如果数组该位置超过了最大阈值,则不成立。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
bool isZeroArray(vector<int>& nums, vector<vector<int>>& queries) {
int n = nums.size(), m = queries.size();
vector<int> diff(n + 1), cnt(n + 1);
for(int i = 0; i < m; i ++ ) {
int l = queries[i][0], r = queries[i][1];
diff[l] ++, diff[r + 1] --;
}
cnt[0] = diff[0];
for(int i = 1; i < n; i ++ ) {
cnt[i] = cnt[i - 1] + diff[i];
}
for(int i = 0; i < n; i ++ ) {
if(nums[i] > cnt[i]) return false;
}
return true;
}
};

T3

https://leetcode.cn/problems/zero-array-transformation-ii/description/

题面

给你一个长度为 n 的整数数组 nums 和一个二维数组 queries,其中 queries[i] = [li, ri, vali]

每个 queries[i] 表示在 nums 上执行以下操作:

  • 将 nums 中 [li, ri] 范围内的每个下标对应元素的值 最多 减少 vali
  • 每个下标的减少的数值可以独立选择。

零数组 是指所有元素都等于 0 的数组。

返回 k 可以取到的 最小****非负 值,使得在 顺序 处理前 k 个查询后,nums 变成 零数组。如果不存在这样的 k,则返回 -1。
提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 5 * 105
  • 1 <= queries.length <= 105
  • queries[i].length == 3
  • 0 <= li <= ri < nums.length
  • 1 <= vali <= 5

分析

二分答案+差分数组。
差分数组顾名思义,类似T2的操作,只是这里从加减1变成了常数。可以在o(1)时间内完成区间上加减定值。
由于k越大,越能满足题意,且题意为找一个最小的k,所以这一题的答案据有单调性,可以二份答案区间。这里其实k的取值可以是[1, m],所以右边界可以设置为 m + 1 。当最终得到m+1则证明没有valid答案。
这里二分枚举答案区间,如果在区间内就把右端点 r = mid; 如果不在区间内就把左断点 l = mid + 1;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public:
int minZeroArray(vector<int>& nums, vector<vector<int>>& q) {
int n = nums.size(), m = q.size();
int l = 0, r = m + 1;
auto check = [&](int k) -> bool {
vector<int> diff(n + 1), cnt(n + 1);
for(int i = 0; i < k; i ++ ) {
int l = q[i][0], r = q[i][1], val = q[i][2];
diff[l] += val;
diff[r + 1] -= val;
}
for(int i = 0; i < n; i ++ ) {
cnt[i] = cnt[max(0, i - 1)] + diff[i];
if(cnt[i] < nums[i]) return false;
}
return true;
};
while(l < r) {
int mid = (l + r) / 2;
if(check(mid)) r = mid;
else l = mid + 1;
}
return l == m + 1 ? -1 : l;
}
};

T4

TODO….

前言

多模态大模型发展至今,产生了CLIP、BLIP、BLIP2、InstructBLIP,LLaVA、miniGPT4,等经典模型。以及国内清华的VisualGLM、阿里的Qwen-VL,ailab的InternVL等。每个模型后续还有迭代更新,本文对上述模型做原理解释,以及相关数据支持。

1. 多模态模型

1.1 CLIP

Contrastive Language-Image Pretraining
OpenAI 2021年的工作
paper: https://arxiv.org/abs/2103.00020
github: https://github.com/openai/CLIP
基本思想: CLIP通过大规模的图像和文本对进行对比学习,学习在特征空间中对齐文本和图像,从而理解图像内容和文本描述之间的关联。
模型结构:

  • 图像编码器:通常使用Vision Transformer (ViT) 或者其他卷积神经网络 (CNN) 如ResNet作为backbone。
  • 文本编码器:通常采用BERT或类似基于Transformer的模型。
  • 特征提取后,图像和文本特征通过归一化处理,然后通过点积计算余弦相似度,使用对比损失(info-NCE loss)进行训练。

参考:
https://www.bilibili.com/video/BV1SL4y1s7LQ 【未看完】

1.2 BLIP

Salesforce Research
Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation
paper: https://arxiv.org/abs/2201.12086
github: https://github.com/salesforce/BLIP
基本思想: BLIP旨在通过自举方法来提升模型在视觉-语言理解和生成任务上的性能。BLIP还可以通过生成合成图像描述并使用过滤器去除噪声描述,有效地利用了网络上收集的噪声图像-文本对。
统一了理解与生成

模型结构: BLIP模型采用了多模态混合编码器-解码器(Multimodal Mixture of Encoder-Decoder, MED)架构,该架构可以作为单模态编码器、图像引导的文本编码器或图像引导的文本解码器来操作。MED模型通过三种视觉-语言目标进行联合预训练:图像-文本对比学习(image-text contrastive learning)、图像-文本匹配(image-text matching)和图像条件语言建模(image-conditioned language modeling)。

  • 图像编码器:使用视觉Transformer(如ViT)作为图像编码器,将输入图像分割成多个小块(patches),并将其编码为一系列嵌入向量,同时使用额外的[CLS]标记来表示整个图像的特征。
  • 文本编码器:采用BERT或类似的基于Transformer的模型作为文本编码器,在文本输入的开始处附加[CLS]标记,以汇总句子的表示。
  • 图像引导的文本编码器:在文本编码器的基础上,通过在自注意力(self-attention)层和前馈网络(feed-forward network)之间插入额外的交叉注意力(cross-attention)层来注入视觉信息。
  • 图像引导的文本解码器:替换了图像引导的文本编码器中的双向自注意力层为因果自注意力层,并使用[Decode]标记来指示序列的开始和结束。

    Bootstrapping/自举法

    自举法(Bootstrapping)是一种重采样技术。
    Bootstrapping基本思想是对现有的数据,不断再随机取小的样本,对每个小样处理数据,得到estimator.从而来了解estimator 的分布。
    步骤:
  1. 在原有的样本中通过重抽样(有放回的抽取,即一个数据有可以被重复抽取超过一次) 一定数量(比如100)的样本。
  2. 基于产生的新样本,计算需要的估计量,均值,方差,协方差。
    真实的α分布,和基于bootstrap方法得到的1000个α的分布,二者是比较相近的,也就是说Bootstrap有着不错的估计效果。而且当重复次数增多,Bootstrap的估计效果会更好。

1.3 BLIP2

Salesforce Research
paper: https://arxiv.org/abs/2301.12597
github: https://github.com/salesforce/LAVIS/tree/main

Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models
Based on BLIP and ALBEF

核心原理:
图像(Image)输入了图像编码器(Image Encoder),得到的结果与文本(Text)在 Q-Former(BERT初始化)里进行融合,最后送入LLM模型。
结构:

  • 冻结的 视觉编码器:(如ViT-L/14或ViT-g/14)
  • 冻结的 LLM:如OPT和FlanT5
  • Q-Former(Querying Transformer):BLIP2中可训练的模块,轻量的transformer,用于融合特征。熟悉ALBEF或者BLIP的同学或许发现,Q-Former的结构和ALBEF其实很像,如果看代码的话,可以发现就是在ALBEF基础上改的。

相较于ALBEF,最大的不同,就是Learned Query的引入。
这些query通过cross-attention与图像的特征交互,通过self-attention 与文本的特征交互。
Query是基于两种模态信息得到的;
不管多大的backbone,最后都是Query长度的特征输出,大大降低计算量。
比如在实际实验中,ViT-L/14的模型的输出的特征是257x1024的大小,最后也是32x768Query特征

training:
stage1:
三个task: Image-Text Contrastive Learning (ITC),Image-grounded Text Generation (ITG),Image-Text Matching (ITM)

stage2:
针对两类不同LLM设计了不同的任务:

  1. Decoder类型的LLM(如OPT):以Query做输入,文本做目标;
  2. Encoder-Decoder类型的LLM(如FlanT5):以Query和一句话的前半段做输入,以后半段做目标;
    FC 层:适应模型的不同embedding维度。 参考:
    https://zhuanlan.zhihu.com/p/606364639

1.4 InstructBLIP

通过指令调整(instruction tuning)来构建通用的视觉-语言模型。
Salesforce Research
paper: https://arxiv.org/abs/2305.06500
github: https://github.com/salesforce/LAVIS/tree/main/projects/instructblip
模型结构:InstructBLIP的模型结构基于BLIP2,介绍了如何把指令微调的范式做在 BLIP-2 模型上面。

和BLIP2 类似,InstructBLIP 由图像编码器、LLM 和 Q-Former 组成。
在指令微调期间只训练 Q-Former,冻结图像编码器和 LLM 的参数。

contribution:

  1. 引入 Instruction Tuning (BLIP2中的prefix text换成了 instruction),文本指令不仅提供给冻结的LLM,还提供给Q-Former。
  2. LLM换做Vicuna
    BLIP -> BLIP2 -> InstructBLIP 是一条线,都是 来自 Salesforce Research的团队做的。

1.5 Flamingo🦩

paper: https://arxiv.org/pdf/2204.14198
DeepMind 2022 年的工作,比较老了,没有开源
Challenge:
BLIP2工作中由于只采用了图文对(Image-Text Pair)数据,因此其 in-context 能力欠缺,few-shot 效果不佳。Flamingo 工作中,作者从互联网数据中收集了大量的图文交织(Image-Text Interleaving)数据。

Perceiver Resampler: from varying-size large feature maps to few visual tokens。从视觉编码器(从图像或视频中获得)接收时空特征,并输出固定数量的视觉token。
Vision Encoder: from pixels to features。我们的视觉编码器是一个预训练且参数被固定的NormalizerFree ResNet (NFNet)

Image-Text Interleaving

1.6 LLaVA

llava -> llava1.5 -> llava-next

1.7 Qwen-VL

Qwen-VL -> Qwen-VL 1.5 -> Qwen-VL2
Alibaba

Qwen-VL 在图像描述、问题回答、视觉定位和灵活互动等任务中表现出色。
模型架构:

  • LLM:直接使用了Qwen-7B模型的预训练权重
  • vision encoder:Openclip的ViT-bigG模型。
  • Position-aware Vision-Language Adapter:
    为了缓解由于长图像特征序列而产生的效率问题而提出的。
    适配器包括一个单层的交叉注意力模块,随机初始化。模块使用一组可训练的向量(嵌入)作为查询向量,使用来自视觉编码器的图像特征作为键进行交叉注意力操作。将图像特征序列压缩成了固定长度的256。
    • 作用:
      • 压缩图像特征序列
      • 2D绝对位置编码
  • 为了区分图像特征输入和文本特征输入,作者引入了两个特殊的标记:<img></img>
    • 任务:
      • 区域描述(Region Descriptions):这是描述图像中特定区域的文本,通常包括了区域的位置、特征或属性等信息。
      • 问题(Questions):与区域描述相关的问题,模型需要理解问题并生成相应的回答。
      • 检测(Detections):这些是图像中的检测结果,通常与区域描述和问题相关联。
        training

Qwen2-VL

  • 支持 context length已经达到128K token
  • 支持任意分辨率、比例的素材(img + video + text)输入,在视觉评测集(DocVQA, InfoVQA, RealWorldQA, MTVQA, MathVista等)上取得SoTA结果。
    • 2D Rotary Position Embedding 引入。
  • 支持img + video + text等多种模态的输入,支持20分钟以上视频输入
  • 方法:
    • 范式Vit+ LLM(没有 adapter)
  • 资源使用
    • 目前我在8张a100上训练Qwen2-vl-72b,用deepspeed zero_3勉强能训练起来。

1.8 Intern-VL

Intern-VL -> Intern-VL1.5 -> Intern-VL2
Shanghai AI Lab & SenseTime

1.9 Yi-vision

https://huggingface.co/01-ai/Yi-VL-34B
01.AI
Yi-VL采用 LLaVA 架构,由三个主要组件组成:

  • Vision Transformer (ViT):使用 CLIP ViT-H/14 模型 初始化并用于图像编码。
  • 投影模块:它旨在将图像特征与文本特征空间对齐,由具有层归一化的两层多层感知器 (MLP) 组成。
  • 大型语言模型(LLM):使用 Yi-34B-Chat Yi-34B-Chat 或 Yi-6B-Chat进行初始化,在理解和生成英文和中文方面表现出非凡的熟练程度。

2. 分类

多模态模型总体分为两类:

  1. 基于双编码器 dual encoder 对图像和文本分别编码
  2. 基于融合编码器 fusion encoder 除了图像和文本encoder之外,还有额外的transformer 结构用来融合图像和文本。

3. Pretraining

3.1 tasks

Masked Language Modeling (MLM)

Masked Image Modeling (MIM)

Image-Text Matching (ITM)

Image-Text Contrastive Learning (ITC)

4. 评测

VQA

captioning

reasoning

grounding

img-text retrieval

其他的经典论文

  • ViT vision transformer
  • ALBEF
  • transformer

最近换Macbook了。今晚有空正好把我的hexo搬过来了,在这里分享一下换电脑以后如何转移hexo。

由于GitHub上的页面是经过渲染之后的,所以直接clone是无效的。这里需要拷贝之前设备上的hexo项目路径。
注意删除node_modules文件夹,然后把剩余的文件全部备份。

1. 下载git

1
git --version

检查git是否下载好,以及是否设置了环境变量。

2. 下载node.js

检查 node.js 是否下载好,以及是否设置了环境变量。

1
2
node --version
npm --version

给npm 设置淘宝源,这样下载包更快速。
npm config set registry https://registry.npm.taobao.org/

⚠️ Mac 用户注意:
node.js 和 Git的话,如果你的电脑安装是Mac并且安装了xcode,那么便不用再重新安装。

npm淘宝镜像
npm config set registry https://registry.npm.taobao.org
npm华为镜像
npm config set registry https://mirrors.huaweicloud.com/repository/npm/
全局安装cnpm并设置淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
还原默认镜像
方法一:
npm config delete registry
方法二:
npm config set registry https://registry.npmjs.org
查看当前npm镜像
npm config get registry

3. 准备 hexo

npm install hexo-cli -g 安装hexo

4. 准备blog

拷贝之前设备里的blog项目,并cd到那个目录。

5. 安装依赖

安装之前删除的node_modules文件
npm install 如果显示权限不够 记得 sudo

6. 测试

写一篇博客,测试一下是否可以上传至 GitHub。

1
2
hexo new article_test
hexo d -g

Linux

1. 常用文件管理命令

  • ctrl c键: 取消命令,并且换行

  • ctrl u键: 清空本行命令

  • tab键:可以补全命令和文件名,如果补全不了快速按两下tab键,可以显示备选选项

  • ls: 列出当前目录下所有文件,蓝色的是文件夹,白色的是普通文件,绿色的是可执行文件

  • pwd: 显示当前路径

  • cd XXX: 进入XXX目录下,cd ..返回上层目录

  • cp XXX YYY: 将XXX文件复制成YYYXXXYYY可以是一个路径,比如../dir_c/a.txt,表示上层目录下的dir_c文件夹下的文件a.txt

  • mkdir XXX: 创建目录XXX

  • rm XXX: 删除普通文件; rm XXX -r: 删除文件夹

  • mv XXX YYYXXX文件移动到YYY,和cp命令一样,XXXYYY可以是一个路径;重命名也是用这个命令

  • touch XXX: 创建一个文件

  • cat XXX: 展示文件XXX中的内容

  • 复制文本
    windows/Linux下:Ctrl + insert键Mac下:command + c键

  • 粘贴文本
    windows/Linux下:Shift + insert键Mac下:command + v键

  • top :Linux任务管理器

2. tmux 和 vim

tmux

功能:
(1) 分屏。
(2) 允许断开Terminal连接后,继续运行进程。

结构:

一个tmux可以包含多个session,一个session可以包含多个window,一个window可以包含多个pane。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
tmux:
session 0:
window 0:
pane 0
pane 1
pane 2
...
window 1
window 2
...
session 1
session 2
...
  • tmux:新建一个session,其中包含一个windowwindow中包含一个panepane里打开了一个shell对话框。

  • 按下Ctrl + b后手指松开,然后按%:将当前pane左右平分成两个pane

  • 按下Ctrl + b后手指松开,然后按"(双引号):将当前pane上下平分成两个pane

  • Ctrl + d:关闭当前pane;如果当前window的所有pane均已关闭,则自动关闭window;如果当前session的所有window均已关闭,则自动关闭session`。

  • 鼠标点击可以选pane。按下ctrl + b后手指松开,然后按方向键:选择相邻的pane

  • 鼠标拖动pane之间的分割线,可以调整分割线的位置。按住ctrl + b的同时按方向键,可以调整pane之间分割线的位置。

  • 按下ctrl + b后手指松开,然后按z:将当前pane全屏/取消全屏。

  • 按下ctrl + b后手指松开,然后按d:挂起当前session。(不中断进程退出tmux

  • tmux a:打开之前挂起的session

  • 按下ctrl + b后手指松开,然后按s:选择其它session
    方向键 —— 上:选择上一项 session/window/pane
    方向键 —— 下:选择下一项 session/window/pane
    方向键 —— 右:展开当前项 session/window
    方向键 —— 左:闭合当前项 session/window

  • 按下Ctrl + b后手指松开,然后按c:在当前session中创建一个新的window

  • 按下Ctrl + b后手指松开,然后按w:选择其他window,操作方法同上。

  • 按下Ctrl + b后手指松开,然后按PageUp / 鼠标滚轮:翻阅当前pane内的内容。

  • tmux中选中文本时,需要按住shift键。

  • tmux中复制/粘贴文本的通用方式:

    按下Ctrl + b后松开手指,然后按[
    用鼠标选中文本,被选中的文本会被自动复制到tmux的剪贴板
    按下Ctrl + b后松开手指,然后按],会将剪贴板中的内容粘贴到光标处

vim

功能

​ (1) 命令行模式下的文本编辑器。
​ (2) 根据文件扩展名自动判别编程语言。支持代码缩进、代码高亮等功能。
​ (3) 使用方式:vim filename
​ 如果已有该文件,则打开它。
​ 如果没有该文件,则打开个一个新的文件,并命名为filename

模式

​ (1) 一般命令模式
​ 默认模式。命令输入方式:类似于打游戏放技能,按不同字符,即可进行不同操作。可以复制、粘贴、删除文本等。
​ (2) 编辑模式
​ 在一般命令模式里按下i,会进入编辑模式。
​ 按下ESC会退出编辑模式,返回到一般命令模式。
​ (3) 命令行模式
​ 在一般命令模式里按下:/?三个字母中的任意一个,会进入命令行模式。命令行在最下面。
​ 可以查找、替换、保存、退出、配置编辑器等。

操作

vim .vimrc 设置vim编辑环境

  • i:进入编辑模式
  • ESC:进入一般命令模式
  • h左箭头键:光标向左移动一个字符
  • j向下箭头:光标向下移动一个字符
  • k向上箭头:光标向上移动一个字符
  • l向右箭头:光标向右移动一个字符
  • n<Space>:n表示数字,按下数字后再按空格,光标会向右移动这一行的n个字符
  • 0功能键[Home]:光标移动到本行开头
  • $功能键[End]:光标移动到本行末尾
  • G:光标移动到最后一行
  • :nnG:n为数字,光标移动到第n行
  • gg:光标移动到第一行,相当于1G
  • n<Enter>:n为数字,光标向下移动n行
  • /word:向光标之下寻找第一个值为word的字符串。
  • ?word:向光标之上寻找第一个值为word的字符串。
  • n:重复前一个查找操作
  • N:反向重复前一个查找操作
  • :n1,n2s/word1/word2/gn1n2为数字,在第n1行与n2行之间寻找word1这个字符串,并将该字符串替换为word2
  • :1,$s/word1/word2/g:将全文的word1替换为word2
  • :1,$s/word1/word2/gc:将全文的word1替换为word2,且在替换前要求用户确认。
  • v:选中文本
  • d:删除选中的文本
  • dd: 删除当前行
  • y:复制选中的文本
  • yy: 复制当前行
  • p: 将复制的数据在光标的下一行/下一个位置粘贴
  • u:撤销
  • Ctrl + r:取消撤销
  • 大于号 >:将选中的文本整体向右缩进一次
  • 小于号 <:将选中的文本整体向左缩进一次
  • :w 保存
  • :w! 强制保存
  • :q 退出
  • :q! 强制退出
  • :wq 保存并退出
  • :set paste 设置成粘贴模式,取消代码自动缩进
  • :set nopaste 取消粘贴模式,开启代码自动缩进
  • :set nu 显示行号
  • :set nonu 隐藏行号
  • gg=G 将全文代码格式化
  • :noh 关闭查找关键词高亮
  • Ctrl + q 当vim卡死时,可以取消当前正在执行的命令

3. shell 语法

概述

shell是我们通过命令行与操作系统沟通的语言。

shell脚本可以直接在命令行中执行,也可以将一套逻辑组织成一个文件,方便复用。
Terminal中的命令行可以看成是一个“shell脚本在逐行执行”。

Linux中常见的shell脚本有很多种,常见的有:

  • Bourne Shell(/usr/bin/sh/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • zsh

Linux系统中一般默认使用bash,所以接下来讲解bash中的语法。

文件开头需要写#! /bin/bash,指明bash为脚本解释器。

新建一个test.sh文件,内容如下:

1
2
#! /bin/bash
echo "Hello World!"

运行方式

  • 作为可执行文件
1
2
3
4
5
6
7
acs@9e0ebfcd82d7:~$ chmod +x test.sh  # 使脚本具有可执行权限
acs@9e0ebfcd82d7:~$ ./test.sh # 当前路径下执行
Hello World! # 脚本输出
acs@9e0ebfcd82d7:~$ /home/acs/test.sh # 绝对路径下执行
Hello World! # 脚本输出
acs@9e0ebfcd82d7:~$ ~/test.sh # 家目录路径下执行
Hello World! # 脚本输出
  • 用解释器执行
1
2
acs@9e0ebfcd82d7:~$ bash test.sh
Hello World! # 脚本输出

注释

单行注释

每行中#之后的内容均是注释。

1
2
# 这是一行注释
echo 'Hello World' # 这也是注释

多行注释

格式

1
2
3
4
5
:<<EOF
第一行注释
第二行注释
第三行注释
EOF

其中EOF可以换成其它任意字符串。例如:

1
2
3
4
5
6
7
8
9
10
11
:<<abc
第一行注释
第二行注释
第三行注释
abc

:<<!
第一行注释
第二行注释
第三行注释
!

变量

  • 定义变量
    定义变量,不需要加$符号,例如:
1
2
3
name1='yxc'  # 单引号定义字符串
name2="yxc" # 双引号定义字符串
name3=yxc # 也可以不加引号,同样表示字符串
  • 使用变量
    使用变量,需要加上$符号,或者${}符号。花括号是可选的,主要为了帮助解释器识别变量边界。
1
2
3
4
name=yxc
echo $name # 输出yxc
echo ${name} # 输出yxc
echo ${name}acwing # 输出yxcacwing
  • 只读变量
    使用readonly或者declare可以将变量变为只读。
1
2
3
4
5
name=yxc
readonly name
declare -r name # 两种写法均可

name=abc # 会报错,因为此时name只读
  • 删除变量
    unset可以删除变量。
1
2
3
name=yxc
unset name
echo $name # 输出空行
  • 变量类型
    1. 自定义变量(局部变量)
      子进程不能访问的变量
    2. 环境变量(全局变量)
      子进程可以访问的变量

自定义变量改成环境变量:

1
2
3
acs@9e0ebfcd82d7:~$ name=yxc  # 定义变量
acs@9e0ebfcd82d7:~$ export name # 第一种方法
acs@9e0ebfcd82d7:~$ declare -x name # 第二种方法

环境变量改为自定义变量:

1
2
acs@9e0ebfcd82d7:~$ export name=yxc  # 定义环境变量
acs@9e0ebfcd82d7:~$ declare +x name # 改为自定义变量

字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。

单引号与双引号的区别:

单引号中的内容会原样输出,不会执行、不会取变量;
双引号中的内容可以执行、可以取变量;

1
2
3
name=yxc  # 不用引号
echo 'hello, $name \"hh\"' # 单引号字符串,输出 hello, $name \"hh\"
echo "hello, $name \"hh\"" # 双引号字符串,输出 hello, yxc "hh"

获取字符串长度

获取字符串长度

name=”yxc”
echo $

Python常用语法

基础

安装包

1
2
3
# 以下载numpy为例
pip install numpy -i http://mirrors.aliyun.com/pypi/simple/
pip3 install torch==2.0.0+cu118 -i http://mirrors.aliyun.com/pypi/simple/
阅读全文 »

测试markdown文件是否能上传成功

关于个人博客的搭建

最近换了新电脑,但是博客系统一直是在旧电脑上搭建的,索性写个文档记录一下搭建过程(万一下次又换电脑了呢hhhh…

安装git

  1. 打开git的官网,下载git
阅读全文 »