计算机视觉入门必备工具


随着 GPU 和大量优质数据的出现,深度学习技术在计算机视觉任务中扮演着越来越重要的角色。深度学习技术的端到端的模式大大简化了特征工程的工作量,为提取更加有效的特征提供了一个泛化性更强的工具。故而,学习深度学习技术是计算机视觉任务的不二之选。

一般地,学习深度学习技术需要具备以下能力:

  • 编程语言:当前,大多数深度学习框架均以 Python 为主流编程语言。您可以阅读 Python 官方教程:中文 Python
  • 版本控制:一个深度学习项目不是一天建成,需要不断的调试和修复,因而学习版本控制是十分重要的任务。本文仅仅介绍 Git。
  • 解读和使用优质的 GitHub 资源:如果所有的项目都从零开始构建是完全没有必要的,将项目建立在优秀的 GitHub 项目的基础上,继续开发,将会为您节省大量的时间和经历。本文将详细介绍如何使用 GitHub 资源。

1 Git 基础

git 速查表

Git 学习资源:

所谓的版本控制,就是用来记录文件内容的变动,方便未来查询和恢复文件的内容修订的一种系统。版本控制的工具有很多,但是,我比较倾向于 Git。因为 Git 是分布式的,即使服务器上的版本库坏掉了,您也可以从其他非服务器的电脑上进行版本更新。

并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。—— 《Git Pro》

您完全不用担心把文件玩坏,因为版本控制已经帮你准备好了时光机器,借由版本控制您可以追溯文件的前世、今生以及未来,文件的时间轴完全由您掌控,甚至于,您可以借助 Git 的分支跳跃不同的“平行宇宙”。

Git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。Git 有三种状态:已提交(committed)、已修改(modified)和已暂存(staged)。

  • 已提交表示数据已经安全的保存在本地Git 仓库目录(即 .git 目录,是 Git 用来保存项目的元数据和对象数据库的地方。 供其它计算机克拷贝的数据。)中。
  • 已修改表示修改了文件,但还没保存到Git 仓库目录中。
  • 已暂存表示在工作目录(即您磁盘上存储的你看到的数据)对一个已修改文件的当前版本做了标记(即记录在 .git/index 中,一般地,将其称为暂存区域),使之包含在下次提交的快照中。

1.1 配置用户信息

一般情况下,安装好 Git 之后需要您配置用户信息,用于记录提交者的信息。

$ git config --global user.name 用户名
$ git config --global user.email 邮箱

配置好了用户信息,之后您便可以使用 Git 了。如果您不知道某一个命令如何使用,您可以使用 git help 来获取帮助,比如:

$ git help config

您便轻松的获取 git config 的离线帮助文档。

1.2 创建并操作一个本地仓库

创建一个本地仓库,只需要您在工作目录下使用命令 git init 即可。此命令会在工作目录的根目录下创建 .git 目录,即本地的 Git 仓库。但是,此时,您的 Git 本地仓库是空的,我们需要将工作目录中的文件加入 Git 的跟踪:

git init

命令 git add . 将工作目录的所有文件由未跟踪状态转换为跟踪状态,并存储在暂存区(注意,这里说“存储”并不准确,应该说是将文件的内容的指针放入 .git/index 中进行存储),以备下次提交。如果您仅仅只需要跟踪 A.md,那么您可以这样:

$ git add A.md

vscode(一个十分强大的编辑器) 可以显示追踪的状态:

git add

为了查看文件存储的状态,您可以使用 git staus -s

git status

git status 仅仅可以看出文件级别的(与暂存区的)不同状态,而如果您想要获悉文件的内容之间的不同,可以使用 git diff 获取工作目录中当前文件和暂存区域快照之间的差异:

git diff

git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动,若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --staged 命令;命令 git diff --check 可以用来检测可能存在由空白符引起的问题;Git 的 ... 语法:git diff A...B 用于查找分支 A 同 A 与 B 的共同跟节点的不同,可看图理解:

git diff A...B

