小知识

Contents

  • Linux
  • VSCode
  • Git and Github
  • Conda
  • Python Dev

TMP

Linux

后台运行

1
nohup bash auto.sh > ./nohub_log/auto_file_name.log 2>&1 &

为了规范化,这里的log的名字就用所运行的对应的.sh文件名字+时间吧。获取当前时间用如下的命令:

1
2
(sr_benchmark) houjinliang@3090server:~/MyCVProject/eSuperResolution/SR_Benchmark$ date "+%Y_%m_%d__%H_%M_%S"
2024_10_03__10_50_16

如果你想在关闭终端后继续运行bash脚本,你可以使用nohup命令或者将脚本作为作业提交到后台。

  • 使用 nohup 命令:nohup 命令用于在退出账户或关闭终端后继续运行指定的命令。

    1
    2
    nohup bash auto.sh &
    # 这将会在后台运行你的脚本,并且即使你关闭了终端,脚本也会继续运行。所有标准输出和错误输出将被重定向到一个名为 nohup.out 的文件中,除非你指定了其他的输出文件。
  • 记录日志: 如果你想记录输出日志,并确保即使关闭终端也能记录,那么结合 nohup 和重定向输出到日志文件是个好方法:

    1
    2
    nohup bash auto.sh > mylog.log 2>&1 &
    # 这里,所有标准输出和错误输出都会被重定向到 mylog.log 文件中。
  • 使用 & 符号: 你也可以直接在命令后加一个 & 符号,将脚本放到后台运行:

1
2
bash auto.sh &
# 然而,这种方法在你关闭终端时不会保护你的进程,除非你同时使用了 nohup。
  • 使用 disown: 如果你已经运行了脚本并希望将其移到后台而不受终端关闭的影响,可以使用 disown 命令:
1
2
3
4
5
6
7
8
9
10
11
12
# 1. 首先运行脚本:
bash auto.sh

# 2. 然后按下 Ctrl + Z 来停止脚本。

# 3. 使用 bg 命令将脚本放入后台:
bg

# 4. 最后,使用 disown 命令从作业列表中移除该作业:
disown

# 这样即使关闭终端,脚本也会继续在后台运行。

两台服务器之间传文件

1
2
3
4
5
6
(base) houjinliang@3090server:~/MyCVProject/eSuperResolution/exp_datasets$ scp -r -P xxxx ./datasets_pet_se8/ houjinliang@10.69.xx.xx:/mnt/houjinliang/MyCVProject/eSuperResolution/exp_datasets
The authenticity of host '[10.69.xx.xx]:xxxx ([10.69.xx.xx]:xxxx)' can't be established.
ECDSA key fingerprint is SHA256:xxxx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[10.69.xx.xx]:xxxx' (ECDSA) to the list of known hosts.
houjinliang@10.69.xx.xx's password:

nvitop kill function

在nvitop的界面中,选择进程按k能直接把程序kill了,按k的时候会有三个选项,这三个选项的意思如下(来着ChatGLM):

kill 是Linux和类Unix操作系统中用于发送信号到程序的一个命令。您提到的 sigterm、sigkill 和 sigint 是可以发送给进程的信号的名称,下面是这些信号的含义:

  • SIGTERM(信号编号15):这是一个标准的程序终止信号。当你发送 SIGTERM 到一个进程时,你是在请求该进程终止。大多数进程在接收到此信号时会进行清理操作,然后退出。但是,进程可以捕获这个信号并决定如何处理它,甚至可以忽略它。

  • SIGKILL(信号编号9):这是一个强制终止信号的信号,不能被进程捕获或忽略。当你发送 SIGKILL 到一个进程时,操作系统会无条件终止该进程。SIGKILL 通常用于结束那些不再响应 SIGTERM 信号的顽固进程。

  • SIGINT(信号编号2):当用户在终端中按下中断键(通常是Ctrl+C)时,shell会发送 SIGINT 到前台进程。这是一个告诉程序中断其当前操作的请求。进程可以选择捕获这个信号并执行特定的清理操作,或者默认情况下,它会由操作系统终止。使用 kill 命令发送这些信号的基本格式如下:

1
2
3
4
5
6
7
8
9
kill -SIGTERM [进程ID]
kill -SIGKILL [进程ID]
kill -SIGINT [进程ID]
# 通常,可以使用信号编号代替信号名称:

kill -15 [进程ID] # 等同于 SIGTERM
kill -9 [进程ID] # 等同于 SIGKILL
kill -2 [进程ID] # 等同于 SIGINT
# 在操作系统中管理进程时,通常首先尝试使用 SIGTERM 来优雅地结束进程,如果进程没有响应,再考虑使用 SIGKILL。SIGINT 则多用于交互式环境中,比如终端。

kill

  • kill PID: 终止进程:默认情况下,kill命令发送SIGTERM(信号15),这可以请求进程终止。如果进程没有捕获这个信号,它将被终止。
  • kill -9 PID: (强制kill)发送 SIGKILL(信号9)将立即结束进程,不能被忽略或捕获。
  • kill -9 -PID: 杀死进程组:使用 -9 选项可以杀死整个进程组。

ps

  • ps -u: 这个命令会列出当前登录用户的进程,并以用户友好的格式显示。它通常会显示进程的用户名、进程ID(PID)、CPU使用时间和命令名。-u选项告诉ps命令按照用户过滤进程信息,如果不指定用户名,则默认显示当前用户的进程。
  • ps -f: 这个命令会以完整的格式显示当前所有进程的信息。-f选项代表“full format”,它提供了更多的信息,如进程的父进程ID(PPID)、启动时间、运行时间、控制终端(TTY)等。如果不与-u选项结合使用,它将显示系统上所有进程的详细信息。
  • ps -f -u(这个最好用): 这个命令与ps -f类似,但是它会过滤出当前登录用户的进程信息,并且以完整格式显示。如果单独使用-u而不指定用户名,它默认会显示当前用户的进程。
  • ps -f -u username: 这个命令会以完整格式显示指定用户username的所有进程。这里username是你要查询的用户的用户名。这个命令对于系统管理员来说非常有用,因为它允许他们查看特定用户的进程,了解用户可能正在运行哪些程序,以及这些程序消耗的系统资源。

ps -f -u username 是在类Unix系统中使用的一个命令,用于查看特定用户(username)的进程信息。下面是对该命令各部分的解释:

  • ps:这是process status的缩写,是用于显示当前系统进程状态的工具。
  • -f:这是ps命令的一个选项,代表“full format”,它会以完整格式的列表显示进程信息。这通常会包括用户、PID(进程ID)、PPID(父进程ID)、C(CPU使用率)、STIME(开始时间)、TTY(终端)、TIME(运行时间)和CMD(命令)等字段。
  • -u username:这个选项告诉ps命令只显示属于指定用户username的进程。在这里,username是你要查询的用户的用户名。

