Monthly Archives: 8 月 2018

You are browsing the site archives by month.

1. 欧氏距离(Euclidean Distance)

欧氏距离是最易于理解的一种距离计算方法,源自欧氏空间中两点间的距离公式。

  • 二维平面上两点a(x1,y1)b(x2,y2)间的欧氏距离:

  • 三维空间两点a(x1,y1,z1)b(x2,y2,z2)间的欧氏距离:

  • 两个n维向量a(x11,x12,…,x1n) b(x21,x22,…,x2n)间的欧氏距离:

  • 也可以用表示成向量运算的形式:

2. 曼哈顿距离(Manhattan Distance)

从名字就可以猜出这种距离的计算方法了。想象你在曼哈顿要从一个十字路口开车到另外一个十字路口,驾驶距离是两点间的直线距离吗?显然不是,除非你能穿越大楼。实际驾驶距离就是这个曼哈顿距离。而这也是曼哈顿距离名称的来源, 曼哈顿距离也称为城市街区距离(City Block distance)

  • 二维平面两点a(x1,y1)b(x2,y2)间的曼哈顿距离

  • 两个n维向量a(x11,x12,…,x1n) b(x21,x22,…,x2n)间的曼哈顿距离

3. 切比雪夫距离 ( Chebyshev Distance )

国际象棋玩过么?国王走一步能够移动到相邻的8个方格中的任意一个。那么国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?这个距离就叫切比雪夫距离。

  • 二维平面两点a(x1,y1)b(x2,y2)间的切比雪夫距离

  • 两个n维向量a(x11,x12,…,x1n) b(x21,x22,…,x2n)间的切比雪夫距离

  • 这个公式的另一种等价形式是

4. 闵可夫斯基距离(Minkowski Distance)

闵氏距离不是一种距离,而是一组距离的定义,是对多个距离度量公式的概括性的表述。

两个n维变量a(x11,x12,…,x1n) b(x21,x22,…,x2n)间的闵可夫斯基距离定义为:

  其中p是一个变参数。

  当p=1时,就是曼哈顿距离

  当p=2时,就是欧氏距离

  当p时,就是切比雪夫距离

      根据变参数的不同,闵氏距离可以表示一类的距离。

5. 标准化欧氏距离 (Standardized Euclidean Distance)

标准化欧氏距离是针对简单欧氏距离的缺点而作的一种改进方案。标准欧氏距离的思路:既然数据各维分量的分布不一样,那先将各个分量都标准化到均值、方差相等。假设样本集X的均值(mean)m,标准差(standard deviation)s,那么X标准化变量表示为:

  • 标准化后的值 =  ( 标准化前的值  分量的均值 ) /分量的标准差
  • 经过简单的推导就可以得到两个n维向量a(x11,x12,…,x1n) b(x21,x22,…,x2n)间的标准化欧氏距离的公式:

  • 如果将方差的倒数看成是一个权重,这个公式可以看成是一种加权欧氏距离(Weighted Euclidean distance)

6. 马氏距离(Mahalanobis Distance)

马氏距离的引出:

上图有两个正态分布的总体,它们的均值分别为ab,但方差不一样,则图中的A点离哪个总体更近?或者说A有更大的概率属于谁?显然,A离左边的更近,A属于左边总体的概率更大,尽管Aa的欧式距离远一些。这就是马氏距离的直观解释。

  • 概念

马氏距离是基于样本分布的一种距离。物理意义就是在规范化的主成分空间中的欧氏距离。所谓规范化的主成分空间就是利用主成分分析对一些数据进行主成分分解。再对所有主成分分解轴做归一化,形成新的坐标轴。由这些坐标轴张成的空间就是规范化的主成分空间。

  • M个样本向量X1~Xm,协方差矩阵记为S,均值记为向量μ,则其中样本向量Xu的马氏距离表示为:

  • 而其中向量XiXj之间的马氏距离定义为:

  • 若协方差矩阵是单位矩阵(各个样本向量之间独立同分布),则公式就成了:

也就是欧氏距离了。若协方差矩阵是对角矩阵,公式变成了标准化欧氏距离。

7. 余弦距离(Cosine Distance)

几何中,夹角余弦可用来衡量两个向量方向的差异;

机器学习中,借用这一概念来衡量样本向量之间的差异。

  • 二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式:

  • 两个n维样本点a(x11,x12,…,x1n)b(x21,x22,…,x2n)的夹角余弦为:

即:

夹角余弦取值范围为[-1,1]。余弦越大表示两个向量的夹角越小,余弦越小表示两向量的夹角越大。当两个向量的方向重合时余弦取最大值1,当两个向量的方向完全相反余弦取最小值-1

8. 汉明距离(Hamming Distance)

  • 定义

两个等长字符串s1s2的汉明距离为:将其中一个变为另外一个所需要作的最小字符替换次数。

例如

      The Hamming distance between “1011101” and “1001001” is 2.               

      The Hamming distance between “2143896” and “2233796” is 3.               

      The Hamming distance between “toned” and “roses” is 3.                                   

  • 汉明重量

字符串相对于同样长度的零字符串的汉明距离,也就是说,它是字符串中非零的元素个数:对于二进制字符串来说,就是 1 的个数,所以 11101 的汉明重量是 4。因此,如果向量空间中的元素ab之间的汉明距离等于它们汉明重量的差a-b

  • 应用

汉明重量分析在包括信息论、编码理论、密码学等领域都有应用。比如在信息编码过程中,为了增强容错性,应使得编码间的最小汉明距离尽可能大。但是,如果要比较两个不同长度的字符串,不仅要进行替换,而且要进行插入与删除的运算,在这种场合下,通常使用更加复杂的编辑距离等算法。

9. 杰卡德距离(Jaccard Distance)

  • 杰卡德相似系数(Jaccard similarity coefficient)

两个集合AB的交集元素在AB的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示:

杰卡德相似系数是衡量两个集合的相似度一种指标。

  • 杰卡德距离(Jaccard Distance)

与杰卡德相似系数相反,用两个集合中不同元素占所有元素的比例来衡量两个集合的区分度:

10. 相关距离(Correlation distance)

  • 相关系数

衡量随机变量XY相关程度的一种方法,相关系数的取值范围是[-1,1]。相关系数的绝对值越大,则表明XY相关度越高。当XY线性相关时,相关系数取值为1(正线性相关)或-1(负线性相关):

  • 相关距离

11. 信息熵(Information Entropy)

以上的距离度量方法度量的皆为两个样本(向量)之间的距离,而信息熵描述的是整个系统内部样本之间的一个距离,或者称之为系统内样本分布的集中程度(一致程度)、分散程度、混乱程度(不一致程度)。系统内样本分布越分散(或者说分布越平均),信息熵就越大。分布越有序(或者说分布越集中),信息熵就越小。

  • 计算给定的样本集X的信息熵的公式:

  • 参数的含义:

n:样本集X的分类数

piX中第 i 类元素出现的概率

信息熵越大表明样本集S的分布越分散(分布均衡),信息熵越小则表明样本集X的分布越集中(分布不均衡)。当Sn个分类出现的概率一样大时(都是1/n),信息熵取最大值log2(n)。当X只有一个分类时,信息熵取最小值0

问耕 编译自 Source Dexter

作者简介:akshay pai,数据科学工程师,热爱研究机器学习问题。Source Dexter网站创办人。

TensorFlow是Google的开源深度学习库,你可以使用这个框架以及Python编程语言,构建大量基于机器学习的应用程序。而且还有很多人把TensorFlow构建的应用程序或者其他框架,开源发布到GitHub上。

这次跟大家分享一些GitHub上令人惊奇的TensorFlow项目,你可以直接在你的应用中使用,或者根据自身所需进一步予以改进。

TensorFlow简介