您总会有一些文件不希望被 Git 追踪(比如一些机密文件),此时您可以创建文件 .gitignore 并将那些不希望被追踪的文件名称写入到 .gitignore 中(在 https://github.com/github/gitignore 中提供了一些 .gitignore 模板可供参考)。文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。
  • 以(/)开头防止递归。
  • 以(/)结尾指定目录。
  • 惊叹号(!)取反要忽略指定模式以外的文件或目录。

当您通过 git status 查看文件的状态为均已经暂存时,您便可以使用 git commit -m "提交的信息" 命令将所有通过 git add 暂存的文件内容在数据库中创建一个持久的快照,然后将当前分支上的分支指针(即 HEAD)移到其之上。提交时记录的是放在暂存区域的快照,并以 SHA-1 校验码进行标识方便之后的版本转换。更多命令可以由下图解读:

graph LR
A(History) --git reset -- files--> B(Staged)
B --git checkout -- files--> C(Working Directory)
B --git commit -m --> A
C --git add files--> B
C --git commit -a -m --> A
A --git checkout HEAD -- files--> C

如果您已经做了多次提交,那么 Git 会将您的提交的顺序进行记录,通过 git log 命令可以查看您的提交历史。(更多关于 git log 的用法请参阅 https://git-scm.com/book/zh/v2/Git-基础-查看提交历史)。而您的每次提交均被 Git 以 SHA-1 码记录,这样一来,您便可以依据其将工作目录恢复到某个过去的时间节点。假如,您已经回到工作目录过去的某个时间节点,而您又想回到未来(相对于当前时间节点),那么,您可以借助 git reflog 来查找“未来”的时间节点,然后使用 git checkout ID 进行穿梭(ID 指的是 SHA-1 码)。工作目录的时间节点的状态是由 HEAD 进行指示的,故而,您也可以使用 git reset --hard commit_id 不断的切换 HEAD 达到穿梭时间的效果。

有时候您提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行 git commit -a -m 提交命令尝试重新提交(其中 -a 表示 --amend)。

1.3 远程仓库

上一节您已经了解了然后创建一个本地仓库,并对该本地仓库进行管理。本节我们探讨远程仓库(远程仓库是指托管在服务器或其他网络中的你的项目的版本库)。因为该仓库仅仅作为合作媒介,不需要从磁盘检查快照,所以一个远程仓库通常只是一个裸仓库(bare repository,一个没有当前工作目录的仓库,即工程目录内的 .git 目录)。

创建一个裸仓库,只需要:

$ git clone --bare my_project my_project.git

该命令实现了将 my_project/.git 复制到 my_project.git 目录中的作用,而 my_project.git 便是一个裸仓库。为了让裸仓库发挥分布式的作用,需要将其放到服务器上并设置你的协议。其他拥有服务器的访问或读写权限的电脑将可以通过如下方式进行复刻:

$ git clone user@git.example.com:/opt/git/my_project.git

其中, user@git.example.com 代表服务器的地址,而 /opt/git/my_project.git 代表服务器上裸仓库所在路径。本文不展开说明如何构建服务器,如果您想要了解构建服务器的详细信息,可以查看:服务器上的 Git - 在服务器上搭建 Githttps://git-scm.com/book/zh/v2/服务器上的-Git-在服务器上搭建-Git) 或者 GitBlit(http://gitblit.com/)。本文将使用目前最大的 Git 托管平台——GitHub 这一 Git 服务器(详细内容见 https://git-scm.com/book/zh/v2/GitHub-账户的创建和配置)。

假如从 GitHub 上搜寻到一个不错的仓库,您想要将其加入到自己的项目中去,您可以这样做:

fork

点击右边的 fork 按钮,然后,选择您的用户名或者组织,将其复刻下来。这样,您便有了对该仓库的读写以及推送(将本地仓库同步到远端仓库)的权限。使用 git clone 的命令将远端仓库克隆到本地,克隆的网址可以这样获取:

git clone

当您克隆到本地后,可以使用 git remote -v 命令查看远程仓库使用的 Git 保存的简写与其对应的 URL,比如:

origin  https://github.com/xinetzone/xinet-matery.git (fetch)
origin  https://github.com/xinetzone/xinet-matery.git (push)

其中 origin 便是别名。如果您想要拥有多个远程仓库,可以运行 git remote add <shortname> <url> 添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写。

为了方便说明我们创建两个本地仓库 server/D.gitserver/R.git,然后在目录 T 中添加这两个仓库:

git remote add

从上图可以看出,目录 T 下有两个远程仓库,它们的别名分别为:DR。现在您可以在命令行中使用字符串 D 来代替整个 URL。 例如,如果你想拉取 D 所指代的仓库,可以运行 git fetch D,这个命令会访问远程仓库,从中拉取所有你还没有的数据。执行完成后,你将会拥有那个远程仓库中所有分支的引用,接着,您运行 git merge D/master 命令便可以将 D 合并到当前目录。

如果你使用 git clone 命令克隆了一个仓库,该命令会自动将其添加为远程仓库并默认以 “origin” 为简写。

如果您在当前工作目录下做了修改,并且,想要将其分享,只需要执行 git push [remote-name] [branch-name] 命令即可。比如:

$ git push D master

如果您想查看远程仓库的更多详细信息,可以运行 git remote show [remote-name];如果您想要重命名引用的名称可以运行 git remote rename;如果您想要删除远程仓库可以运行 git remote rm 或者 git push origin --delete branch_name

1.4 标签

在切换不同的时间节点时,可以借助 commit 的 ID,但是,此 ID 有点反人类,太长了并且不好记忆。为了人们可以更好的管理历史节点,我们需要给那些重要的历史节点打上标签,这样一来,人们通过这些有实际语义的标签进行管理将更加方便。

Git 主要使用两种类型的标签:轻量标签(lightweight)与附注标签(annotated)。

1.4.1 附注标签

附注标签的创建可以这样:

$ git tag -a v1.4 -m "我的版本 1.4"

您可以使用 git tag 或者 git tag -l 'v1.4.1*' 列出当前的标签。或者使用 git show v1.4 命令查看标签信息与其对应的提交信息。

1.4.2 轻量标签

轻量标签不需要提供 commit 信息,只需要:

$ git tag v1.4-1q

您亦可以对历史提交的某个 commit ID 进行打标,比如:

$ git tag -a v1.1 ead28ed

1.4.3 管理标签

您可以使用命令 git push origin [tagname] 将标签推送到远端;如果想要一次推送多个标签,可以是使用 git push origin --tags

当然,您也可以使用命令 git tag -d <tagname> 删除标签。如果也要将远端的标签删除,可以使用命令 git push <remote> :refs/tags/<tagname>,比如:

$ git push origin :refs/tags/v1.4-1q

1.5 分支

分支 可以想象为不同维度的平行宇宙,在同一个时间节点可以并行的存在不同的支线来发展项目的不同功能。专业点的说法:Git 的分支仅仅是指向提交对象的可变指针,(Git 的默认分支名称为 master)每次进行 git commit 操作,都将会移动该指针。分支就好比河流拥有的支流,只不过在这些支流上面存在着无法移动的“指针”(git tag)与可以移动的“指针”(git branch)。

分支的创建需要使用 git branch,比如:

$ git branch develop

可以移动?那么我们该如何判断工作目录所处的状态呢?(简单点说,我们该如何判断我们 “now” 的位置。)这个很简单,Git 中还有一个特殊的指针 HEAD,它总是指向当前所在的分支所在的时间节点。您可以使用 git log --oneline --decorate 命令查看各个分支的指针。

您若要在不同的分支之间进行跳转,可以使用 git checkout [分支名] 进行切换。有没有命令将创建分支与切换分支进行合并的呢?当然有了,它就是:git branch -b <分支名>

关于分支的命令还有:

  • 合并:git merge branch_name
  • 删除:git branch -d branch_name

1.6 vscode 与 Git 集成

为了让 Git 更好的与 vscode 集成,提供更丰富的 commit 信息,您可以这样:

$ git config --global core.editor "code --wait"

将 vscode 作为 Git 的内核编辑器。

2 使用 Git 管理项目

前面介绍了 Git 的基础知识,本文剩余部分将介绍如何利用 Git 更好的管理您的项目。

2.1 对 Microsoft Office 进行版本控制

最新版的 Git,已经支持对 .docx 的控制。下面我们简单做个小测验:

  1. 创建文件 A.docx,并写入内容:这是一个测试!,之后纳入 Git 管理:

一个测试

接着我们修改 A.docx 中的内容为 这是一个被修改的测试哦!

一个被修改的 word

从上图可以看出修改的内容与之前的(对 .docx 进行)比较。如果您还不满足,想要使用 Git 比较 .xlsx 文件的话,您可以参考:http://programmaticallyspeaking.com/git-diffing-excel-files.html

对于使用命令行,大多数人都是有点抵触的,好在有需求就有市场,在 Windows 系统下使用 Git,我们可以借助一个十分强大的 GUI 软件:TortoiseGit。

首先,我们需要下载并安装 TortoiseGit。下载网址:https://tortoisegit.org/download/,我们选择 64 位进行下载,并且需要下载中文语言包:

TortoiseGit 下载

下载好之后,按照提示默认安装即可,但是,安装中文包的最后一步需要按下图选择打勾:

安装 TortoiseGit 中文包

关于 TortoiseGit 的使用细节可参考其手册:https://tortoisegit.org/docs/。其实,TortoiseGit 被集成在了右键快捷键中:

TortoiseGit 集成于右键

从上图可以清晰的看到 Git 的大部分功能都被集成到了右键快捷键中。使用 TortoiseGit 比较差异将比较简单:

TortoiseGit 比较 docx

接着,将打开 Word,界面如下:

TortoiseGit 比较 docx 界面

这样的界面将会更加直观!

TortoiseGit 的强大不仅仅如此,它还可以直接比较 .xlsx.pptx 等。换句话说,TortoiseGit 与 Microsoft office 完美的结合在了一起,为您的 office 管理提供了一个十分高大上的 Git 支持。

2.2 TortoiseGit 的使用

下面我们演示如何使用 TortoiseGit 操作项目?首先,从服务端(如局域网架设的 Git 服务器,GitHub 等)获取远程项目的地址:ssh://lxw@192.168.42.30:29418/test.git(此地址是我通过 GitBlit 架设的服务器创建的一个空的裸库)。其中, lxw 表示远程裸库的用户名:

TortoiseGit clone

需要输入 lxw 对应的密码:

TortoiseGit clone 密码

因为是刚刚克隆(git clone)的仓库,其中的暂存区与工作目录均是干净的,所以,目录图标上会有蓝色的对勾:

test

下面使用 vscode 打开工作目录 test 并创建一个 git bash 终端。该项目已经存在自述文档(README.md)与 .gitignore(令 Git 忽视的文件列表)。为了更好的展示 TortoiseGit 与的集成效果,下面我们将演示如何利用 TortoiseGit 管理 .docx 文档。

我们先创建 A.docx 并写入内容:我是 A。由于 A.docx 没有加入到 Git 管理,所以其图标为空:

A

接着,将 A.docx 纳入 Git 管理:

右键添加

接着弹出一个窗口,列出所有未被加入到 Git 管理的文件(即 git add 操作):

列出未被 Git 追踪的文档
追踪文档

自此,完成了将 A.docx 纳入 Git 的 index (即暂存区)的操作,刷新目录,可以看到 A.docx 多了一个蓝色的 $+$ 图标:

完成 git add

至此,如果您没有其他需要加入到暂存区的文档,您可以将这些暂存区的信息提交(git commit)到本地仓库,并写上简要的说明:

提交到本地 master

写上简要的说明

如果您还想要与其他人共享编写 A.docx,您需要将其推送(git push)到远端服务器:

git push

其他人只需要在他们克隆的副本进行拉取(git pull)便可获得您的更新:

git pull

如果某人 K 拉取之后对 A.docx 进行了修改,添加内容:

做了 test1。

而您自己也做了修改,添加内容:

学习了 M。

之后,您先将变动推送到了远端。紧接着 K 也将其做的改动推送到远端,由于您们所做的改动有冲突,所以推送失败:

存在冲突

解决冲突的办法有两种:

  1. 创建新的分支(git branch)与发生冲突的分支分开,解决冲突交给管理员(负责管理整个项目的人);
  2. 先将远端的更新获取(git fetch)下来(见下图),之后再解决冲突。

git fetch

更多的关于 TortoiseGit 的使用可以参考其官方文档 https://tortoisegit.org/docs/,本文便不再引申。

更多精彩内容可(⓿_⓿)第 1 章 可爱的 git 勾搭上高富帅 vscode


文章作者: xinetzone
版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 xinetzone !
评论
  目录