所以,当你执行 ps -f -u username 命令时,你会得到一个列表,显示所有属于用户username的进程及其详细信息。这是一个用于进程管理和监控的有用命令,可以帮助系统管理员或用户了解特定用户运行了哪些进程,以及这些进程的状态和资源使用情况。

Tmux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. 新建会话
tmux new -s SESSION_NAME

2. 分离会话(在会话中,使用分离会话,退出到终端中)(快捷键:Ctrl+b d (先按下Ctrl+b,然后松手,再按下d))
tmux detach

3. 接入会话
tmux attach -t SESSION_NAME

4. 杀死会话
tmux kill-session -t SESSION_NAME

5. 切换会话 (快捷键: Ctrl+b s)
tmux switch -t SESSION_NAME

6. 重命名会话
tmux rename-session -t 0 SESSION_NAME

AUTO_ALL_SR.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
current_time=$(date "+%Y_%m_%d__%H_%M_%S")

Sessionname="$current_time-SR2"
# tmux new -s "$Sessionname" -d 'bash AUTO_log.sh 2'
echo "Established Tmux Session: $Sessionname"
sleep 3

Sessionname="$current_time-SR4"
# tmux new -s "$Sessionname" -d 'bash AUTO_log.sh 4'
echo "Established Tmux Session: $Sessionname"
sleep 3

Sessionname="$current_time-SR8"
# tmux new -s "$Sessionname" -d 'bash AUTO_log.sh 8'
echo "Established Tmux Session: $Sessionname"
sleep 3

echo " "
echo "List all Tmux Session:"
tmux ls

符号链接(英语:Symbolic link),又称软链接,是一类特殊的文件, 其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用。

https://blog.csdn.net/qq_45761493/article/details/120829768
Linux创建软连接一定要用绝对路径

备份服务器上的文件夹

1
2
3
4
5
# 3090本地备份
cd ~
rsync -av --exclude='*.mat' --exclude='checkpoints/*' ./MyCVProject/eSuperResolution/SR_Benchmark/ ./MyBackup/SR_Benchmark_Backup3090_241020/
# 3090远程备份到3080
rsync -av --exclude='*.mat' --exclude='checkpoints/*' -e 'ssh -p xxxx' ./MyCVProject/eSuperResolution/SR_Benchmark/ houjinliang@10.xx.xx.xx:./MyBackup/SR_Benchmark_Backup3090_241020/
1
2
3
4
5
# 3080本地备份
cd ~
rsync -av --exclude='*.mat' --exclude='checkpoints/*' ./MyCVProject/eSuperResolution/SR_Benchmark/ ./MyBackup/SR_Benchmark_Backup3080_241020/
# 3080远程备份到3090
rsync -av --exclude='*.mat' --exclude='checkpoints/*' -e 'ssh -p xxxx' ./MyCVProject/eSuperResolution/SR_Benchmark/ houjinliang@10.xx.xx.xx:./MyBackup/SR_Benchmark_Backup3080_241020/

前台任务转后台

linux:将进程切换到后台且不退出|CSDN

  1. 将进程暂停,然后放在后台(Ctrl + Z)
  2. 使用jobs -l,查看后台的进程,可以看到ID和“Stopped”的状态,以及当前的所执行的命令是什么
  3. 可以将进程切换到前台且继续执行:fg [id] / 也可以让进程在后台继续执行:bg [id]
  4. jobs -l,查看后台的进程,可以看到ID和“Running”的状态,如果是后台执行的话,在命令后面将多一个”&”符号
  5. 通过exit命令退出当前shell。执行exit退出shell后,进程不退出。
  6. 再打开另一个shell,使用ps -ef|grep [xxx]可查看到在后台运行的进程。这里”xxx”指的是之前运行的命令是什么,比如scp, wget, python等。

VSCode

vpdb

1
2
3
4
# install
pip install vpdb
# use
vpdb python main_Apricity.py --ae_title GAE --running_mode train --running_phase ae

VSCode 查找正则表达式

\[[^\]]*\]
查找左右括号及其里面的内容

用在

  • log/A_wandb_sync_errors.log(复制upload上次失败的命令)
  • utils/manually_wandb_upload.sh(粘贴到这里,用正则表达式删去没有的)

Git and Github

git push error!

1
2
3
4
5
6
7
8
9
10
11
# 设置代理
(base) PS D:\Document\DevelopProject\Develop_DeepLearning\HSI\HSI-FSC> git config --global http.proxy http://127.0.0.1:7890
(base) PS D:\Document\DevelopProject\Develop_DeepLearning\HSI\HSI-FSC> git config --global https.proxy http://127.0.0.1:7890
# 查看代理
(base) PS D:\Document\DevelopProject\Develop_DeepLearning\HSI\HSI-FSC> git config --global https.proxy
http://127.0.0.1:7890
(base) PS D:\Document\DevelopProject\Develop_DeepLearning\HSI\HSI-FSC> git config --global http.proxy
http://127.0.0.1:7890
# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy

Github repository 瘦身

被吐槽 GitHub仓 库太大,直接 600M 瘦身到 6M,这下舒服了

查看github仓库大小

只在乎代码的成功运行和快速下载和浏览,不在乎提交记录!直接干脆彻底一点,清理掉仓库的所有提交记录,一劳永逸。既要清除一个分支上的所有提交记录,同时又不能删除这个分支本身,其实我们可以迂回一下。

  1. 我们首先使用 –orphan 命令创建一个全新的分支new-branch,这个新建的分支和其他分支没有任何关系,它不会包含任何先前的提交记录或者历史记录。相当于新建了一个干净的空分支,并让该分支指向一个全新的根节点。
1
git checkout --orphan <new-branch-name>
  1. 然后 commit 全部的项目文件到这个分支,暂不需要推到远程仓库。
1
2
git add -A
git commit -am "Initial commit"
  1. 接着删除旧的分支,并把新建的分支名改成旧分支名称,推到远程仓库就行了。
    1
    2
    3
    git branch -D <old-branch-name>
    git branch -m <old-branch-name>
    git push -f origin <old-branch-name>

Commit Message 个人规范

  1. 改代码

    1
    git commit -m "[Modify] file1\file2\file3 {from hjl-3090server}"
  2. 加模块

    1
    git commit -m "[Add] file1-newmodel\file2-newmodel\ {from hjl-3090server}"
  3. 解决BUG

    1
    git commit -m "[Fix] file1-fixedbugs\file2-fixedbugs\ {from hjl-3090server}"
  4. 删除文件、代码

    1
    git commit -m "[Del] file1\file2-codes\ {from hjl-3090server}"
  5. 组合使用

    1
    git commit -m "[Modify] file1\file2\file3 [Fix] file1-fixedbugs\file2-fixedbugs [Del] file1\file2-codes {from hjl-3090server}"
  6. 待解决

    1
    git commit -m "[Todo] xxxx {from hjl-3090server}"

Git忽略规则.gitignore不生效

Git忽略规则.gitignore不生效-阿里云开发者社区 (aliyun.com)

在项目开发过程中个,一般都会添加 .gitignore 文件,规则很简单,但有时会发现,规则不生效。
原因是 .gitignore 只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。
那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交。

