[个人笔记] Git常用命令

最常用的命令:

日常提交最新变更:
git add deep_learning.txt
git commit -m "comment message"
git push origin HEAD:master
git pull origin

# 查看远程URL地址:
git remote -v

# 查看远程分支:
git branch -r

合并dev分支到master分支:
1.先把本地当前分支切换成master: 
  git checkout master
2.拉取一遍远端仓库最近的代码: 
  git pull 
3.把本地dev分支合并到master分支:
  git merge dev
4.把本地的master分支提交到远端master分支: 
  git push
5.把本地分支切换回dev: 
  git checkout dev

帮助命令:git help command

Git架构图:

 

 

  1. 获取远程代码:
    git clone -b branch 远程仓库的地址

如果是本地新增git库初始化,可用命令:git init

  1. 本地修改代码:
    git add file_name 将写的文件提交到暂存区
    git commit -m “提交备注” 将暂存区的文件提交到本地仓库,
    (切记这只是本地仓库,还未分享出去*)
    git push 提交到远程仓库,这时你的同事就可以看见了
    git status 查看提交状态
    git log 查看提交日志

修改最近一次提交(commit)的注释:
git commit –amend
详细说明

3. 回退代码版本:
有两种思路:
1. 用reset,强回退,会导致别人commit的中间版本的更新记录丢失
2. 用revert, 使用新加一次 commit 的方式,回退之前特定一次提交版本,别人提交的更新记录不会丢失。
实践中,需要回退时,应尽可能使用 revert来操作,避免因个人的失误导致团队其它人的commit丢失。

revert基本用法: git revert -n commit_id
示例网页

reset的用法:
git reset –hard HEAD^
HEAD is a pointer, point to the current version of file
HEAD^ HEAD^^ … HEAD~100
You can change HEAD to point to diff ID to change history version

将文件从暂存区回退到工作区
git reset HEAD filename
回退整个版本:
一个^表示一个版本,可以多个,另外也可以使用:git reset HEAD~n这种形式
git reset HEAD^

3.1 如果回退错了,希望恢复被回退的版本
先通过:git reflog查看哈希值
再使用:git reset 哈希值返回

3.2 git reset 三种模式区别介绍
–hard: 强制回退,放弃之前commit的所有内容
–soft:回退后,之前commit的内容会被放到缓冲区,即 stage 状态,相当于改动的文件已被 git add
(mixed) 无参数时默认 mixed:回退后,之前commit 的内容都变成 unstage 的状态,可以工作目录中看到未提交的内容
介绍文章

4. 分支相关命令:
git branch 查看你当前所在的分支
git branch name 创建分支
git checkout -b branchName 当前所在分支创建新分支
git checkout branchName 切换分支
git merge branchName 合并branchName分支到当前分支
git git cherry-pick (-n) commitId(SHA) 挑拣(多个)一个提交到当前分支

5.临时保存本地修改过的代码,先不放到提交范围里:
git stash list 查看保存的工作进度
git stash 保存工作进度
git stash pop 来恢复保存的工作状态

6.比较代码差异:
git diff 工作空间和暂存区的区别
git diff HEAD 工作空间和版本库的区别
git diff –cached 暂存区和版本库的区别

7.在远程git服务器上新增一个仓库
echo "# lihongyi" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/username/reposname.git
git push -u origin master

8.合并时报错:Pulling is not possible because you have unmerged files
原因:当前分支有一个文件因为有修改,没有被合并,这时checkout或pull都会失败
处理方案:强制冲掉这个文件的修改,返回上一次提交的节点
命令:git reset –hard FETCH_HEAD

9.删除不需要跟进的文件及文件夹
命令:git clean -fd [files or folder]

10.合并其它分支的某次提交到当前分支
git log
git checkout cur_branch
git cherry-pick (commitid)

11.删除分支
删除本地分支: git branch -d [branch name]
删除远程分支: git push origin –delete [branch name]

12.合并其它分支单个文件
如果使用git merge命令,会将整个A分支都合并到B
如果只想合并某一个文件,应该使用git checkout -p(–patch)
git checkout -p A file.txt
如果merge过程中遇到冲突,在手动解决完冲突后,可通过git add 命令告诉git冲突已解决