如果你已经知道TensorFlow是什么,以及它是如何工作的,建议直接跳到下一节。如果你对使用Python学习TensorFlow感兴趣,网上也有相关的教程可以参考。

这一节内容比较傲适合初学者。如前所述,TensorFlow是一个深度学习库,使用这一框架,可以用来构建和测试深度神经网络。

深度学习让我们能够以极高的准确性构建复杂的应用程序。图像、视频、文本、音频等领域的问题,都可以通过深度学习解决。TensorFlow可以用于实现前述所有应用。

2015年11月9日,Google正式发布并开源TensorFlow,目前官方正式版本为TensorFlow 1.2。下面这段视频,是当年TensorFlow刚发布时,Google发布的一个官方介绍短片,Jeff Dean等出镜讲述。

TensorFlow很快成为GitHub上用户最多的深度学习框架。这个库之所以如此流行,是因为开发人员可以轻松的用其来搭建、测试和部署机器学习应用。

TensorFlow使用数据流图,上面是一个TensorFlow的示意图。我们不用关心这张图具体代表什么,但你需要知道,其中的椭圆和正方形代表节点,节点就是一些数学函数,你可以将节点分组形成各种数学计算,并得到输出。

箭头代表流动到各个节点的数据。所以TensorFlow也被成为数据流库。

OK,简介到此,下面分享四个我非常喜欢的TensorFlow GitHub项目。

项目一:Neural Style

这是最酷的TensorFlow GitHub项目之一。神经风格是将一张照片的风格迁移到另一张照片上的过程,同时保留相关的特张。简单的来说,通过这个项目,你可以使用TensorFlow创建自己的Prisma应用程序。

如上图所示,把梵高画作的风格,迁移到一张狮子的照片上,就得到一个星空风格的狮子照片,这就是所谓的风格迁移。下面再展示一组这个项目的风格迁移,能把这张狮子的照片,变成哪些非常有趣的效果。

这个项目在风格迁移的同时,还能对图像进行语义分割。进而实现对内容的前景、背景进行不同的风格迁移处理。这个过程如下图所示:

另外这个算法还能适用于视频处理。

上述图片处理使用的软硬件如下:

CPU: Intel Core i7-6800K@3.4GHz×12

GPU: NVIDIA GeForce GTX 1080/PCIe/SSE2

OS: Linux Ubuntu 16.04.1 LTS 64-bit

CUDA: 8.0

python: 2.7.12

tensorflow: 0.10.0rc

opencv: 2.4.9.1

GitHub地址如下:

https://github.com/cysmith/neural-style-tf

项目二:Mozilla Deep Speech

这个GitHub项目使用TensorFlow将语音转换为文本。语音转文本是一个热门的机器学习领域,然而各地的人们有着不同的口音,这也是一个难以解决的问题。不过仍然可以通过深度学习实现非常不错的准确性。

其实这个项目,是一个基于百度DeepSpeech架构的TensorFlow实现。换句话说,这个项目是百度的内核,Google的外貌。

百度的相关论文地址在此:

https://arxiv.org/abs/1412.5567

DeepSpeech是吴恩达带领百度团队研发出的成果,最早发布于2014年底。今年初,百度基于DeepSpeech2,开发出一款名为SwiftScribe的应用(swiftscribe.ai),可以把语音文件更为快速、便捷的转换为文字。目前只限于英文。

回到这个项目。

所需软件环境如下:

Git Large File Storage

TensorFlow 1.0 or 1.1

SciPy

PyXDG

python_speech_features (nb: deprecated)

python sox

pandas

DeepSpeech native client libraries

如果你有至少8GB显存的英伟达GPU,强烈建议安装支持GPU的TensorFlow,因为使用GPU的训练比CPU快得多。

GitHub地址如下:

https://github.com/mozilla/DeepSpeech

项目三:句子分类

句子分类就是识别句子类型的过程。例如,对于“食物非常糟糕”这个句子,你可能希望将其分类为正面句子或负面句子,这也被称为情绪分析。这个问题的难点在于:句子结构带来的复杂性。

