最近写autoencoder的时候,遇到嵌套列表复制和reverse的问题。虽然list提供了copy方法,但涉及嵌套复制时就会出错。例如,

1
2
3
4
x = [[1, 2], 3]
y = x.copy()
y.reverse()
y[1][0] = 2

yx变为,

1
2
x = [[2, 2], 3]
y = [3, [2, 2]]

list.copy()对最外层的列表实现了复制,但内部的列表并没有。解决方法是用copy库中的deepcopy方法,如下

1
2
3
4
5
from copy import deepcopy
x = [[1, 2], 3]
y = x.copy()
y.reverse()
y[1][0] = 2

此时的xy为,

1
2
x = [[1, 2], 3]
y = [3, [1, 2]]

Reference

Comment and share

趁着系统在升级,记录一下ubuntu recovery mode的网络恢复功能。我的系统是Ubuntu1610,因为不是LTS,官方已经不支持更新了,因此也无法通过正常的手段升级,曲线升级的方法参考这里

Revoery 模式下网络连接

在升级过程中,可能会出现重启后无法连接网络的问题,其中最严重的就是网卡驱动没有了。解决方法如下,

  1. 重启系统;
  2. 选择Advanced options for ubuntu;
  3. 选择最近的image的recover mode;
  4. 进入后,选择network enable network;
  5. 再次重启。

DNS server

另一种情况是,DNS server出现问题,例如/etc/reconv.conf文件为空,或者出现问题。解决方法是自己添加,默认的配置如下

1
2
3
4
5
6
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 127.0.0.53

也可以自己修改成如下形式,

1
2
nameserver 114.114.114.114
nameserver 8.8.8.8

多网卡的配置

除了网络恢复问题,多网卡的配置也是我关注的问题,这样可以一定程度上保证电脑处在联网状态。以我的系统为例,分别有两块网卡,有线网卡enp0s31f6和无线网卡wlp4s0,二者将连接到不同的网络,以有线网卡作为主要网卡,则配置如下,配置文件为/etc/network/interfaces

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
# The primary network interface
auto enp0s31f6
iface enp0s31f6 inet static
address 192.168.1.100
netmask 255.255.255.0
network 192.168.1.0
gateway 192.168.1.1
# The wireless network interface with dhcp
auto wlp4s0
iface wlp4s0 inet dhcp
address 192.168.30.100
netmask 255.255.255.0
network 192.168.30.0
gateway 192.168.30.1
wpa-ssid WIFI-NAME # SSID name
wpa-key-mgmt WPA-PSK # Encryption method
wpa-psk YOYR-PASSWORD-HERE # WIFI password

References

Comment and share

考虑到系统的稳定性,也因为懒,一直没升级Ubuntu 1610,也没有update。最近发现官方已经不支持1610了,而且直接把yakkety的镜像给取消了。所以,即使是利用系统自带的update manager,也无法直接升级到1710,会出现如下的两类错误,

无法更新
1
2
3
4
5
6
7
8
E:The repository 'http://archive.canonical.com/ubuntu yakkety Release' does not have a Release file.,
W:Updating from such a repository can't be done securely, and is therefore disabled by default.,
W:See apt-secure(8) manpage for repository creation and user configuration details.,
E:The repository 'http://archive.ubuntu.com/ubuntu yakkety Release' does not have a Release file.,
W:Updating from such a repository can't be done securely, and is therefore disabled by default.,
W:See apt-secure(8) manpage for repository creation and user configuration details.,
E:The repository 'http://archive.ubuntu.com/ubuntu yakkety-updates Release' does not have a Release file.,
...
无法升级
1
An upgrade from 'yakkety' to 'artful' is not supported with this tool.

参考Askubuntu上的问题,有如下的解决方法,

1
2
3
4
5
6
7
8
9
10
11
cd /etc/apt/
# 备份现有的sources.list
sudo cp sources.list sources.list.bkp
# 替换yakkety为artful
sudo vim sources.list
:%s/yakkety/artful/g
# 保存并重新更新和升级
sudo update
sudo upgrade
# 重启系统
reboot

