cake fork什么意思_Fork 是什么意思?

前一段时间,我的几位朋友做了国内唯一一个以区块链为主题的 Podcast , http://forkit.fm/ 。主播都是都是开源世界的老手,所以大家对 fork 这个词是非常有感情,但是不同的语境下,其实 fork 的含义是有差异的,下面咱们仔细聊聊。

传统开源语境下

Peter 十多年前就开始做开源了,那个时候如果有人说,You are forked ,其实是一个不好消息。fork 就是 Knife and Fork 中的 fork ,就是吃饭用的叉子。但是开源代码跟叉子是怎么挂上勾的呢?

我们要从开源代码的开发过程说起。说起一个项目,最初其实就是一个文件夹,里面存放着一些代码。每次对项目的修改内容,开源世界的行话叫做一个 patch ,翻译成中文就是补丁,注意,开源世界的补丁是源码形式的,跟升级 windows 系统时说的补丁不一样。这样,项目不断添加补丁,就会形成多个版本。有了类似 CVS 和 SVN 这样的版本控制工具之后,每一个版本都会被永久保留,同时新老版本互相连接,就形成一条线。后来大家都用 Git 做版本控制了,一个版本叫做一个 commit 。

那项目什么时候会被 fork 呢?项目不断开发,总有人会对项目的方向有不同意见,所以这些人会把项目代码自己拷贝一份。然后按照不同的思路继续开发。这样形成的结果是,两拨人的项目的最初的一些版本是相同的,也就是开发都在一条线上,但是后来大家分道扬镳了,项目变成了两条线来进行。这样整体上看起来就像叉子一样,顶部分叉了。这就是 fork 这个词在开源世界的最初含义了,国内对 fork 的翻译是”分叉“,翻译的非常好。

所以说,开源世界的分叉,最本质的意思就是,有些人跟我有不同意见,自己另起炉灶了。所以,一旦被 fork ,就意味着团结破裂,竞争出现,所以是不太好的感觉。

Github 语境下

2008年 Github 诞生了,Fork 的含义开始变得越来越正面。Github 甚至还出过一个文化衫,上面赫然印着 Fork me 。这种含义的转变,跟 Git 的工作模式有关系。

Linux 之父 Linus 在2005年创造了 Git 版本控制工具。Git 是去中心化的版本控制,原则上是没有中央服务器的,每个人都是各自开发,即使机器不联网也一样可以制作新版本,所以如果使用 Git 来开发项目,任意一个时间点,出现无数的分支时很正常的事情了,也就是说即使大家共识没有破裂,项目也一直处于一种临时的 fork 状态。区别于传统的 CVS/SVN 这些版本控制工具,Git 最大的强项就是合并分支,术语就叫 Merge 。

http://Github.com 上一个项目被 fork 的次数越多,就意味着这个项目越活跃。Github 流行起来之后,fork 的含义非常积极了。打开一个开源项目,例如 https://github.com/nervosnetwork/ckb ,页面的右上角就可以看到一个 fork 按钮。如果我想要为这个项目贡献代码,就点一下 Fork 。这样,Github 就会把 ckb 项目拷贝到我的名下。这样,我就可以在这个拷贝上不断做 commit 。当我想要提交这些代码给 ckb 官方的时候,就会发一个 Pull Request ,也就是“拉取请求”,ckb 官方收到请求通知后,可以审核一下我的代码,没有问题就可以把代码 merge 到官方仓库中了。

所以说,Github 语境下,fork 是整个开源贡献过程的第一步,没有任何共识破裂的意思,所以意义是完全积极的。

区块链语境下

区块链出现以后,fork 这个词又反复出现在区块链语境下。http://forkit.fm/ 上第一期就是 《 Let’s talk about FORK 》,两位主播作为区块链的资深从业者,聊了他们对 fork 的看法,可以作为参考。我认为区块链这里 fork 要分两个层面来讨论。