注:分支A可以是远程的分支,也可以是本地分支,远程分支应该写origin/A,如果只写A则默认是本地分支。

冲突合并思路:
通过git stash命令,把工作区的修改提交到栈区,目的是保存工作区的修改
通过git pull命令,拉取远程分支上的代码并合并到本地分支,目的是消除冲突
通过git stash pop命令,把保存在栈区的修改部分合并到最新的工作空间中

12-1. 让分支树的展示更简洁
git rebase 可以在合并代码后,让整个分支树呈现完美的线性
与之相比, git merge 合并后可能存在分支树的情况
相关介绍说明

Rebase 黄金法则
最后必须要提到一条 rebase 黄金法则:绝不要在公共的分支上使用它。 git rebase 会重写历史,一定只能在你自己的分支上使用它, 否则你的队友们可能会暴打你一顿。

13.列出远端所有分支
git branch -r

14.以 bare 方式在远端上创建库存(创建仓库/初始化库存)
mkdir /home/name/repos/project_name.git
cd /home/name/repos/project_name.git
git init –bare 创建裸仓库
从裸仓库clone下来的本地仓库可以进行正常的push操作,但从一般仓库clone下来的本地仓库不能push。
裸仓库不包含工作区,所以不存在在裸仓库上直接提交变更的情况。
裸仓库一般是作为远程的中心仓库而存在的。

15. 使用stash临时存储不打算提交的内存至栈中
临时保存当前分支修改,先不提交(要在add 之前操作)
git stash save "msg"
以栈的方式存储,先进后出

16. 找出代码提交者
git blame file -L a,b 打印出file中行数在a,b之间的的内容,并会显示每一行代码的提交者信息

17. 获取远程最新信息 并 合并至本地分支
git fetch 获取远端有而本地没有的数据
git merge alias 将服务器上的任何更新(假设有人这时候推送到服务器了)合并到当前分支

18. 删除 Untracked files
git clean -f 会强制删除未add到git中的文件
-d 连目录一起删除
-x 连 ignored files 文件一起删除
-X 只删除 ignored files

19. 各类型merge合并参数

20. git merge时空格处理参数

临时保存功能

背景:当你不想提交当前完成了一半的代码,但是却不得不修改一个紧急Bug,那么使用’git stash’就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区间和上一次提交的内容是完全一样的,所以你可以放心的修 Bug,等到修完Bug,提交到服务器上后,再使用’git stash apply’将以前一半的工作应用回来。 引用自

stash 基本操作

查看当前临时保存的列表
git stash list

将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。
该命令将堆栈中最近保存的内容删除(栈是先进后出)
git stash pop

将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除
git stash apply

从堆栈中移除某个指定的stash
git stash drop + 名称

清除堆栈中的所有 内容
git stash clear

查看堆栈中最新保存的stash和当前目录的差异。
git stash show

 

参考资料:http://blog.csdn.net/txw910/article/details/53998951

利用hook实现自动部署
解决方案参考

Gitflow实践分支设定
最佳实践

主要工作流程:

1. 初始化项目为gitflow, 默认创建master分支, 然后从master拉取第一个develop分支
2. 从develop拉取feature分支进行编码开发(多个开发人员拉取多个feature同时进行并行开发, 互不影响)

3. feature分支完成后, 合并到develop(不推送, feature功能完成还未提测, 推送后会影响其他功能分支的开发)
    合并feature到develop, 可以选择删除当前feature, 也可以不删除 . 但当前feature就不可更改了, 必须从release分支继续编码修改

4. 从develop拉取release分支进行提测, 提测过程中在release分支上修改BUG

5. release分支上线后, 合并release分支到develop/master并推送
     合并之后, 可选删除当前release分支, 若不删除, 则当前release不可修改 . 线上有问题也必须从master拉取hotfix分支进行修改

6. 上线之后若发现线上BUG, 从master拉取hotfix进行BUG修改

7. hotfix通过测试上线后, 合并hotfix分支到develop/master并推送
    合并之后, 可选删除当前hostfix, 若不删除, 则当前hotfix不可修改, 若补丁未修复, 需要从master拉取新的hotfix继续修改

8. 当进行一个feature时, 若develop分支有变动, 如其他开发人员完成功能并上线, 则需要将完成的功能合并到自己分支上
    即合并develop到当前feature分支