Reference

[1] How to upgrade ubuntu from 1610 to 1710

Comment and share

这两天尝试将一个MATLAB工程转成Python,卡在一个bug上很久,最后发现是二者在矩阵索引上存在区别。这里我采用的是Python的NumPy库。

我们经常会通过一定的逻辑关系索引矩阵中的元素,并获取这些元素的位置信息,即indices。例如,

1
2
3
4
5
6
% MATLAB实现
x = resize(0:8, 3, 3);
% 一维索引
idx = find(x >= 3);
% 二维索引
[idr, idc] = find(x >= 3);

对应的python实现为,

1
2
3
4
5
import numpy as np
x = np.arange(9).reshape(3,3)
# 只有二维索引
[idr, idc] = np.where(x >= 3)

这里可以看出,MATLAB提供一种一维索引,即将二维矩阵以列为先,行次之转为一维向量,输出的索引对应该一维向量中元素所在位置。(这种处理方法经常可以用于加速运算,缩短运行时间。)然而,NumPy的where方法根据矩阵的维数提供对应axis的索引,没有MATLAB这种一维索引的输出。

因此,在python中使用np.where进行矩阵元素索引时,要注意如下两点,

  1. np.where的输出是一个列表;
  2. np.where的输出列表的元素个数与矩阵的维数对应。

Reference

[1] numpy.where

Comment and share

简单记录一下利用python的SciPy库进行曲线拟合的方法,主要分为三个步骤,(1) 获取待拟合数据; (2) 定义函数描述待拟合曲线; (3)利用Scipy.optimize.curve_fit模块进行拟合。

获取数据的步骤不再赘述,这里从步骤二开始。以泊松分布为例,首先定义函数poisson_func

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import math
def poisson_func(k, l, c):
"""Poisson function
inputs
======
k: np.ndarray
number of accidents, i.e., the x axis;
l: double
the lambda parameter of Poisson distribution
c: double
a constant for release the optimization
output
======
the fitted result according to l and c w.r.t. k
note
====
l and c are the parametres to be estimated.
"""
k_mat = np.ones(k.shape)
for x, i in enumerate(k):
k_mat[i] = math.factorial(x)
return l**k / k_mat*np.exp(-l) + c

紧接着,根据待拟合的数据,对参数进行估计,如下

1
2
3
4
from scipy.optimize import curve_fit
popt, pcov = curve_fit(poisson_func, x, y)
perr = np.sqrt(np.diag(pcov))

其中popt为估计的参数,pcov为对应的相关矩阵,其对角线为方差,可用于计算拟合参数的误差perr。

下图为我的测试样例,图中橙色三角为待拟合样本点,蓝色实线为拟合结果。

References

[1] Scipy.optimize.curve_fit
[2] Poisson distribution

Comment and share

背景

面试官负责的业务: 计算机视觉相关

应聘职位:机器学习,计算机视觉方向

流程

首先自我介绍,介绍项目背景、贡献和成果。然后具体讨论技术,面试时间约45分钟。

问题及回答

深度学习

Q1. 为什么做预训练+精调,用于无监督的样本有没有直接尝试做标记以后进行有监督训练?两个数据集有什么区别? 样本的筛选有标准吗?

  • 因为有标签的样本数量不足, 无标签的样本数量可观; 预训练可以利用海量的样本进行特征学习,精调可以有针对性的强化特征中适合分类的特征。
  • 没有尝试做有监督学习,是因为此类样本的标注需要专家和公开发表。且我们认为做无监督学习是有意义的。
  • 两个数据集的区别:1. 样本的质量,2. 样本的类别模糊性,3. 各个类别的样本分布不同。
  • 筛选有标准:例如图像质量、样本能适用于分类器的输入要求。