利用卷积神经网络,我们可以尝试构建一个强大的文本分类器。

这里介绍的项目,是Yoon Kim论文《Convolutional Neural Networks for Sentence Classification(使用卷积神经网络进行句子分类)》的简单实现。这个论文的地址如下:

https://arxiv.org/abs/1408.5882

通过一个简单的CNN卷积神经网络,只进行很少的超参数调整和静态矢量,就可以得到出色的句子分类结果。

所需软件环境如下:

Python 3

Tensorflow > 0.12

Numpy

GitHub地址如下:

https://github.com/dennybritz/cnn-text-classification-tf

项目四:图像分类/物体识别

图像分类,也就是训练系统识别猫猫狗狗,或者车道、海滩、天际线等场景。计算机视觉是一个范围巨大的领域,从面部识别到情感识别,甚至可以进行视觉气体泄漏检测。虽然实现流程各异,但底层系统是相通的。

所以作者创建了一个TensorFlow GitHub库,其中包括两个相互关联的部分。第一部分:能够识别1000个对象的TensorFlow图像分类器。第二部分:创建并训练一个全新的图像分类器。

我们先来看看第一部分。

Google的TensorFlow图像识别系统是目前最准确的图像分类软件。所谓图像识别,就是对图片中的内容进行识别,然而这并非对任意图片都能识别。

只有被训练过的对象,系统才能识别。例如,我们用三个类型训练分类器:猫、狗和牛。三个分类器只能识别相应类别中的一个。如果给出一张骆驼的图片会怎样?图片仍会通过一个分类器,但是置信率会非常的低。

如何快速创建一个TensorFlow图像分类器?只需要简单的三步。当然前提是你已经装好了TensorFlow,而且懂编程、会用Python。

第一步:下载

下载预训练的模型、图片和脚本。使用如下命令即可。

git clone https://github.com/akshaypai/tfClassifiercd tfClassifier

第二步:运行脚本找到最佳预测

给定一个图片,运行脚本来进行分类。默认情况下,会显示最佳预测。

Python classifier.py –image_file file_path_to_image

为了获得top n分类,可以使用如下参数。

Python classifier.py –image_file file_path_to_image –num_top_predictions number_of_top_results

示例:比方我们给出这样一张图片。

python classifier.py –image_file ~/Pictures/fruit.jpgpomegranate (score = 0.98216)

分类器表示:这是石榴,准确率98%。

第三步:运行脚本获得top n识别分类

现在我们尝试给出一个具有更多属性的图像,如下图的房子。

python classifier.py –image_file ~/Pictures/house.jpg –num_top_predictions 5picket fence, paling (score = 0.95750)worm fence, snake fence, snake-rail fence, Virginia fence (score = 0.03615)beacon, lighthouse, beacon light, pharos (score = 0.00018)boathouse (score = 0.00013)patio, terrace (score = 0.00007)

从上面的结果可以看出,分类器以95%的可能性预测图片中有一个栅栏,另外分类器还发现了其他围栏、庭院、露台等。

到此为止,你已经学到如何设置TensorFlow图像识别系统。虽然,这个系统被限制在预训练模型的几个分类器之间。

那么我们接下来看看第二部分,如何增加一些新的分类器。

也是三个步骤。

第一步:下载预训练模型以及所需脚本

我已经把全部所需的文件整合进一个git仓库里。使用下面的命令可以下载。

git clone https://github.com/akshaypai/tfClassifiercd tfClassifier

第二步:设置图像文件夹

这个步骤用于设置文件夹结构,以便数据流图可以简单地拾取分类。假设,你想重新训练五种新的花朵分类器:玫瑰、郁金香、蒲公英、五月花和万寿菊,那么需要如下的三个步骤来创建相应的文件夹结构:

1、为每种花型创建一个文件夹,文件夹的名称就是类型的名称

2、将花的所有图像添加到各自的文件夹中,所有的玫瑰放入玫瑰花文件夹