1
2
3
git rm -r --cached .
git add .
git commit -m 'update .gitignore'

git clean -xfd (危险,不要用!)

git clean -xfd 命令会删除你的工作目录中所有未被 Git 跟踪的文件和目录。这是一个非常危险的命令,因为它会永久删除文件,所以在运行之前你应该非常小心。
问ChatGLM关于gitignore规则不生效的问题,它给说了一个这个方法,使用这个方法试了一下,好家伙!目录下的所有文件全都删了。。。。服了!!所有程序重写了。。。

git命令

branch_3090_2分支的修改merge到main上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 切换到branch_3090_2分支
git checkout branch_3090_2

# 2. 拉取到本地
git pull origin branch_3090_2 or git pull

# 3. 切换到main分支
git checkout main

# 4. 合并代码到main分支
git merge branch_3090_2

# 5. 检查,是否合并成功,是否有冲突
git status

# 6. 推送代码
git push origin main or git push

拉取远端main分支更新到branch_3080分支上

首先把当前在本地对branch_3080分支上的修改先commit一下或者是使用git checkout .撤销掉当前的修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 切换到main分支
git checkout main

# 2. 远端的main拉取到本地
git pull origin main or git pull

# 3. 切换到branch_3080分支
git checkout branch_3080

# 4. merge
git merge main

# 5. 检查
git status

# 6. 推送
git push origin branch_3080 or git push

新建本地分支,然后推送到远程

1
2
3
4
5
# 在本地新建一个名为“branch_4090_2”的分支
(base) houjinliang@4090server2:~/MyCVProject/eSuperResolution/SR_Benchmark$ git checkout -b branch_4090_2

# 推送到远端(github.com),远端的分支名称可以与本地分支同名,也可以不同
(base) houjinliang@4090server2:~/MyCVProject/eSuperResolution/SR_Benchmark$ git push origin branch_4090_2:branch_4090_2

git branch

git branch 是Git版本控制系统中的一个基本命令,用于列出、创建或删除分支。下面是 git branch 命令的一些基本用法和含义:

  • 列出分支:git branch:列出所有本地分支。当前所在的分支前面会有一个 * 号。
  • 创建分支:git branch :创建一个名为 的新分支,但不会切换到新分支。
  • 删除分支:git branch -d :删除名为 的本地分支。
  • 强制删除: git branch -D :强制删除名为 的本地分支,即使它有未合并的更改。
  • 重命名分支:git branch -m :将 分支重命名为
  • 查看分支详细信息:git branch -v:列出所有本地分支及其最后提交的信息。
  • 创建并切换分支:git checkout -b :创建一个新分支 并立即切换到该分支。
  • 跟踪分支:git branch –track :创建一个本地分支 以跟踪远程分支
  • 设置上游分支:git branch –set-upstream-to=/ :为本地分支 设置上游分支 /
    在没有参数的情况下,git branch 命令会显示所有本地分支,并标明当前所在的分支。分支在Git中是一种轻量级、可快速切换的工作环境,可以让你在不影响主分支的情况下进行开发工作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
git branch
git branch -a:这个命令会列出所有本地分支和远程分支。-a标志代表“all”,意味着显示所有分支,不仅仅是当前所在的分支。
git branch -r:这个命令仅列出所有远程分支。-r标志代表“remote”,意味着只显示远程仓库的分支信息。

(base) houjinliang@4090server2:~/MyCVProject/eSuperResolution/SR_Benchmark$ git branch -a
* branch_4090_2
main
remotes/origin/HEAD -> origin/main
remotes/origin/branch_3080
remotes/origin/branch_3090
remotes/origin/branch_3090_2
remotes/origin/branch_4090
remotes/origin/branch_4090_2
remotes/origin/main

(base) houjinliang@4090server2:~/MyCVProject/eSuperResolution/SR_Benchmark$ git branch -r
origin/HEAD -> origin/main
origin/branch_3080
origin/branch_3090
origin/branch_3090_2
origin/branch_4090
origin/branch_4090_2
origin/main

在Git中,remote 和 origin 以及 HEAD 都是具有特定含义的关键字:

  • remote: 在Git中,remote 是指一个远程仓库的引用。远程仓库是托管在网络上,可以被多个用户克隆和推送的仓库。你可以通过SSH、HTTP/HTTPS等方式与远程仓库进行交互。

  • origin: origin 是默认的远程仓库名称。当使用 git clone 命令克隆一个仓库时,Git会自动将克隆的仓库命名为 origin。这是一个约定俗成的名称,但你可以通过配置来更改它。通常,origin 指的是你克隆仓库的原始位置。

  • HEAD: HEAD 是Git中一个特殊的引用,它指向当前所在的分支的最后一次提交。简单来说,HEAD 表示当前的工作位置。当你切换分支或者进行提交时,HEAD 的指向会改变。

  • remotes/origin/HEAD -> origin/main:这表示远程仓库 origin 的 HEAD 指向了分支 main。这意味着如果你在本地克隆这个仓库,并且没有切换到其他分支,那么 HEAD 会在本地指向 main 分支。

  • remotes/origin/branch_3080、remotes/origin/branch_3090 等等:这些都是远程仓库 origin 中的分支。它们表示在远程仓库上有不同的开发线或特性分支。

  • origin/main:这是远程仓库 origin 的 main 分支。通常,main(或者在某些情况下是 master)是主分支,包含了项目的主要开发历史。

总的来说,remote origin 是指你通过Git克隆或添加的远程仓库的默认名称,而 HEAD 是一个指针,它告诉你当前在哪个提交上工作,无论是在本地分支还是远程跟踪分支。

git checkout

git checkout 是Git中的一个多功能命令,它主要有以下两种用法:

  • 切换分支:git checkout :这个命令用于切换到名为 的分支。如果 存在于本地仓库中,Git会将你的工作副本更新为 分支的最新状态。
  • 恢复文件:git checkout – :这个命令用于从暂存区(或者某个特定的提交)恢复文件 到工作目录中。这通常用于撤销对文件的未提交更改。

git checkout -b : -b 选项告诉Git在执行 checkout 命令的同时创建一个新分支 。如果当前分支是 ,那么这个命令会创建一个从 分支的最新提交开始的新分支 ,并立即切换到这个新分支。这实际上等价于以下两个命令的组合:

1
2
git branch <new-branch>
git checkout <new-branch>

git fetch

git fetch 是Git中的一个命令,用于从远程仓库获取最新的数据,但不合并到当前的工作分支。

  • 获取远程仓库的数据:git fetch 命令会访问远程仓库,并下载所有你还没有的数据。这包括所有分支的更新以及任何你还没有的标签。
  • 更新远程跟踪分支:当 git fetch 执行后,它更新你的远程跟踪分支(通常是 origin/ 的形式)。这些远程跟踪分支是你本地仓库中远程仓库分支的副本。
  • 不会影响你的工作副本:重要的是要注意,git fetch 命令本身不会改变你工作目录中的文件(即你的当前工作副本)。它只是下载数据,并更新你的远程跟踪分支。