Q2. 有没有尝试过引入其他类别的图像,做类似于迁移学习的工作?

  • 有尝试做迁移学习,但从结果上看,只应用在已有样本集上的效果更优。
  • 迁移学习的网络参数规模还是比较大的,对训练设备要求较高。我们尝试提出层数较低的网络,能有助于其被应用。

Q3. 既然尝试了生成网络,VAE和GAN的相同点和区别在哪里? 既然说GAN不好训练,为什么呢?

  • VAE和GAN的相同之处: 1. 二者都是由两个子网络组成,2. 目的都是通过估计参数的分布,以从该分布中采样,生成新的样本。
  • VAE和GAN的区别之处: 1. GAN是从一个随机噪声中产生样本,VAE是从一个特定的低维高斯分布映射到高维的样本空间,后者的约束更强。2. 普通的GAN在训练时不容易收敛,面试官建议从KL散度的角度来分析不收敛的原因。
  • 近期如WGAN等对GAN的优化,使得输入和输出的分布不一定要强相关,能够帮助网络的收敛。(面试官)

Q4. 生成网络怎么衡量效果好呢? (云核心也有问过)

  • 比较生成样本的分布与原分布的相似程度;
  • 将生成的样本交给专家判断,交叉验证计算机器和专家的结论。

Q5. 深度学习中,常用的避免过拟合的tricks有哪些?

  • 常用的tricks有dropout, regularization, batch normalization, residual。难度逐渐增加,方法也越新。

Q6. 正则化,L1和L2的区别是什么?

Q7. 激活函数的作用?可以用线性的激活函数吗?

  • 激活函数有两个作用,1. 使分类器能够求解非线性问题,2. 对输出进行约束,避免BP时的梯度爆炸。
  • 线性的激活函数是不可用的,因为NN本身就是为了解决各种非线性的问题, 线性激活函数不适用这种问题。(面试官)
  • 我的理解是线性激活函数,如果你真想用,也是可以的。。。
传统机器学习

Q1. 你涉及过的传统机器学习模型有哪些?

  • 不要给自己挖坑,说你真正推导过,理解原理的。我的回答是, SVM, ANN, DF, AdaBoost,HMM.

Q2. SVM的核技术是什么?怎么约束核函数的?

  • SVM用核方法的目的是解决非线性分类超平面的求解问题,通过核技巧将本特征空间的非线性分类转化为另一个空间的线性分类问题。
  • SVM核的选择参考Mercer定理,要求该函数是半正定的,且计算一对特征向量的核函数等价于在变换后的空间中计算这对向量的点积。(还是没太懂。。。)

Q3. HMM的两个假设是什么?
参考《统计学习方法》

  • 齐次马尔可夫性假设,即任意时刻t的状态只依赖于t-1时刻的状态,与t-1之间的状态和观测无关,
  • 观测独立性假设: 即任意时刻的观测只依赖于该时刻的马尔可夫链的状态,与其他状态和观测无关,

Q4. EM算法还有其他的类似的模型和应用吗?

  • 常用的有两个,KNN的求解类似于EM,以及Monte Carlo模拟的求解思路类似。

Q5. AdaBoost,为什么有效果,原理是什么?
AdaBoost是用弱分类器的线性加权来代替强分类器。这里的强和弱指“可学习”性,即分类器通过学习以后,学习准确率相对于随机猜测的距离。AdaBoost通过迭代减少分类器在数据集上的分类误差率,从而体现出有效性。或者说Boost通过弱分类降低了整体估计的误差,或者说方差,使得置信区间更小。还有一种理解是,Boost方法提高了模型的泛化能力,从而提升了分类准确率。

图像处理问题

Q1. 既然做过分类,那么传统图像处理中有哪些特征?
同样的,不要给自己挖坑。。。用过哪些就说,比如我说的是GLCM, Gabor。HoG和SIFT这种很常见,也需要巩固的。

Q2. 为什么用Gabor的效果就好呢?
我的回答是效果好。。。其实我理解的是特征提取的目的就是找到可分性高的特征。所以要考虑怎么衡量可分性。