9. 当进行一个release分支时, 若develop分支有变动, 如其他开发人员完成功能并上线, 则需要将完成的功能合并到自己分支上
    即合并develop到当前release分支 (!!! 因为当前release分支通过测试后会发布到线上, 如果不合并最新的develop分支, 就会发生丢代码的情况)

git面试常见问题

win10 docker搭建gitlab
gitlab代码评审

[转载]怎么简单理解贝叶斯公式

作者:李现民
链接:https://www.zhihu.com/question/51448623/answer/147298455
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

贝叶斯公式与两个概率有关系,一个是先验概率(基础概率),一个是现象概率(观察到的条件)

例子:某城市发生了一起汽车撞人逃跑事件,该城市只有两种颜色的车,蓝色15%,绿色85%,事发时有一个人在现场看见了,他指证是蓝车。但是根据专家在现场分析,当时那种条件能看正确的可能性是80%。那么,肇事的车是蓝车的概率到底是多少?

令B是城市里车为蓝色的事件,G为车子是绿色的事件,E为观察到车子为蓝色的事件。则由已知条件可以得出P(B)=0.15,P(G)=P(~B)=0.85,至于P(E)我们一会儿再说。

好了,现在,如果没有证人看到肇事者车的话,那么我们只能盲猜,因此肇事者的车子为蓝色的概率只能是整个城市里面车为蓝色的概率,也就是先验概率P(B)=0.15,因为这时我们还没有其他证据介入,只能做个粗略的估算。

接下来,当当当当,有证人了。证人说他看到了车子,并且说是蓝色的,注意,这分两种情况,…………重要的事情说两遍:贝叶斯里面现象(新的证据)部分总是分两种情况出现的:一是车子的确是蓝色的,并且证人也正确的分辨出车是蓝色的来了,概率为 P(E,B)=P(B)xP(E|B)=0.15×0.8=0.12,二是车子根本就是绿色的,只是证人看成蓝色的了,概率为P(E,~B)=P(~B)xP(E|~B)=P(~B)x(1 – P(~E|~B))=0.85x(1-0.8)=0.17,所以P(E)=P(E,B)+P(E,~B)=0.12+0.17=0.29

 

然后,我们要求解的其实是在有证人的条件下车子为蓝色的概率,也就是P(B|E)=P(E,B)/P(E)=0.12/0.29=0.41

你看,P(B|E)根本就是P(B)的加强版本,条件概率跟先验概率描述的根本就是同一件事。那么当当当当,又一个结论来了:当有新的证据出现时,P(B|E)会替代原来P(B)的角色。换句话说,现在警察找到了一个新的证人,他也觉得这辆肇事车是蓝色的,这时在新一轮的贝叶斯概率计算中,基础概率P(B)=0.41,而不是原先的0.15,大家可以算一下,新的P(B|E)=0.73,换句话说,当有两个人看见肇事车辆为蓝色的时候,对比只有一个人看到肇事车辆为蓝色的时候,该车实际为蓝色的概率大大增加

关于贝叶斯,写过一篇文章专门详述了相关的内容,可以参考链接:

lixianmin/cloud

30岁

与一大学同学闲聊中,她说她爸问她30岁了想要什么礼物。这个问题一下子让人觉得有些意外,是的, 什么时候,我们都还觉得30岁很遥远。什么时候,却突然发现已然踏入这个门槛。

没看过真正的富士山,但在我的想像中,它的山顶始终是积雪覆盖的白色,无论四季如何变换。可能这就是不断变化时光中唯一的坚守,没有花开花谢,不管白天黑夜,任它星空流转,是寂寞,亦是执着。

很庆幸,过了这么多年,依然有三两个朋友,一直保持着联系。君子之交淡如水,不需要那些做作无用的嘘寒问暖。

新生儿的诞生,亲人的辞世。。。

是时间教会我们坦然,学会谦让,知道忍耐,懂得感恩。

一文读懂人工神经网络学习原理

原文标题: How do Artificial Neural Networks learn?

作者:rubikscode;翻译:和中华;校对:李海明;

本文约3000字,建议阅读10分钟
本文对人工神经网络是如何学习的进行了简单介绍,使读者可以对神经网络的运行机制有更进一步的认识。