下面是 git fetch 命令的一些使用场景:

  • 查看更新:如果你想查看远程仓库有什么更新,但不希望立即将这些更新合并到你的当前分支,你可以使用 git fetch 来获取这些信息。
  • 准备合并或变基:在合并来自远程仓库的更改之前,你可以使用 git fetch 来更新你的远程跟踪分支,然后你可以决定是使用 git merge 来合并这些更改,还是使用 git rebase 来在你的本地分支上重新应用这些更改。
  • 多人协作:在一个多人协作的项目中,git fetch 可以帮助你了解其他开发者在远程仓库上所做的更改,而不影响你当前的工作。

git push origin branch_3090_2

这个命令的作用是将你本地的分支 branch_3090_2 推送到远程仓库 origin。如果远程仓库中已经存在一个同名的分支,Git 将会更新该远程分支以匹配你的本地分支。如果远程仓库中没有这个分支,Git 将会创建一个新的远程分支。

git push origin branch_3090_2

git push origin –delete branch_3090_2: 这个命令的作用是删除远程仓库 origin 上的分支 branch_3090_2。–delete 标志告诉 Git 你想要删除一个远程分支。执行这个命令后,远程仓库中名为 branch_3090_2 的分支将被移除

git如何从主分支更新到自己的分支

git如何从主分支更新到自己的分支
git将master主分支最新代码合并到自己的分支

要从主分支更新到自己的分支,可以按照以下步骤进行操作:

  1. 确定当前所在分支:使用命令git branch查看当前所在的分支,确认是否在主分支。

  2. 切换到主分支:如果不在主分支,可以使用命令git checkout main(main替换为你的主分支名称)切换到主分支。

  3. 更新主分支:在主分支上,使用命令git pull origin main来拉取远程主分支的最新代码。

  4. 切换到自己的分支:使用命令git checkout branch_3080(branch_3080替换为你的分支名称)切换回你的分支。

  5. 合并主分支的更新:使用命令git merge main将主分支的更新合并到你的分支。

  6. 处理冲突(如果有):如果合并过程中发生冲突,需要根据提示手动解决冲突,并使用git add命令将解决后的文件标记为已解决。

  7. 提交更新:使用命令git commit -m "Merge updates from main branch"提交合并的更新。

  8. 推送到远程仓库:使用命令git push origin branch_3080将更新的代码推送到远程仓库的你的分支。

完成以上步骤后,你的分支就会包含主分支的最新更新内容。记得定期更新主分支,以便保持代码同步和避免冲突。

Conda env