首先第一个层面,区块链项目本身都是开源项目,一个区块链项目被 fork 了,首先就是一个传统的开源 fork 的事件发生了。类似比特币这样的区块链项目,都是基于去中心化网络的。整个网络上没有中央服务器,每个节点都是一个安装了相同的客户端的一台机器。每个机器都地位对等,互为服务器。对于比特币,所有的运行规则都要靠比特币客户端来执行。比特币客户端的代码在 https://github.com/bitcoin/bitcoin 。2017年比特币就被 fork 过一次,有一批人另起炉灶,搞了 BCH ,代码就是把比特币的代码拷贝一份,然后继续开发,当然这些新开发的内容是根本没有打算 merge 回官方的仓库的。

再说第二个层面,区块链本身也会分叉。前面我们说的分叉,一直是说源码的各个版本形成的一条历史线出现了新的分支。但是有意思的是,区块链本身也是一个由多个区块组成的一条历史线,所以区块链语境下,人们说分叉,一般指的是区块链的分叉,而非客户端源码的分叉。这里的知识非区块链业内人士不会太关心,所以这里我简要说明一下。区块链分叉有软分叉和硬分叉之分。软分叉指的是最终能回归到一条线上的分叉,是临时性的分叉。而硬分叉是永久性的分叉,原因就是因为客户端代码有了大的改动造成了向前不兼容。例如,比特币官方客户端和 BCH 项目的客户端不兼容,就出现了硬分叉,这是两拨人共识破裂造成的。但是,也有的时候,官方发布了向后不兼容的更新,也会通过硬分叉的形式对区块链进行升级。

总之,区块链语境下,人们说的分叉通常指的是区块链自身的分叉,而非客户端源码的分叉。

总结

这节关于分叉,咱们就聊到这里。总结一下,传统上分叉,只的是源码分叉,指的是开源项目的开发历史线出现了新的分支。而区块链分叉,是区块连接成的历史线出现了新的分支。不管是源码分叉还是区块链的分叉,本身善恶没有定论,一方面意味着社区力量不团结了,但是另一方面,少数派有权利自己去探索一条新道路,也是一种开源自由精神的体现。

Mask R-CNN 是一种基于 Faster R-CNN 的目标检测算法,不仅可以检测出物体的位置,还可以精确地分割出物体的 mask。下面是一个 Mask R-CNN 的例程: ```python import os import sys import random import math import numpy as np import skimage.io import matplotlib import matplotlib.pyplot as plt # Root directory of the project ROOT_DIR = os.path.abspath("../") # Import Mask RCNN sys.path.append(ROOT_DIR) # To find local version of the library from mrcnn import utils import mrcnn.model as modellib from mrcnn import visualize from mrcnn.config import Config # Directory to save logs and trained model MODEL_DIR = os.path.join(ROOT_DIR, "logs") # Local path to trained weights file COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5") # Download COCO trained weights from Releases if needed if not os.path.exists(COCO_MODEL_PATH): utils.download_trained_weights(COCO_MODEL_PATH) # Directory of images to run detection on IMAGE_DIR = os.path.join(ROOT_DIR, "images") class InferenceConfig(Config): # Set batch size to 1 since we'll be running inference on # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU GPU_COUNT = 1 IMAGES_PER_GPU = 1 NUM_CLASSES = 1 + 80 # COCO has 80 classes config = InferenceConfig() config.display() # Create model object in inference mode. model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config) # Load weights trained on MS-COCO model.load_weights(COCO_MODEL_PATH, by_name=True) # COCO Class names # Index of the class in the list is its ID. For example, to get ID of # the teddy bear class, use: class_names.index('teddy bear') class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'] # Load a random image from the images folder file_names = next(os.walk(IMAGE_DIR))[2] image = skimage.io.imread(os.path.join(IMAGE_DIR, random.choice(file_names))) # Run detection results = model.detect([image], verbose=1) # Visualize results r = results[0] visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], class_names, r['scores']) ``` 在上面的例程中,我们首先导入所需的库和模块,包括 Mask R-CNN 的配置、模型、可视化等。然后,我们设置了模型的超参数和文件路径,以及加载了预训练的 COCO 权重。接下来,我们定义了一个 InferenceConfig 类,它继承自 Config 类,并设置了模型的 GPU 数量、每个 GPU 的图片数量和类别数。然后,我们在 inference 模式下创建了模型对象,并加载了预训练的 COCO 权重。最后,我们从图片文件夹中随机加载一张图片,并对其进行目标检测和分割,最后可视化检测结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值