3、将所有的文件夹,添加到一个父文件夹中,可以命名为:花

然后我们就得到如下的结构:

~/flowers~/flowers/roses/img1.jpg~/flowers/roses/img2.jpg…~/flowers/tulips/tulips_img1.jpg~/flowers/tulips/tulips_img2.jpg~/flowers/tulips/tulips_img3.jpg…

这样,文件夹结构已经OK了。

第三步:运行预训练脚本

使用如下命令运行脚本。

python retrain.py –model_dir ./inception –image_dir ~/flowers –output_graph ./output –how_many_training_steps 500

部分命令行参数:

-model_dir这个参数给出了预训练模型的位置。

-image_dir在步骤二中创建的文件夹路径

-output_graph存储新训练图的位置

-how_many_training_steps这代表要执行的迭代次数,默认为4000

好了,以上就是如何重新训练一个TensorFlow Inception模型。一旦你有了模型,就能开始用来进行分类处理。

结论

我希望你们也能体会到上述这些项目的精彩之处。学习一件事最好的方法就是动手去做。如果你还有更值得推荐的TensorFlow GitHub项目,可以留言给我们,让更多的人看到。今天就先到这里吧。休息,休息一下~

 

link: http://www.techweb.com.cn/news/2017-07-31/2566452.shtml

Problem

You want to use different shapes and line types in your graph.

Solution

Note that with bitmap output, the filled symbols 15-18 may render without proper anti-aliasing; they can appear jagged, pixelated, and not properly centered, though this varies among platforms. Symbols 19 and 21-25 have an outline around the filled area, and will render with smoothed edges on most platforms. For symbols 21-25 to appear solid, you will also need to specify a fill (bg) color that is the same as the outline color (col); otherwise they will be hollow.

Standard graphics

Use the pch option to set the shape, and use lty and lwd to set the line type and width. The line type can be specified by name or by number.

set.seed(331)

# Plot some points with lines
# Set up the plotting area
par(mar=c(3,3,2,2))
plot(NA, xlim=c(1,4), ylim=c(0,1))

# Plot solid circles with solid lines
points(1:4, runif(4), type="b", pch=19)
# Add open squares with dashed line, with heavier line width
points(1:4, runif(4), type="b", pch=0,  lty=2, lwd=3)

points(1:4, runif(4), type="b", pch=23,   # Diamond shape
       lty="dotted", cex=2,               # Dotted line, double-size shapes
       col="#000099", bg="#FF6666")       # blue line, red fill

ggplot2

With ggplot2, shapes and line types can be assigned overall (e.g., if you want all points to be squares, or all lines to be dashed), or they can be conditioned on a variable.