Any questions?

  1. 如果可以进来,我需要准备什么?
  2. 部门有哪些业务?Base在哪里?

Comment and share

问题描述

也许是Ubuntu16.04以后版本,或者是google-chrome的版本问题,会出现从chrome以外的链接打开chrome后只显示空白标签的情形。

解决方法

其解决方法是给google-chrome.desktop配置文件的Exec提供%U的值,步骤如下

1
2
3
vim ~/.local/share/applications/google-chrome.desktop
# Find Exec and add %U
Exec=/opt/google/chrome/chrome %U

Reference

解决Ubuntu无法从外部应用启动Chrome打开链接的问题

Comment and share

Nothing to tell, ‘cause I am out of work for a week, lol. A warm greeting from my hometown that happy Chinese new year. Also a celebrationg for my 400th contribution to my github.

Wish everything well in the new year.

Comment and share

写之前吐个槽,连续的熬夜加酗酒,要跪。。。睡前写个hexo相关的教程,基于hexo如何撰写和发布一篇博客。主要分为两步,(1) 掌握markdown语法和git相关指令; (2) 利用hexo命令初始和编译文章。

Markdown语法和git相关指令

Markdown的基本语法可以参考这篇文章,在博客中主要会用到三种语法结构,

  • 标题控制 用#,#号数量越多,标题级别越低;
  • 超链接: 形如[name](address);
  • 图像: 形如![name](address) 注意感叹号。

而git相关的指令,用于上传图片,作为图床。主要指令有,

  • git add xxx : 添加一个需要push的文件;
  • git commit -m “xxx”: 给这次push添加commitp;
  • git push: 将commit的文件推送到git仓库中。

利用Hexo命令初始、编译和发布文章

Hexo 的安装和配置参考这篇文章,这里只介绍新文章的生成过程。

  1. 新建一篇名为xxx的文章,此时在blog/source/_posts路径下会生成名为’xxx.md’的文件

    1
    2
    $ cd blog
    $ hexo new "xxx"
  2. 编写文章

    1
    2
    $ cd ./source/_posts
    $ vim xxx.md

或者可以利用markdown相关的编辑器,如haroopad,这是一款非常好用的编辑器。

  1. 编译、预览和发布文章
    利用如下命令可以编译、预览和发布文章,
    1
    2
    3
    $ hexo g # 编译
    $ hexo s # 预览,此时在浏览器输入 localhost:4000
    $ hexo d # 发布文章到github

Enjoy it~~

Comment and share

写之前吐个槽,我又把tf.nn.softmax_cross_entropy_with_logits的参数赋反了,折腾了一晚上。。。这篇文章主要讨论TensorFlow中训练指定变量的问题。这篇博客给了个非常巧妙的方法,简单记录一下。

1. 查看可训练的参数及其index

tf.trainiable_variables里存储了可以用于训练的变量,利用如下方法可以打印出它们的信息,

1
2
3
4
5
6
7
variables_names = [v.name for v in tf.trainable_variables()]
values = sess.run(variables_names)
i = 0
for k, v in zip(variables_names, values):
print(i, "Variable: ", k)
print("Shape: ", v.shape)
i += 1

2. 建立train options,并为其提供不同的trainable lists

假设有两个loss function,分别对应网络中不同区域的变量,为了实现梯度的有效传递,可以利用如下方法,

1
2
3
4
5
6
loss1 = ...
loss2 = ...
var_list1 = tf.trainable_variables()[0:10]
var_list2 = tf.trainable_variables()[10:]
train_op1 = tf.train.AdamOptimizer(learning_rate).minimize(loss1, var_list=var_list1)
train_op2 = tf.train.AdamOptimizer(learning_rate).minimize(lose2, var_list=var_list2)

reference

[1] [tensorflow] 在不同层上设置不同的学习率,fine-tuning

Comment and share

Author's picture

Jason Ma

We are in the same story.


Astronomer? Software engineer


Shanghai