在之前的博客中,我们谈到了关于人工神经网络(ANN)的一些非常有趣的主题。其中介绍了人工神经网络的基本结构以及一些最常用的激活函数。然而,我们并未提及人工神经网络最重要的方面 —- 学习。这种系统最大的威力在于,它们可以像人类一样,一旦在训练过程中熟悉了某种问题,随后便可以解决同类型的问题。在深入这个令人兴奋的主题之前,我们先来快速回顾一下人工神经网络的一些最重要的组件以及其架构。

人工神经网络中最小也是最重要的单元叫神经元。与生物神经系统类似,这些神经元也互相连接并具有强大的处理能力。一般而言,ANNs试图复现真实大脑的行为和过程,这也是为什么他们的结构是基于生物学观察而建模的。人造神经元也是一样的,它的结构令人想起真正的神经元结构。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

每个神经元都有输入连接和输出连接。这些连接模拟了大脑中突触的行为。与大脑中突触传递信号的方式相同——信号从一个神经元传递到另一个神经元,这些连接也在人造神经元之间传递信息。每一个连接都有权重,这意味着发送到每个连接的值要乘以这个因子。再次强调,这种模式是从大脑突触得到的启发,权重实际上模拟了生物神经元之间传递的神经递质的数量。所以,如果某个连接重要,那么它将具有比那些不重要的连接更大的权重值。

由于可能有许多值进入一个神经元,每个神经元便有一个所谓的输入函数。通常,连接的输入值都会被加权求和。然后该值被传递给激活函数,激活函数的作用是计算出是否将一些信号发送到该神经元的输出。之前的文章对这方面有更具体的介绍。

我们可以(并且通常会)在每个ANN中有多层神经元,就如下图所示:

640?wx_fmt=png

学习

如果我们观察自然界,可以发现能够学习的系统都具有高度适应性。在获取知识之时,这些系统利用外界的输入,修改其已经获得的信息,或者修改其内部结构。这其实就是ANNs的本质——它们适应并修改内部结构从而进行学习。更确切地说,ANNs基于输入和期望的输出来改变连接的权重。

你可能会问:“为什么是权重?” 你仔细观察ANNs的结构,会发现如果我们想修改它们的架构,那么可以修改其内部的一些组件。比如,我们可以在神经元之间创建新连接,或者删除连接,或者添加和删除神经元。我们甚至可以修改输入函数或激活函数。事实证明,修改权重参数是最实用的方法。另外,其他大部分情况可以通过修改权重参数来涵盖。例如,删除连接可以通过将权重设为0来完成(译者注:这里作者的意思类似于dropout机制)。如果我们把一个神经元所有相连的权重都设为0,则相当于删除了该神经元。

训练

在文章的开篇部分,我提到了一个对ANNs非常非常重要的词— 训练。对于每个ANN而言,这都是一个必要过程,在这期间ANN会熟悉它所需要解决的问题。在实践中,我们会收集一些数据,并基于此创建预测、分类或进行其他处理,这个数据集则被称为训练集。事实上,根据训练期间的行为和训练集的性质,我们可以将学习分为如下几类:

  • 无监督学习 — 训练集仅包括输入。网络试图识别相似的输入并把他们分类。这种学习受生物学驱动,但并不一定适合所有问题。
  • 强化学习 — 训练集包括输入,但是在训练期间也会给网络提供额外的信息。 内部机制是一旦网络计算出某个输入的输出,我们就提供信息以表明计算结果是正确的还是错误的,并且可能表明网络错误的性质。
  • 监督学习 — 训练集包括输入和期望的输出。通过这种方式,网络可以检查它的计算结果和期望输出相不相同,并据此采取适当的行动。

监督学习是最常用的,所以我们来深入探讨一下此话题。基本上,我们会得到一个训练集,包括输入值向量和期望的输出值向量。一旦网络计算出其中一个输入的输出,成本函数便计算误差向量。这个误差表明我们的猜测跟期望的输出有多接近。最常用的成本函数是均方误差函数:

640?wx_fmt=png

这里,x是训练集中的输入向量,y(x)是人工神经网络产生的输出, a是期望的输出。此外,可以看到这个函数是关于w和b的函数,他们分别代表了权重和偏差(biases)。