conda环境打包,然后从一个设备迁移到另外的一个设备

  1. 直接把整个环境打包成压缩包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # pip 下载安装conda-pack包
    (SSPSR) houjinliang@3080server:~/MyCVProject/eSuperResolution/Re_SSPSR$ pip install conda-pack

    # 查看当前设备的conda environments:
    (SSPSR) houjinliang@3080server:~/MyCVProject/eSuperResolution/Re_SSPSR$ conda env list

    base /mnt/houjinliang/miniconda3
    SSPSR * /mnt/houjinliang/miniconda3/envs/SSPSR
    xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    #把SSPSR环境打包
    (SSPSR) houjinliang@3080server:~/MyCVProject/eSuperResolution/Re_SSPSR$ conda pack -n SSPSR
    Collecting packages...
    Packing environment at '/mnt/houjinliang/miniconda3/envs/SSPSR' to 'SSPSR.tar.gz'
    [################################# ] | 83% Completed | 3min 30.7s
  2. 把环境压缩包上传到新设备上,直接在对应位置解压缩

  • 最常用的文件传输软件FileZilla居然只支持本地站点和远程指点之间的文件传输,两个远程站点之间的传输不支持。所以只能借助本地为桥梁,先传到本地,在传到新服务器上。(不对!)
  • 可以借助scp命令,见“两台服务器之间传文件”
1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 先在新服务器上建立整个环境的文件夹
(base) houjinliang@3090server:~/miniconda3/envs/SSPSR$ pwd
/mnt/houjinliang/miniconda3/envs/SSPSR

## 2. 解压
(base) houjinliang@3090server:~/MyDownloadFiles$ tar -xzvf SSPSR.tar.gz -C /mnt/houjinliang/miniconda3/envs/SSPSR

## 3. 查看
(base) houjinliang@3090server:~/MyDownloadFiles$ conda env list
base * /mnt/houjinliang/miniconda3
SSPSR /mnt/houjinliang/miniconda3/envs/SSPSR

# 完成虚拟环境的迁移了!

environment.yml

1
2
3
(SSPSR) houjinliang@3080server:~/MyCVProject/eSuperResolution/Re_SSPSR$ conda env export > environment.yml

conda env create -f environment.yml
1
2
3
conda env create -f environment.yml

# 新建的环境根据yml中的name来命名新环境

conda环境打包

  1. 直接把整个环境打包成压缩包
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    (SSPSR) houjinliang@3080server:~/MyCVProject/eSuperResolution/Re_SSPSR$ pip install conda-pack
    (SSPSR) houjinliang@3080server:~/MyCVProject/eSuperResolution/Re_SSPSR$ conda env list
    # conda environments:
    #
    base /mnt/houjinliang/miniconda3
    SSPSR * /mnt/houjinliang/miniconda3/envs/SSPSR
    xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    (SSPSR) houjinliang@3080server:~/MyCVProject/eSuperResolution/Re_SSPSR$ conda pack -n SSPSR
    Collecting packages...
    Packing environment at '/mnt/houjinliang/miniconda3/envs/SSPSR' to 'SSPSR.tar.gz'
    [################################# ] | 83% Completed | 3min 30.7s
  2. 把环境压缩包上传到新设备上,直接在对应位置解压缩

最常用的文件传输软件FileZilla居然支支持本地站点和远程指点之间的文件传输,两个远程站点之间的传输不支持。所以只能借助本地为桥梁,先传到本地,在传到新服务器上。

现在新服务器上建立整个环境的文件夹

1
2
(base) houjinliang@3090server:~/miniconda3/envs/SSPSR$ pwd
/mnt/houjinliang/miniconda3/envs/SSPSR

解压

1
(base) houjinliang@3090server:~/MyDownloadFiles$ tar -xzvf SSPSR.tar.gz -C /mnt/houjinliang/miniconda3/envs/SSPSR

完成虚拟环境的迁移了!

1
2
3
4
5
(base) houjinliang@3090server:~/MyDownloadFiles$ conda env list
# conda environments:
#
base * /mnt/houjinliang/miniconda3
SSPSR /mnt/houjinliang/miniconda3/envs/SSPSR

使用clone方法创建Torch环境的流程

image-20240718150404471

1
2
3
4
conda create -n py38torch1101-cu113 python=3.8
cd MyDownloadFiles/offlinefile/
pip install torch-1.10.1+cu113-cp38-cp38-linux_x86_64.whl torchvision-0.11.2+cu113-cp38-cp38-linux_x86_64.whl
conda create -n MotionBERT --clone py38torch1101-cu113
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(py38torch1101-cu113) houjinliang@3080server:~$ pip list
Package Version
----------------- ------------
cachetools 5.3.3
numpy 1.24.4
nvidia-ml-py 12.535.161
nvitop 1.3.2
pillow 10.4.0
pip 24.0
psutil 6.0.0
setuptools 69.5.1
termcolor 2.4.0
torch 1.10.1+cu113
torchvision 0.11.2+cu113
typing_extensions 4.12.2
wheel 0.43.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(py38torch1101-cu113) houjinliang@3080server:~/MyDownloadFiles/offlinefile$ ll
总用量 44156456
drwxrwxr-x 6 houjinliang houjinliang 4096 7月 12 11:10 ./
drwxrwxr-x 12 houjinliang houjinliang 4096 7月 12 12:03 ../
-rw-rw-r-- 1 houjinliang houjinliang 1821456984 5月 30 22:41 torch-1.10.0+cu113-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1821412903 6月 13 19:58 torch-1.10.0+cu113-cp38-cp38-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 881913771 6月 13 19:58 torch-1.10.1-cp38-cp38-manylinux1_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1831320975 7月 11 16:40 torch-1.10.1+cu113-cp38-cp38-linux_x86_64.whl ⭐
-rw-rw-r-- 1 houjinliang houjinliang 1821442173 6月 13 19:42 torch-1.10.2+cu113-cp38-cp38-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1837736693 5月 9 16:33 torch-1.12.1+cu113-cp39-cp39-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1156750317 6月 13 15:45 torch-1.7.1+cu110-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 735494141 5月 30 22:21 torch-1.8.0-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1982170278 5月 30 22:40 torch-1.8.1+cu111-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 23185811 5月 30 22:44 torchvision-0.10.0+cu111-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 21802303 5月 30 22:38 torchvision-0.11.0+cu113-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 21800388 6月 13 19:50 torchvision-0.11.0+cu113-cp38-cp38-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 24585273 6月 13 19:48 torchvision-0.11.2+cu113-cp38-cp38-linux_x86_64.whl ⭐
-rw-rw-r-- 1 houjinliang houjinliang 12930152 6月 13 15:44 torchvision-0.8.2+cu110-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1999639040 1月 1 2019 VOCtrainval_11-May-2012.tar

使用clone方法创建PyTorch环境的流程(个人)

  1. 模板环境
    1
    2
    3
    4
    # py38torch1101-cu113是个人的一个模板环境
    conda create -n py38torch1101-cu113 python=3.8
    cd MyDownloadFiles/offlinefile/
    pip install torch-1.10.1+cu113-cp38-cp38-linux_x86_64.whl torchvision-0.11.2+cu113-cp38-cp38-linux_x86_64.whl

看一下模板环境有什么包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(py38torch1101-cu113) houjinliang@3080server:~$ pip list
Package Version
----------------- ------------
cachetools 5.3.3
numpy 1.24.4
nvidia-ml-py 12.535.161
nvitop 1.3.2
pillow 10.4.0
pip 24.0
psutil 6.0.0
setuptools 69.5.1
termcolor 2.4.0
torch 1.10.1+cu113
torchvision 0.11.2+cu113
typing_extensions 4.12.2
wheel 0.43.0

看一下模板环境用的什么版本的pytorch离线包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(py38torch1101-cu113) houjinliang@3080server:~/MyDownloadFiles/offlinefile$ ll
总用量 44156456
drwxrwxr-x 6 houjinliang houjinliang 4096 7月 12 11:10 ./
drwxrwxr-x 12 houjinliang houjinliang 4096 7月 12 12:03 ../
-rw-rw-r-- 1 houjinliang houjinliang 1821456984 5月 30 22:41 torch-1.10.0+cu113-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1821412903 6月 13 19:58 torch-1.10.0+cu113-cp38-cp38-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 881913771 6月 13 19:58 torch-1.10.1-cp38-cp38-manylinux1_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1831320975 7月 11 16:40 torch-1.10.1+cu113-cp38-cp38-linux_x86_64.whl ⭐
-rw-rw-r-- 1 houjinliang houjinliang 1821442173 6月 13 19:42 torch-1.10.2+cu113-cp38-cp38-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1837736693 5月 9 16:33 torch-1.12.1+cu113-cp39-cp39-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1156750317 6月 13 15:45 torch-1.7.1+cu110-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 735494141 5月 30 22:21 torch-1.8.0-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1982170278 5月 30 22:40 torch-1.8.1+cu111-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 23185811 5月 30 22:44 torchvision-0.10.0+cu111-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 21802303 5月 30 22:38 torchvision-0.11.0+cu113-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 21800388 6月 13 19:50 torchvision-0.11.0+cu113-cp38-cp38-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 24585273 6月 13 19:48 torchvision-0.11.2+cu113-cp38-cp38-linux_x86_64.whl ⭐
-rw-rw-r-- 1 houjinliang houjinliang 12930152 6月 13 15:44 torchvision-0.8.2+cu110-cp37-cp37m-linux_x86_64.whl
-rw-rw-r-- 1 houjinliang houjinliang 1999639040 1月 1 2019 VOCtrainval_11-May-2012.tar
  1. 通过clone模板环境py38torch1101-cu113,建立新的环境MotionBERT
    1
    conda create -n MotionBERT --clone py38torch1101-cu113

Python Dev

wandb : nvidia_gpu_stat占过多的CPU资源

wandb/wandb: [Bug]: nvidia_gpu_stats binary causes high CPU cycle usage.

在跑程序的时候遇到一个问题,服务器的CPU资源占据非常高!使用top命令查看发现是有好多“nvidia_gpu_stats”进程在疯狂占据CPU的资源,网上搜索了一下发现,这是wandb的锅!wandb会监控系统的资源,将其关掉就好了!(这样就看不到GPU的log曲线了,但这个也没什么用处,关了也无妨。

Matplotlib - cmap

matplotlib

torchvision.models -> pretrained models

模型下载地址更改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 默认的地址
>>> import torch
>>> torch.hub.get_dir()
'/data/houjinliang/.cache/torch/hub'

# 更改地址
# 1. 先建立一个文件夹
>>> import os
>>> current_workspace_path = os.getcwd()
>>> torch_pretrained_model_path = os.path.join(current_workspace_path, 'torch_pretrained_model')
>>> if not os.path.exists(torch_pretrained_model_path):
... os.makedirs(torch_pretrained_model_path)
# 2. 使用os.environ设置Torch HOME
>>> os.environ['TORCH_HOME'] = torch_pretrained_model_path
>>> torch.hub.get_dir()
'/data/houjinliang/MyCVProject/eSuperResolution/SR_Benchmark/torch_pretrained_model/hub'
# 3. 检查
>>> print(f"This pretrained model downloaded by Torchvision will save at {torch.hub.get_dir()}")
This pretrained model downloaded by Torchvision will save at /data/houjinliang/MyCVProject/eSuperResolution/SR_Benchmark/torch_pretrained_model/hub
#4. 下载
>>> import torchvision.models as models
>>> net = models.vgg16(pretrained=True)
Downloading: "https://download.pytorch.org/models/vgg16-397923af.pth" to /mnt/houjinliang/MyCVProject/eSuperResolution/SR_Benchmark/torch_pretrained_model/hub/checkpoints/vgg16-397923af.pth

感知损失(Perceptual Losses)

感知损失|知乎

如何理解 “图像傅里叶变换的频谱图”

CSDN
这篇文章写的还是比较通俗易懂的,可能不是那么深入,但至少是就能把频谱图给看懂了。

通过ssh方式连接的服务器如何查看图片

通过ssh方式连接的服务器,在运行plt.imshow()的时候,因为没有桌面,是无法显示图像的。如何解决?

  1. plt.imsave(),保存到服务器上,然后用vscode查看。
  2. 使用visdom工具。

visdom工具在做本科毕设的使用用到过,这次再拿出来用一下。

fossasia/visdom

超分任务不使用BN

超分辨中为什么不用BN层?
超分网络一般不需要BN

Batch Norm可谓深度学习中非常重要的技术,不仅可以使训练更深的网络变容易,加速收敛,还有一定正则化的效果,可以防止模型过拟合。在很多基于CNN的分类任务中,被大量使用。
但在图像超分辨率和图像生成方面,Batch Norm的表现并不好,加入了Batch Norm,反而使得训练速度缓慢,不稳定,甚至最后发散。

以图像超分辨率来说,网络输出的图像在色彩、对比度、亮度上要求和输入一致,改变的仅仅是分辨率和一些细节,而Batch Norm,对图像来说类似于一种对比度的拉伸,任何图像经过Batch Norm后,其色彩的分布都会被归一化,也就是说,它破坏了图像原本的对比度信息,所以Batch Norm的加入反而影响了网络输出的质量。虽然Batch Norm中的scale和shift参数可以抵消归一化的效果,但这样就增加了训练的难度和时间,还不如直接不用。不过有一类网络结构可以用,那就是残差网络(Residual Net),但也仅仅是在residual block当中使用,比如SRResNet,就是一个用于图像超分辨率的残差网络。为什么这类网络可以使用Batch Norm呢?有人认为是因为图像的对比度信息可以通过skip connection直接传递,所以也就不必担心Batch Norm的破坏了。

基于这种想法,也可以从另外一种角度解释Batch Norm为何在图像分类任务上如此有效。图像分类不需要保留图像的对比度信息,利用图像的结构信息就可以完成分类,所以,将图像都通过Batch Norm进行归一化,反而降低了训练难度,甚至一些不明显的结构,在Batch Norm后也会被凸显出来(对比度被拉开了)。

而对于照片风格转移,为何可以用Batch Norm呢?原因在于,风格化后的图像,其色彩、对比度、亮度均和原图像无关,而只与风格图像有关,原图像只有结构信息被表现到了最后生成的图像中。因此,在照片风格转移的网络中使用Batch Norm或者Instance Norm也就不奇怪了,而且,Instance Norm是比Batch Norm更直接的对单幅图像进行的归一化操作,连scale和shift都没有。

说得更广泛一些,Batch Norm会忽略图像像素(或者特征)之间的绝对差异(因为均值归零,方差归一),而只考虑相对差异,所以在不需要绝对差异的任务中(比如分类),有锦上添花的效果。而对于图像超分辨率这种需要利用绝对差异的任务,Batch Norm只会添乱。

模型复杂度评估

这三个指标可以用来衡量模型的复杂度,即模型计算量的大小。

  • FLOPs(Floating point operations per second)是指每秒浮点运算次数
  • MACs (Multiply-Accumulate Operations)是指乘加操作的次数
  • Params(Parameters)是指模型的参数数量。

✖️查看模型权重和模型结构(pth2pnnx, netron,tensorboard.add_graph)

在使用netron查看模型的权重和文件的时候,如果直接查看pth。
netron trained_model/PaviaC_NationalDay6_Window4_Embed60_Subs16_Ovlps4_Scale4_Epochs150_2024_10_07_01_16_13.pth
Serving ‘trained_model/PaviaC_NationalDay6_Window4_Embed60_Subs16_Ovlps4_Scale4_Epochs150_2024_10_07_01_16_13.pth’ at http://localhost:8080
是看不到模型结构的,只有模型的节点权重。

有一个解决办法是把pth转onnx
netron trained_model/PaviaC_NationalDay6_Window4_Embed60_Subs16_Ovlps4_Scale4_Epochs150_2024_10_07_01_16_13.onnx

然后就能看到模型的结构了。

但带来一个问题是,模型太复杂了,电脑根本带不动,特别特别卡顿!
虽然是在服务器端运行,但是显示是在终端的浏览器上,所以还是需要终端的电脑足够强的。

所以还是不用了。

此外,使用tensorboard的add_graph API也可以,但是没在所有的模型上调通(也是不用了)。并且调通了之后发现也是特别卡,对设备的性能要求还是很高啊。

wandb sync offline

Weights & Biases使用指南 | github.io

1
2
cd wandb/
ls | grep -E "run|offline" | grep -v latest | xargs wandb sync --no-mark-synced

设置可见的CUDA

1
2
3
4
5
6
7
8
os.environ['CUDA_VISIBLE_DEVICES'] = '6'
print(f"Number of visible GPUs: {torch.cuda.device_count()}")
print(f"Current device index: {torch.cuda.current_device()}")

# Number of visible GPUs: 1
# Current device index: 0
# 这里设置的可见的CUDA是只有cuda:6,所以在可见的cuda中,这个index是0.
# 因此如果print(x.device)输出的结果是cuda:0,则不一定代表当初的变量是在整个系统的cuda:0上,而是在可见的CUDA设备中的cuda:0上。

python -m models.SSPSR 一种通过模块方式运行 Python 脚本的方式

python -m models.SSPSR 是一种通过模块方式运行 Python 脚本的方式,-m 参数会让 Python 把指定的模块当作脚本来执行,同时能够正确处理模块的导入路径问题。

解释

python -m:告诉 Python 解释器要运行一个模块,而不是直接运行一个文件。
models.SSPSR:这里表示模块的路径,即 models 是一个包(文件夹),SSPSR 是包中的一个模块(Python 文件 SSPSR.py)。
当你使用 python models/SSPSR.py 运行脚本时,Python 会把当前工作目录作为路径的起点,而不考虑项目的根目录,因此它找不到 utils 目录中的模块。

使用 python -m models.SSPSR,Python 会从项目的根目录开始查找 models 包中的 SSPSR 模块,这样就能正确导入 utils 模块。

要求

要使用 python -m 的前提是你的项目结构必须符合 Python 包的规范:
models/ 和 utils/ 目录中应该有一个 init.py 文件(即使是空文件),告诉 Python 这些目录是包。
你需要在项目的根目录下运行这个命令,比如:

1
2
3
cd ~/MyCVProject/eSuperResolution/SR_Benchmark
python -m models.SSPSR
# 这样,Python 会正确解析 models 和 utils 目录间的相对路径。

init.py 是 Python 中的一个特殊文件,它的作用是将包含它的目录标记为一个 Python 包,使你可以通过模块导入的方式访问目录中的 Python 文件或子包。

主要作用:

  • 标记目录为包: 如果一个目录中包含 init.py,Python 会将这个目录当作一个包,允许你从外部导入该包及其中的模块。没有这个文件时,Python 会认为这个目录只是普通文件夹,不是包,无法使用 import 进行模块导入。
  • 初始化包: init.py 还可以包含一些包的初始化代码,比如导入包中的某些模块或设置一些包级别的变量。

你的场景:

你有一个 models 目录和一个 utils 目录,为了让 Python 能够正确识别 models 和 utils 作为包,你需要在这两个目录中各自添加一个 init.py 文件。

操作步骤:

在 models/ 目录中添加一个空的 init.py 文件:

1
2
3
4
touch models/__init__.py
# 在 utils/ 目录中同样添加一个 __init__.py 文件:
touch utils/__init__.py
# 即使文件为空,它们也会告诉 Python 这些目录是包,从而让导入如 from utils.nn_units import ... 变得有效。

Python中的注释

1
2
3
4
5
6
7
r"""
\n
"""

"""
\n
"""
  • 在Python中,r""" """ 是一个多行原始字符串的表示方式。这里的 r 代表 “raw”,意味着字符串中的转义字符不会被特殊处理。以下是关于原始字符串的一些要点:
  • 原始字符串:在原始字符串中,反斜杠 \ 不会被当作转义字符。例如,在普通字符串中 \n 表示换行,但在原始字符串中,\n 就是两个字符:反斜杠和字母 ‘n’。
  • 多行字符串:使用三个双引号 “”” 或三个单引号 ‘’’ 可以创建一个多行字符串,字符串中的换行符会被保留。
    所以,r””” “”” 结合了原始字符串和多行字符串的特性,意味着你可以创建一个跨越多行的字符串,同时不需要担心转义字符的问题。
1
2
3
4
5
6
7
8
9
10
11
12
# 普通字符串
normal_str = "This is a newline: \n followed by a backslash: \\"
print(normal_str)

# 原始字符串
raw_str = r"This is a newline: \n followed by a backslash: \\"
print(raw_str)

# 输出结果
This is a newline:
followed by a backslash: \
This is a newline: \n followed by a backslash: \\

torch.nn.functional.pad 函数解释

  • 在Swin Transformer中,因为要涉及到“图像”的尺寸需要把Window size整除,所以需要提前把“图像”给padding成合适的尺寸,这里就需要用到pad函数。
  • torch.nn.functional.pad|pytorch.org

os.environ[‘CUDA_VISIBLE_DEVICES’] = args.gpus

1
2
3
4
5
6
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus 
# 这是一个环境变量,专门用于控制运行在NVIDIA GPU上的程序,告诉程序哪些GPU是可见的。
# 在深度学习或者其他需要使用GPU加速的场合,这个环境变量经常被用来指定使用哪些GPU。

# os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus: 这行代码将用户指定的GPU编号赋值给CUDA_VISIBLE_DEVICES环境变量。
# 这意味着只有编号在args.gpus中的GPU对程序是可见的。如果args.gpus设置为'0,1',则只有编号为0和1的GPU会被程序使用。

wandb login api key

wandb Github Issues

You can find your API key in your browser here: https://wandb.ai/authorize

Wandb docs

(sr_benchmark) houjinliang@3090server2:~/MyCVProject/eSuperResolution/exp_datasets$ wandb login
wandb: Currently logged in as: cosmicdustycn (cosmicdustycn-npu). Use wandb login --relogin to force relogin

wandb log

  • install & login

    1
    2
    3
    4
    (sr_benchmark) houjinliang@3090server:~$ pip install wandb
    # 输入https://wandb.ai/home的密钥
    (sr_benchmark) houjinliang@3090server:~$ wandb login
    wandb: Currently logged in as: cosmicdustycn (cosmicdustycn-npu). Use `wandb login --relogin` to force relogin
  • init

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    wandb.init(
    # set the wandb project where this run will be logged
    project="your_project_name"
    name="your_experiment_name"

    # track hyperparameters and run metadata
    config={
    "learning_rate": xx
    "batch_size": xx
    "epochs": xx
    }
    )
  • log

    1
    2
    3
    4
    5
    6
    7
    8
    wandb.log({
    "epoch":e,
    "n_iter":n_iter,
    "train_loss" : train_loss,
    "avg_epoch_loss": epoch_loss,
    "avg_validation_loss": eval_loss,
    "learning_rate": lr
    })

📌(TODO)wandb sweep

wandb offline and sync

在main函数的wandb init中加入关于mode的两行代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
os.environ["WANDB_MODE"] = "offline"

wandb.init(
# set the wandb project where this run will be logged
project="your_project_name"
name="your_experiment_name"

mode="offline",

# track hyperparameters and run metadata
config={
"learning_rate": xx
"batch_size": xx
"epochs": xx
}
)

在main代码文件跑完之后,会输出用什么命令来sync

1
2
3
4
5
6
7
8
9
10

You can sync this run to the cloud by running:
wandb sync /mnt/houjinliang/MyCVProject/eSuperResolution/SR_Benchmark/wandb/offline-run-20240917_164903-erkfg070
Find logs at: wandb/offline-run-20240917_164903-erkfg070/logs


wandb sync /mnt/houjinliang/MyCVProject/eSuperResolution/SR_Benchmark/wandb/offline-run-20240917_145545-qfuofp0z

# Find logs at: /mnt/houjinliang/MyCVProject/eSuperResolution/SR_Benchmark/wandb/debug-cli.houjinliang.log
# Syncing: https://wandb.ai/cosmicdustycn-npu/SR_Benchmark/runs/qfuofp0z ... done.

torh.roll

torch.roll 是 PyTorch 提供的一个函数,用于对张量(tensor)进行滚动操作。具体来说,这个函数会将张量的元素沿着指定的维度(dimension)滚动一定数量的步幅。

以下是 torch.roll 的基本用法:
torch.roll(input, shifts, dims)

  • input:要滚动的张量。
  • shifts:每个维度要滚动的步数。这个参数可以是单个整数,也可以是与 input 维度数目相同的元组,以指定每个维度滚动的步数。
  • dims:一个包含要滚动维度的整数列表。如果这个参数被省略,则所有维度都会被滚动。

函数的工作方式如下:

  1. 对于 dims 中指定的每个维度,input 张量的元素会按照 shifts 指定的步数进行滚动。
  2. 正数表示元素向更高的索引方向滚动,而负数表示元素向更低的索引方向滚动。
  3. 滚动是在指定维度内进行的,不会影响其他维度。

多头注意力机制(Multi-Head Attention)中,head_dim = dim // num_heads,不能整除怎么办

在深度学习中,特别是在多头注意力机制(Multi-Head Attention)中,head_dim = dim // num_heads 这行代码用于计算每个注意力头的维度。这里的 dim 是总的特征维度,而 num_heads 是注意力头的数量。

如果 dim 不能被 num_heads 整除,直接使用整数除法(//)会导致 head_dim 是一个整数,且不包含余数。这意味着,如果存在余数,那么总的维度将无法完全被注意力头均匀分配。

处理这种情况有几种方法:

  • 向上取整:将 dim 除以 num_heads 并向上取整,以确保每个头至少获得足够的维度。这可以通过使用 math.ceil 函数来实现。
  • 向下取整并调整:首先使用整数除法计算 head_dim,然后将剩余的维度平均分配给前几个头。这需要一些额外的代码来处理。
  • 直接舍去余数:忽略不能均匀分配的维度,只使用可以均匀分配的部分。

选择哪种方法取决于你的具体需求和对性能的考虑。在某些情况下,小的余数可能不会对模型性能产生重大影响,因此可以直接舍去或均匀分配。在其他情况下,可能需要更精确的维度分配。

view() & permute() & transpose()

在编程和数据处理中,view(), permute(), 和 transpose() 这三个函数常常用于数组的操作,尤其是在Python的NumPy库中。下面是它们各自的定义和区别:

  1. view():
  • view() 函数返回一个新的数组对象,这个对象与原始数组共享相同的数据,但是具有不同的形状。这意味着,当你通过view()改变数组形状时,原始数组的数据不会被复制,而是通过不同的视角来查看同一块数据。
  • 使用view()通常是为了节省内存,因为它不会进行数据的复制。
  • 示例:如果有一个形状为(3, 4)的数组,使用.view()并指定新的形状为(4, 3)将不会改变底层数据的存储,但是会改变数组的形状。
  1. permute():
  • permute() 函数通常用于重新排列数组的维度。在有些库(如PyTorch)中,permute()可以接受一个维度索引的排列,并根据这个排列来返回一个新的数组,其维度顺序被改变。
  • 使用permute()时,原始数据同样不会被复制,仅仅是改变了维度的顺序。
  • 示例:对于一个形状为(2, 3, 4)的数组,使用.permute(2, 0, 1)将返回一个形状为(4, 2, 3)的新数组。
  1. transpose():
  • transpose() 函数用于交换数组的两个维度。在二维数组中,这通常意味着行和列的交换。在多维数组中,transpose()可以接受一个维度索引的元组,用于指定需要交换的维度。
  • 与view()和permute()一样,transpose()也不会复制数据,它只是返回一个提供了不同视角的数组。
  • 对于二维数组,transpose()默认交换第一个和第二个维度。对于更高维度的数组,需要指定维度索引。
  • 示例:对于一个形状为(2, 3)的二维数组,使用.transpose()将返回一个形状为(3, 2)的新数组。对于一个形状为(2, 3, 4)的三维数组,使用.transpose(0, 2, 1)将返回一个形状为(2, 4, 3)的新数组。

总结:

  • view() 更改数组的形状而不改变数据的连续性。
  • permute() 重新排列数组的维度顺序。
  • transpose() 交换数组中的两个或多个维度。
  • 在使用这些函数时,需要注意它们都不会改变原始数组的数据,只是提供了不同的访问方式。如果需要对数组进行深拷贝,应使用copy()函数。

relative_position_index & relative_position_bias_table & relative_position_bias

relative_position_index

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# get pair-wise relative position index for each token inside the window
coords_h = torch.arange(self.window_size[0])
coords_w = torch.arange(self.window_size[1])
coords = torch.stack(torch.meshgrid([coords_h, coords_w], indexing="ij")) # [2, Mh, Mw]
coords_flatten = torch.flatten(coords, 1) # [2, Mh*Mw]

# [2, Mh*Mw, 1] - [2, 1, Mh*Mw]
relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # [2, Mh*Mw, Mh*Mw] (张量广播)

relative_coords = relative_coords.permute(1, 2, 0).contiguous() # [Mh*Mw, Mh*Mw, 2]

# 二元位置索引 -> 一元位置索引
relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0
relative_coords[:, :, 1] += self.window_size[1] - 1
relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1
relative_position_index = relative_coords.sum(-1) # [Mh*Mw, Mh*Mw] # 相对位置索引

self.register_buffer("relative_position_index", relative_position_index)
# 只要窗口的尺寸不变,relative_position_index就是不变的
# 在训练过程中,变化的是relative_position_bias_table

在PyTorch框架中,self.register_buffer()是一个在模型中注册一个缓冲区(buffer)的方法,这个缓冲区不是模型参数,但是它会在模型的保存和加载过程中与模型参数一起被保存和加载。以下是对代码self.register_buffer(“relative_position_index”, relative_position_index)的解释:

  • self: 这是模型的一个实例。在PyTorch中,模型的类通常继承自torch.nn.Module,self代表这个模型实例本身。
  • register_buffer(): 这是一个PyTorch模块的方法,用于注册一个缓冲区。缓冲区与模型参数(通过nn.Parameter定义)不同,它们在模型的前向传播中不会进行梯度计算(即不会被更新),但是它们可以随模型一起保存和加载。
  • “relative_position_index”: 这是一个字符串,用于给注册的缓冲区命名。这个名字可以用来在模型内部访问这个缓冲区。
  • relative_position_index: 这是一个张量(tensor),是你想要注册为缓冲区的数据。在调用register_buffer()之后,你可以通过self.relative_position_index来访问这个缓冲区。

具体到这段代码的上下文,relative_position_index可能是用于在模型中编码相对位置信息的索引。例如,在Transformer模型中,相对位置编码是一个重要的概念,它帮助模型理解序列中元素之间的相对位置关系。

使用register_buffer()的好处是,当你保存和加载模型时,这个相对位置索引不需要在模型的state_dict之外单独处理,它会自动被包括在模型的保存和加载过程中。

总结来说,这段代码的作用是在模型中注册一个名为relative_position_index的缓冲区,该缓冲区包含了模型在处理序列数据时需要用到的相对位置索引信息。这样做可以确保这个索引信息在模型的训练和推理过程中保持一致,并且在模型保存和加载时被正确处理。

relative_position_bias_table

1
2
self.relative_position_bias_table = nn.Parameter(torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads))  # [2*Mh-1 * 2*Mw-1, nH]
nn.init.trunc_normal_(self.relative_position_bias_table, std=.02) # 相对位置偏移表格 初始化

relative_position_bias

1
relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view(self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1)

Python Package镜像网站(备用)

PyTorch

CUDA


小知识
https://blog.cosmicdusty.cc/post/Knowledge/ResearchTips/
作者
Murphy
发布于
2025年6月1日
许可协议