# Sample data
df <- read.table(header=T, text='
  cond xval yval
     A    1  2.0
     A    2  2.5
     B    1  3.0
     B    2  2.0
')


library(ggplot2)

# Plot with standard lines and points
# group = cond tells it which points to connect with lines
ggplot(df, aes(x=xval, y=yval, group = cond)) +
    geom_line() +
    geom_point()

# Set overall shapes and line type
ggplot(df, aes(x=xval, y=yval, group = cond)) +
    geom_line(linetype="dashed",  # Dashed line
              size = 1.5) +       # Thicker line
    geom_point(shape = 0,         # Hollow squares
               size = 4)          # Large points

# Condition shapes and line type on variable cond
ggplot(df, aes(x=xval, y=yval, group = cond)) +
    geom_line(aes(linetype=cond), # Line type depends on cond
              size = 1.5) +       # Thicker line
    geom_point(aes(shape=cond),   # Shape depends on cond
               size = 4)          # Large points


# Same as previous, but also change the specific linetypes and
# shapes that are used
ggplot(df, aes(x=xval, y=yval, group = cond)) +
    geom_line(aes(linetype=cond), # Line type depends on cond
              size = 1.5) +       # Thicker line
    geom_point(aes(shape=cond),   # Shape depends on cond
               size = 4) +        # Large points
    scale_shape_manual(values=c(6,5)) +                  # Change shapes
    scale_linetype_manual(values=c("dotdash", "dotted")) # Change linetypes

By default, ggplot2 uses solid shapes. If you want to use hollow shapes, without manually declaring each shape, you can use scale_shape(solid=FALSE). Note, however, that the lines will visible inside the shape. To avoid this, you can use shapes 21-25 and specify a white fill.

# Hollow shapes
ggplot(df, aes(x=xval, y=yval, group = cond)) +
    geom_line(aes(linetype=cond), # Line type depends on cond
              size = 1.5) +       # Thicker line
    geom_point(aes(shape=cond),   # Shape depends on cond
               size = 4)  +       # Large points
    scale_shape(solid=FALSE)

# Shapes with white fill
ggplot(df, aes(x=xval, y=yval, group = cond)) +
    geom_line(aes(linetype=cond), # Line type depends on cond
              size = 1.5) +       # Thicker line
    geom_point(aes(shape=cond),   # Shape depends on cond
               fill = "white",    # White fill
               size = 4)  +       # Large points
    scale_shape_manual(values=c(21,24))  # Shapes: Filled circle, triangle

 

Note

This code will generate the chart of line types seen at the top.

par(mar=c(0,0,0,0))

# Set up the plotting area
plot(NA, xlim=c(0,1), ylim=c(6.5, -0.5),
    xaxt="n", yaxt="n",
    xlab=NA, ylab=NA )

# Draw the lines
for (i in 0:6) {
    points(c(0.25,1), c(i,i), lty=i, lwd=2, type="l")
}
# Add labels
text(0, 0, "0. 'blank'"   ,  adj=c(0,.5))
text(0, 1, "1. 'solid'"   ,  adj=c(0,.5))
text(0, 2, "2. 'dashed'"  ,  adj=c(0,.5))
text(0, 3, "3. 'dotted'"  ,  adj=c(0,.5))
text(0, 4, "4. 'dotdash'" ,  adj=c(0,.5))
text(0, 5, "5. 'longdash'",  adj=c(0,.5))
text(0, 6, "6. 'twodash'" ,  adj=c(0,.5))

Bioconductor version: Release (3.7)

Multivariate data analysis and graphical display of microarray data. Functions include between group analysis and coinertia analysis. It contains functions that require ADE4.

Author: Aedin Culhane

Maintainer: Aedin Culhane <Aedin at jimmy.harvard.edu>

Citation (from within R, enter citation(“made4”)):

AC C, J T, G P, DG H (2005). “MADE4:an R package for multivariate analysis of gene expression data.” Bioinformatics, 21(11), 2789-90.

Installation

To install this package, start R and enter:
## try http:// if https:// URLs are not supported
source("https://bioconductor.org/biocLite.R")
biocLite("made4")

Documentation

To view documentation for the version of this package installed in your system, start R and enter:
browseVignettes("made4")

link: https://www.bioconductor.org/packages/release/bioc/html/made4.html

最近在开发一个新应用,有一天在gitlab上clone代码的时候发现我的应用竟然有170+M,明明是一个全新的应用,代码都没有几行呢,为什么会有这么大呢?

后来经过了解Git的原理,解决了这个问题,把相关内容记录下来。分享一下。

Why

我的一个新应用竟然要170+M,这是打死我我也不会信的,于是就开始分析为什么会这么大。

step 1. 把代码拉到本地

git clone git@github.com:hollischuang/Architecture-Evolution.git

只是用这个地址举例,实际并不是这个项目。

step 2. 查看哪个文件占用的空间比较大

$cd Architecture-Evolution
$du -d 1 -h
 174M   ./.git
 264K   ./test
 96K    .

于是,发现是.git目录自己就占用了174M,了解Git的人都知道,.git目录是git自己生成的,记录了git仓库的相关信息的。看到这里其实并不难知道原因。

Git 维护着一个微型的文件系统,其中的文件也被称作数据对象。所有的数据对象均存储于项目下面的 .git/objects中。

经过我的验证,确实是.git/objects这个文件夹中的文件占了磁盘上174M的空间。

也就是说,只要我有一次将一个大文件误提交了,那么即使我后面把它删除了,但是,实际上在.git中,这个文件还是存在的,虽然我们可能再也不需要他了,但是他还在那里默默的存在着。。。

Git与大部分版本控制系统的差别是很大的,比如Subversion、CVS、Perforce、Mercurial 等等,使用的是“增量文件系统” (Delta Storage systems), 就是说它们存储每次提交(commit)之间的差异。Git正好与之相反,它会把你的每次提交的文件的全部内容(snapshot)都会记录下来。这会是在使用Git时的一个很重要的理念。

也就是说,如果我又一次把一个大文件务提交到git仓库中了,那么,下次提交时,即使你只改动了某个文件的一行内容,Git 也会生成一个全新的对象来存储新的文件内容。


因为以上两个特性,我回想起我的一次手残行为:
刚刚创建一个应用之后,我快速的写完代码,编译,运行,发现没啥问题之后,我准备先把他发布掉,于是我开始创建git仓库,并尝试把代码提交上去,这时我并没有创建.gitignore文件,我直接git add . git commit -m 'init'git push一气呵成的执行了熟悉的操作。

相信聪明的人已经发现了,逗比啊,我在编译代码之后,会有很多jar被我down到target目录下。我直接git add.把target下面的jar包,war包等这些也直接提交了。。。虽然后面我意识到,并且删除了这些文件,然后再次提交,但是由于刚我们说过的原因,这些文件依然占用着我的空间。。。

更多关于git的原理内容参见:Git 内部原理

How

问题已经定位到了,接下来就是要解决问题了。如果对git的原理及命令了解的比较多的话,这个问题还是比较好解决的,由于当时博主并不十分了解git的原理,所以做了一些知识储备之后才开始动手的。(Git 之术与道 — 对象为什么你的 Git 仓库变得如此臃肿

Step 1 查看哪些历史提交过文件占用空间较大

使用以下命令可以查看占用空间最多的五个文件:

git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"

rev-list命令用来列出Git仓库中的提交,我们用它来列出所有提交中涉及的文件名及其ID。 该命令可以指定只显示某个引用(或分支)的上下游的提交。

--objects:列出该提交涉及的所有文件ID。

--all:所有分支的提交,相当于指定了位于/refs下的所有引用。

verify-pack命令用于显示已打包的内容。

step 2. 重写commit,删除大文件

使用以下命令,删除历史提交过的大文件:

git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch big-file.jar' --prune-empty --tag-name-filter cat -- --all

上面脚本中的big-file.jar请换成你第一步查出的大文件名,或者这里直接写一个目录。

filter-branch命令可以用来重写Git仓库中的提交

--index-filter参数用来指定一条Bash命令,然后Git会检出(checkout)所有的提交, 执行该命令,然后重新提交。

–all参数表示我们需要重写所有分支(或引用)。

在重写提交的过程中,会有以下日志输出:

Rewrite 6cdbb293d453ced07e6a07e0aa6e580e6a5538f4 (266/266)
# Ref 'refs/heads/master' was rewritten

如果显示 xxxxx unchanged, 说明repo里没有找到该文件, 请检查路径和文件名是否正确,重复上面的脚本,把所有你想删除的文件都删掉。

step 3. 推送修改后的repo

以强制覆盖的方式推送你的repo, 命令如下:

git push origin master --force

step 4. 清理和回收空间

虽然上面我们已经删除了文件, 但是我们的repo里面仍然保留了这些objects, 等待垃圾回收(GC), 所以我们要用命令彻底清除它, 并收回空间,命令如下:

rm -rf .git/refs/original/

git reflog expire --expire=now --all

git gc --prune=now

至此,我们已经彻底的删除了我们不想要的文件。

 

来源:http://www.hollischuang.com/archives/1708

京ICP备15063075号