现在这个误差被返回神经网络,并且权重被相应地修改。这个过程就是反向传播,它是一个高级的数学算法,人工神经网络通过该算法可以一次调整所有权重。由于这是一个复杂的话题,需要一篇独立的文章介绍,所以建议你阅读这里

(https://rubikscode.net/2018/01/22/backpropagation-algorithm-in-artificial-neural-networks/)需要记住的重点是,通过使用这种算法,ANNs可以快速简单的修改权重。

梯度下降

整个训练的关键是给权重设置正确的值,从而在神经网络中得到期望的输出。这就意味着,我们要使误差向量尽可能小,即找到成本函数的全局最小值。其中一种解决办法是使用微积分。我们可以计算导数,并使用它们找到成本函数的极值所在。然而,这里的成本函数并不是一两个变量的函数,而是网络中所有权重的函数,计算量很快就会变得不可行。这也是为什么我们要使用梯度下降技术。

有一个类比可以很好的描述该过程。想象你有一个小球位于如下图所示的山谷中,如果你让小球滚动,它将会从山谷的一边滚到另一边,最终到达谷底。

640?wx_fmt=png

本质上,我们可以如此看待小球的行为:小球从左到右优化它的位置,最终到达谷底,在本例中,底部就是误差函数的最小值。这就是梯度下降算法在做的事情,它从一个位置开始,计算成本函数C的导数和二阶导数得到关于“小球”朝哪滚的信息。每次我们计算导数时,我们都可以得到当前位置山谷边坡的斜率信息,这在下图中用蓝线表示。

当斜率为负(从左到右向下)时,小球应该朝右移动,否则该朝左移动。请注意,小球只是一个类比,我们并不是要准确的模拟一个物理定律。由于我们已经意识到微积分不是最好的方法,所以我们试图用这种替代方法来到达函数的最小值。

640?wx_fmt=png

简而言之,这个过程是这样的:

  • 将训练集放入神经网络并获得输出。
  • 将输出与期望输出做对比,并使用成本函数计算误差。
  • 基于误差值和使用的成本函数,决定如何改变权重以使误差最小。
  • 重复该过程直到误差值最小。

我刚刚所解释的还有另外一个名字—- 批次梯度下降(Batch Gradient Descent)。这是因为我们把整个训练集放在网络中,然后修改权重。这种方法的问题是,我们可能到达误差函数的一个局部最小值,而不是全局最小值。这也是神经网络中最大的难题之一,不过有多种方式可以解决它。

然而,避免陷入局部最小值陷阱的常用方法是处理完训练集中的一个输入之后就修改权重。当训练集中的所有输入都处理完了,一个epoch也就完成了。为了得到最好的结果,有必要进行多个epochs。这个过程被称为随机梯度下降(Stochastical Gradient Descent)。而且,通过这样做,我们最小化了另一个问题出现的概率 —- 过拟合。过拟合是指神经网络在训练集上表现良好,而在未知的真实数据上不好。当权重被设置为仅仅解决训练集中的特定问题时,会发生这种情况。

总结

现在,我们总结一下:

  • 在神经网络中随机初始化权重
  • 我们将第一组输入值发送给神经网络,使其传播通过网络并得到输出值。
  • 我们将输出值和期望的输出值进行比较,并使用成本函数计算误差。
  • 我们将误差传播回网络,并根据这些信息设置权重。
  • 对于训练集中的每个输入值,重复2至4的步骤。
  • 当整个训练集都发送给了神经网络,我们就完成了一个epoch, 之后重复多次epochs。

所以,这只是神经网络如何学习的一个简化表示。我没有提到的是,在实践中,训练集被分成两部分,第二部分用于验证网络。

希望本文将对神经网络的学习方式提供一个很好的概述。由于这是一个复杂的话题,有些东西并未涉及(比如反向传播),这些都将在后续文章中涉及。需要提及的是,我尽量没有太深入数学,这也给读者留下了很多研究空间。

原文链接:https://rubikscode.net/2018/01/15/how-artificial-neural-networks-learn/

原译文链接:http://blog.csdn.net/Tw6cy6uKyDea86Z/article/details/79283446

 

半监督式学习

相对于所有的数据及测试数据都有label的监督式学习,我们把数据只少量包含有标签,大多数不包含标签的这种情况下的学习,称为半监督式学习。

原理部分,转载一篇文章:

(http://blog.csdn.net/ice110956/article/details/13775071)

什么是半监督学习?

传统的机器学习技术分为两类,一类是无监督学习,一类是监督学习。

无监督学习只利用未标记的样本集,而监督学习则只利用标记的样本集进行学习。

但在很多实际问题中,只有少量的带有标记的数据,因为对数据进行标记的代价有时很高,比如在生物学中,对某种蛋白质的结构分析或者功能鉴定,可能会花上生物学家很多年的工作,而大量的未标记的数据却很容易得到。

这就促使能同时利用标记样本和未标记样本的半监督学习技术迅速发展起来。

 

半监督学习理论简述:

半监督学习有两个样本集,一个有标记,一个没有标记.分别记作

Lable={(xi,yi)},Unlabled={(xi)}.并且数量上,L<<U.

1.      单独使用有标记样本,我们能够生成有监督分类算法

2.      单独使用无标记样本,我们能够生成无监督聚类算法

3.      两者都使用,我们希望在1中加入无标记样本,增强有监督分类的效果;同样的,我们希望在2中加入有标记样本,增强无监督聚类的效果.

一般而言,半监督学习侧重于在有监督的分类算法中加入无标记样本来实现半监督分类.也就是在1中加入无标记样本,增强分类效果.

半监督学习的动力,motivation

某人讨论的时候,总是教导我们的词,motivation.一下午四五遍地强调写论文要有motivation.下面说说半监督学习的motivation.

1.      有标记样本难以获取.

需要专门的人员,特别的设备,额外的开销等等.

2.      无标记的样本相对而言是很廉价的.

半监督学习与直推式学习的区别:

这个网上也有论述.主要就是半监督学习是归纳式的,生成的模型可用做更广泛的样本;而直推式学习仅仅为了当前无标记样本的分类.

简单的说,前者使用无标记样本,为了以后其他样本更好的分类.

后者只是为了分类好这些有限的无标记样本.

下面几个图来生动形象地诠释半监督的好处:

上图中,只有两个标记样本,X,O,剩下绿点是无标记的样本.通过无标记样本的加入,原来的分类界限从0移到了0.5处,更好地拟合了样本的现实分布.

半监督学习算法分类:

1.      self-training(自训练算法)

2.      generative models生成模型

3.      SVMs半监督支持向量机

4.      graph-basedmethods图论方法

5.      multiview learing多视角算法

6.      其他方法

接着简单介绍上述的几个算法

self-training算法:

还是两个样本集合:Labled={(xi,yi)};Unlabled= {xj}.

执行如下算法

Repeat:

1.      L生成分类策略F;

2.      F分类U,计算误差

3.      选取U的子集u,即误差小的,加入标记.L=L+u;

重复上述步骤,直到U为空集.

上面的算法中,L通过不断在U中,选择表现良好的样本加入,并且不断更新子集的算法F,最后得到一个最有的F.

Self-training的一个具体实例:最近邻算法

记d(x1,x2)为两个样本的欧式距离,执行如下算法:

Repeat:

1.      L生成分类策略F;

2. 选择x = argmin d(x, x0). 其中x∈U,min x0∈L.也就是选择离标记样本最近的无标记样本.

2.      F给x定一个类别F(x).

3.      (x,F(x))加入L中

重复上述步骤,直到U为空集.

上面算法中,也就是定义了self-training的”误差最小”,也就是用欧式距离来定义”表现最好的无标记样本”,再用F给个标记,加入L中,并且也动态更新F.

下面是这种算法的效果图:

上图从两个点出发,不断加入最近邻点,不断更新F.

上面的算法表现良好,当然更多的是表现不好.如下:

生成模型

生成算法来源于假设,比如我们假设原样本满足高斯分布,然后用最大释然的概率思想来拟合一个高斯分布,也就是常用的高斯混合模型(GMM).

简单介绍下高斯混合模型:

假设如下的样本分布:

我们假设他们满足高斯分布.

高斯分布的参数有: θ = {w1, w2, µ1, µ2, Σ1, Σ2}

利用最大释然的思想,最大化如下概率:

p(x, y|θ) = p(y|θ)p(x|y, θ).

得到如下的假设分布:

顺便贴一个介绍高斯混合模型日志:

http://blog.csdn.net/zouxy09/article/details/8537620

接着是我们的半监督生成算法:

样本分布如下:

算法过后,得到如下分布:

对比这两个图,说明下高斯混合模型与半监督生成模型的区别:

这两种方法的释然函数不同,前者最大化标记样本出现概率,后者加入了无标记样本出现概率.

算法的具体实现,请参见E-M算法.

这样生成的算法也有许多不良表现,如下:

假设原始的分布式这样的:

通过GMM,它变成了这样:

几个需要注意的地方:

1.      高斯混合的局部收敛性

2.      减少无标记样本的权值

半监督SVM,图算法模型,流行模型等.

SVM的理论不再赘述,就是一个最优超平面:

偷一张很牛逼的SVM图:

这些内容涵盖比较广泛,一篇日志装不下.有兴趣地可以进一步了解.

最后是小结

上两张图:

由于我们对火星基本不了解,探索号带着稀少的标记样本知识飞到了火星.接着就是不断地接触新的样本,更新自己的算法来适应火星环境.

还有我们,从小不断地接触新的事物,不断地被灌输标记或无标记的样本,活到老学到老.

to be continue…

keras 深度学习 mnist示例代码

'''
功能:通过深度学习,让机器学会自动识别手写数字。
源数据来源于:mnist官方库中手写数字的训练及测试数据。

附:
keras中文文档:
http://keras-cn.readthedocs.io/en/latest/for_beginners/concepts/

keras英文文档:
https://keras.io/
'''

#!/usr/bin/env python

import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
import numpy as np
import keras
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.layers import Conv2D, MaxPool2D, Flatten
from keras.optimizers import SGD, Adam
from keras.utils import np_utils
from keras.datasets import mnist

# 定义数据加载函数
def load_data():
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    
    '''
    x_train.shape=[10000,28,28], x_train[0]=(一个二维数组)
    x_test.shape=[(10000, 28, 28)],x_test[0]=(一个二维数组)
    y_train.shape=[(60000,)],y_train[0]=[5]
    y_test.shape=[(10000,)],y_test[0]=[7]
    说明x_train的每一个元素, 都是一个28*28的数组, 下面我们要将数转换成一维向量
    '''

    number = 10000
    x_train = x_train[0:number]
    y_train = y_train[0:number]

    # 将三维数组转换为二维数组
    x_train = x_train.reshape(number, 28*28)
    x_test = x_test.reshape(x_test.shape[0], 28*28)

    # 将向里中每个元素的值从整形转为浮点
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')

    # convert class vectors to binary class matrices
    # 即用one hot encoding方法将输出标签的向量(vector)转化为
    # 只在出现对应标签的那一列为1,其余为0的布尔矩阵, 10个列,有值的一列为1, 其余为0
    # keras.utils.to_categorical(labels, num_classes)
    y_train = np_utils.to_categorical(y_train, 10)
    y_test = np_utils.to_categorical(y_test, 10)

    '''
    x_train = x_train
    x_test = x_test
    '''

    x_train = x_train / 255
    x_test = x_test / 255

    return (x_train, y_train), (x_test, y_test)

'''
x_train.shape => (10000, 784) x_train的形状: 10000个784维的向量
x_train[0] => 第一个向量的值
'''

# 加载训练数据及测试数据
(x_train, y_train), (x_test, y_test) = load_data()
'''
print ('x_train.shape=[%s],x_train[0]=[%s]' %(x_train.shape, x_train[0]))
print ('x_test.shape=[%s],x_test[0]=[%s]'   %(x_test.shape, x_test[0]))
print ('y_train.shape=[%s],y_train[0]=[%s]' %(y_train.shape, y_train[0]))
print ('y_test.shape=[%s],y_test[0]=[%s]'   %(y_test.shape, y_test[0]))
print ('\n\n')
exit()

x_train.shape=[(10000, 784)],x_train[0]=(一个一维数组)
x_test.shape=[(10000, 784)],x_test[0]=(一个一维数组)
y_train.shape=[(10000, 10)],y_train[0]=[[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]]
y_test.shape=[(10000, 10)],y_test[0]=[[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]
'''

# 定义一个序贯模型(Graph模型的一个特殊情况)
# 序贯模型是多个网络层的线性堆叠,训练时数据在网络层之间顺序执行。
# 序贯模型是相对于Graph模型而言。
# Graph模型支持多输入多输出,层与层之间想怎么边就怎么连,但是编译速度慢。
model = Sequential()

# 定义神经网络输入层
model.add(Dense(input_dim=28*28, units=633, activation='relu'))

# 定义神经网络的隐藏层
model.add(Dense(units=633, activation='relu'))
model.add(Dense(units=633, activation='relu'))

# 定义神经网络输出层
model.add(Dense(units=10, activation='softmax'))

# 指定损失函数:loss, 优化器:optimizer, 性能评估指标列表:metrics
model.compile(loss='categorical_crossentropy',optimizer=SGD(lr=0.1),metrics=['accuracy'])

# 开始训练模型
# model.fit(data, labels, batch_size=, epochs=)
model.fit(x_train, y_train, batch_size=1, epochs=1000)

# 打印训练得到最终的准确度
print('\nGet Train Accuracy')
result_train = model.evaluate(x_train,y_train)
print('Train Accuracy:[%f]\n' %(result_train[1]))

# 打印应用到测试数据得到的准确度
print('Get Test Accuracy')
result_test = model.evaluate(x_test,y_test)
print('Test Accuracy:[%f]' %(result_test[1]))

'''
# 使用训练得到的模型,对新的数据进行预测:
classes = model.predict(x_newdata, batch_size=128)
'''

 

Batch size and epochs 参数设置

Batch的含义:

引用自:http://keras-cn.readthedocs.io/en/latest/for_beginners/concepts/

深度学习的优化算法,说白了就是梯度下降。每次的参数更新有两种方式。

第一种,遍历全部数据集算一次损失函数,然后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数都要把数据集里的所有样本都看一遍,计算量开销大,计算速度慢,不支持在线学习,这称为Batch gradient descent,批梯度下降。

另一种,每看一个数据就算一下损失函数,然后求梯度更新参数,这个称为随机梯度下降,stochastic gradient descent。这个方法速度比较快,但是收敛性能不太好,可能在最优点附近晃来晃去,hit不到最优点。两次参数的更新也有可能互相抵消掉,造成目标函数震荡的比较剧烈。

为了克服两种方法的缺点,现在一般采用的是一种折中手段,mini-batch gradient decent,小批的梯度下降,这种方法把数据分为若干个批,按批来更新参数,这样,一个批中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性。另一方面因为批的样本数与整个数据集相比小了很多,计算量也不是很大。

基本上现在的梯度下降都是基于mini-batch的,所以Keras的模块中经常会出现batch_size,就是指这个。

顺便说一句,Keras中用的优化器SGD是stochastic gradient descent的缩写,但不代表是一个样本就更新一回,还是基于mini-batch的。

epochs的含义:

指的是训练过程中,训练数据将被跑几轮。

Keras中,batch_size 和 epochs参数值的影响:

(以下内容,参考自知乎:https://www.zhihu.com/question/32673260)

在训练时, 需要指定最小批次:batch_size, 以及迭代次数:epochs。 这两个参数可以显著的影响训练收敛的速度及准确度。设置不当的话,很可能会导致训练不收敛,或者要训练很久才会收敛。

分别说明:

batch_size: 

batch_size比较大的情况下,训练容易陷入局部最优解(local minimize)的情况,同时对机器内存(以及显存)的配置要求比较高。好处是收敛速度比较快(存疑)。
batch_size比较小的情况下,收敛的速度会慢一些, 甚至有可能会不收敛。 但是训练引入的随机性比较大,相当程度上可避免出现局部最优解(local minimize), 对硬件配置要求相对较低。

batch数太小,而类别又比较多的时候,真的可能会导致loss函数震荡而不收敛,尤其是在你的网络比较复杂的时候。

那么怎么选择batch size呢?可以选择8的倍数,然后是稍微大一点(一般而言)。另外一个方法,就是选择一部分数据,跑几个batch看看loss是不是在变小, 选择一个合适的就可以了。