引用

文章资源文件夹

对于那些想要更有规律地提供图片和其他资源以及想要将他们的资源分布在各个文章上的人来说,Hexo也提供了更组织化的方式来管理资源。这个稍微有些复杂但是管理资源非常方便的功能可以通过将 config.yml 文件中的 post_asset_folder 选项设为 true 来打开。

_config.yml
post_asset_folder: true

当资源文件管理功能打开后,Hexo将会在你每一次通过 hexo new [layout] <title> 命令创建新文章时自动创建一个文件夹。这个资源文件夹将会有与这个文章文件一样的名字。将所有与你的文章有关的资源放在这个关联文件夹中之后,你可以通过相对路径来引用它们,这样你就得到了一个更简单而且方便得多的工作流。

相对路径引用的标签插件

通过常规的 markdown 语法和相对路径来引用图片和其它资源可能会导致它们在存档页或者主页上显示不正确。在Hexo 2时代,社区创建了很多插件来解决这个问题。但是,随着Hexo 3 的发布,许多新的标签插件被加入到了核心代码中。这使得你可以更简单地在文章中引用你的资源。

{% asset_path slug %}
{% asset_img slug [title] %}
{% asset_link slug [title] %}

比如说:当你打开文章资源文件夹功能后,你把一个 example.jpg 图片放在了你的资源文件夹中,如果通过使用相对路径的常规 markdown 语法 ![](/example.jpg)

它将 不会 出现在首页上。(但是它会在文章中按你期待的方式工作)

正确的引用图片方式是使用下列的标签插件而不是 markdown :

{% asset_img example.jpg This is an example image %}

通过这种方式,图片将会同时出现在文章和主页以及归档页中。

Decistion Tree(决策树)

假设有如下数据:

信息熵(information entropy)

信息熵(Information entropy): 是度量样本集合纯度的一种指标 公式: 假设当前样本集D中第k类样本所占的比利为 \(p_k\) (k=1, 2, ..., |y|) \[ Ent(D) = - \sum_{k=1}^{\vert y \vert}p_k\cdot log_2 p_k \]

信息增益熵(Information gain)

信息增益熵(Information gain): 一定条件下,信息复杂度(不确定性)减少的程度 公式: \[ Gain(D, a) = Ent(D) - \sum_{v=1}^V \dfrac{|D^v|}{|D|}Ent(D^v) \]

基尼指数(Gini index)

公式: \[ Gini(D) = 1 - \sum_{k=1}^{|y|} p_k^2 \]

\[ Gini_index(D, a) = \sum_{v=1}^{V} \dfrac{|D^v|}{|D|}Gini(D^v) \]

不同的算法

  • ID3
    for node in nodes:
    pass
  • C4.5
  • CART(classification and regression tree)

https://zh.wikipedia.org/wiki/A*%E6%90%9C%E5%B0%8B%E6%BC%94%E7%AE%97%E6%B3%95 #

希腊符号读音

希腊字母 汉字注音 汉语拼音
Αα 阿尔法 alfa
Ββ 贝塔 bita
Γγ 伽马 gama
Δδ 德耳塔 dêlta
Εε 艾普西龙 êpsilon
Ζζ 截塔 zita
Ηη 艾塔 yita
Θθ 西塔 sita
Ιι 约塔 yota
Κκ 卡帕 kapa
∧λ 兰布达 lamda
Μμ 米尤 miu
Νν 纽 niu
Ξξ 克西 ksai
Οο 奥密克戎 oumikelong
∏π 派 pai
Ρρ 若 rou
∑σ 西格马 sigma
Ττ 套 tao
Φφ 斐 fai
Χχ 喜 hai
Υυ 宇普西龙 yupsilon
Ψψ 普西 psai
Ωω 欧米伽 omiga

Back Bropagation(向后传播)

其中: \[ net_i: 第i个神经元的输入 \\\\ o_i: 第i个神经元的输出 \\\\ \omega_{i, j}: 第i个神经元到下一层第j个神经元的权重 \\\\ \]

因此可得: \[ o_i = \gamma(net_i) \\\\ E = \sum[t\cdot\log(y) + (1-t)\cdot\log(1-y)] \]

其中: - \(\gamma\) 是激活函数 - E 是误差(这里使用Cross Entropy Loss), y是为输出神经元的实际输出, t为样本的预期输出

所以求误差对于权重的偏微分: \[ \begin{align} \dfrac{\sigma(E)}{\sigma(\omega_{i, j})} &= \dfrac{\sigma(E)}{\sigma(o_j)} \cdot \dfrac{\sigma(o_j)}{\sigma(net_j)} \cdot \dfrac{\sigma(net_j)}{\sigma(\omega_{i, j})} \\\\ \end{align} \]

其中: \[ \begin{align} \dfrac{\sigma(o_j)}{\sigma(net_j)} &= \dfrac{\sigma(\gamma(net_j))}{\sigma(net_j)} \\\\ &= \gamma(net_j) \cdot (1 - \gamma(net_j)) \\\\ &= o_j \cdot (1 - o_j) \end{align} \]

\[ \begin{align} \dfrac{\sigma(net_j)}{\sigma(\omega_{i, j})} &= \dfrac{\sigma}{\sigma(\omega_{i, j})}(\omega_{i, j} \cdot o_i + b_i) \\\\ &= o_i \end{align} \]

输出层

因为当\(o_j\)是最后一层输出层时: \[ \begin{align} \dfrac{\sigma(E)}{\sigma(o_j)} &= \dfrac{\sigma}{\sigma(y)} \cdot [t \cdot \log(y) + (1-t)\cdot\log(1-y)] \\\\ &= \dfrac{t}{y} - \dfrac{1-t}{1-y} \\\\ &= \dfrac{t - y}{y\cdot(1 - y)} \end{align} \]

隐藏层

\(o_j\)为任意一层隐藏层的时: \[ \begin{align} \dfrac{\sigma(E)}{\sigma(o_j)} &= \dfrac{\sum_{l \in L}E_l}{\sigma(o_j)} \\\\ &= \sum_{l \in L}\dfrac{E}{\sigma(o_j)} \\\\ &= \sum_{l \in L}\dfrac{E}{\sigma(o_l)} \cdot \dfrac{\sigma(o_l)}{\sigma(net_l)} \cdot \dfrac{\sigma(net_l)}{\sigma(o_j)} \\\\ &= \sum_{l \in L}\dfrac{E}{\sigma(o_l)} \cdot \dfrac{\sigma(o_l)}{\sigma(net_l)} \cdot \dfrac{(\omega_{j, l} \cdot o_j + b_j)}{\sigma(o_j)} \\\\ &= \sum_{l \in L}\dfrac{E}{\sigma(o_l)} \cdot \dfrac{\sigma(o_l)}{\sigma(net_l)} \cdot \omega_{j, l} \\\\ \end{align} \] 其中: - \(L\)是下一层神经层, \(l \in L\)神经层的神经元

这里设: \[ \begin{align} \delta_j &= \dfrac{E}{\sigma(o_j)} \cdot \dfrac{\sigma(o_j)}{\sigma(net_j)} \end{align} \]

所以有: \[ \begin{align} \delta_j &= \begin{cases} \dfrac{t - y}{y\cdot(1 - y)} \cdot o_j \cdot (1 - o_j) , &当j是输出层的神经元时 \\\\ \sum_{l \in L}(\delta_l \cdot \omega_{j, l} ) \cdot o_j \cdot (1 - o_j), &当j是隐藏层的神经元时 \\\\ \end{cases} \end{align} \]

更新参数

\[ \begin{align} \omega_{i, j} &= \omega_{i, j} - \eta \cdot \dfrac{\sigma(E)}{\sigma(\omega_{i, j})} \\\\ &= \omega_{i, j} - \eta \cdot \delta_j \cdot o_i \end{align} \]

其中: - \(\eta\) 是学习率,也就是步长

同理: \[ \begin{align} b_{i, j} &= b_{i, j} - \eta \cdot \dfrac{\sigma(E)}{\sigma(b_{i, j})} \\\\ &= b_{i, j} - \eta \cdot \delta_j \end{align} \]

TODO list

  • [ ][Batch Normal](https://arxiv.org/pdf/1502.03167.pdf)
  • [ ][A*搜索算法](https://zh.wikipedia.org/wiki/A*%E6%90%9C%E5%B0%8B%E6%BC%94%E7%AE%97%E6%B3%95)
  • [ ][数据结构Graph](https://en.wikipedia.org/wiki/Graph_(abstract_data_type))

AlexNet

non-saturating neurons(非饱和神经元) 和 saturating neurons(饱和神经元)

https://stats.stackexchange.com/questions/174295/what-does-the-term-saturating-nonlinearities-mean 使用非压缩性的激活函数的神经元是非饱和神经元 例如: Relu 使用压缩性的激活函数的神经元是饱和神经元 例如: tanh, sigmod

参考:https://www.jianshu.com/p/8066e8d4f187

PyQt5

常用工具

  • Qt Designer
  • PyUIC5

pyqt5的工具链配置

配置Qt Designer(mac 环境下)

使用 brew 安装pyqt5之后, designer一般路径为: /usr/local/Cellar/qt/5.11.0/libexec/Designer.app,可以自行搜索Designer.app

Tools->External Tools-> +
Name: Qt Designer
Description: 生成.ui文件
Program: /usr/local/Cellar/qt/5.11.0/libexec/Designer.app
Parameters: $FilePath$
Working directory: $ProjectFileDir$

配置好以后, 在.ui文件右键"External Tools->Qt Designer", 可以在Qt Designer中编辑这个.ui文件

配置PyUIC5

Tools->External Tools-> +
Name: PyUIC5
Description: 将.ui文件转为.py文件
Program: pyuic5
Parameters: $FilePath$ -o $FileDir$/$FileNameWithoutExtension$.py
Working directory: $ProjectFileDir$

配置好以后, 在.ui文件右键"External Tools->PyUIC5", 可以调用命令转成.py文件

使用pyinstaller打包

pyinstaller -F main.py

http://yeephycho.github.io/2017/09/16/Loss-Functions-In-Deep-Learning/ http://www.csuldw.com/2016/03/26/2016-03-26-loss-function/ http://thegrandjanitor.com/2015/08/20/gradient-descent-for-logistic-regression/ https://blog.csdn.net/happyer88/article/details/46772347 https://zh.wikipedia.org/wiki/%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD%E7%AE%97%E6%B3%95 https://www.cnblogs.com/charlotte77/p/5629865.html # Loss Function 顾名思义,误差损失函数, 用于计算预测和实际值得误差的函数.

前期知识

似然函数[WiKi]

似然函数是一种对于统计模型中参数的估计

似然性 和 概率

概率是指在已知一些条件的情况下预估结果 似然性则是用于在已知某些观测所得到的结果时,对有关事物的性质的参数进行估计

在这种意义上,似然函数可以理解为条件概率的逆反。在已知某个参数B时,事件A会发生的概率写作: \[ P(A|B) = \dfrac{P(A, B)}{P(B)} \] 根据贝叶斯定理 \[ P(B|A) = \dfrac{P(A|B) \cdot P(B)}{P(A)} \]

例子: 假设投掷硬币2次得到正面,记 H为得到正面的事件, pH为得到正面的概率 则 \[ P(HH|pH) = pH^2 = 0.5^2 \] 因此2次正面的结果的似然函数为: \[ L(pH|HH) = P(HH|pH) = pH^2 \] 所以,当 * pH = 0.5 * 时,似然函数的值是0.25(注意这里的0.25并不是pH取值0.5的概率),这个大小并不重要 当 * pH = 0.6 * 时, L(pH|HH) = 0.36, 0.36 > 0.25. 注意到这里似然函数的值变大了。 所以根据观测的结果,2次正面朝上,pH=0.6比pH=0.5的概率更大,似然函数值更大,更为合理. 似然函数的重要性不是它的具体取值,而是当参数变化时函数到底变小还是变大 对同一个似然函数,如果存在一个参数值,使得它的函数值达到最大的话,那么这个值就是最为“合理”的参数值。

Mean Sequared Error(L2 Loss)

\[ MSG = \dfrac{1}{n} \sum{e^2} \]

Cross Entropy Loss

\[ J(\theta) = \dfrac{1}{m} \sum_{i=1}^m Cost(h_\theta(x_i), y_i) \] \[ Cost(h_\theta(x_i), y_i) = \begin{cases} -y_i \cdot \log(h_\theta(x_i)) , y=1 \\\\ -(1 - y_i) \cdot (1 - \log(h_\theta(x_i))) , x=0 \\\\ \end{cases} \] \[ J(\theta) = - \dfrac{1}{m} \sum_{i=1}^m[yi \cdot log(h_\theta(x_i)) + (1-y_i) \cdot log(1 - h_\theta(x_i))] \]

\(h_\theta(x_i) = sigmod(x_i)\) \(Sigmod = (1 + e^{-x})^{-1}\)

L1 Loss

这里挖坑

python

python 的 GIL

python wiki 中对 GIL的解释

GIL(Global Interpreter Lock),全局解释器锁.

python的解释器,py文件的运行需要解释器。在cpython中,这个解释器不是线程安全的,他有一个全局锁,用于保证对象的线程安全。当多线程情况下运行时候。每次其实只有一个线程在运行,其他的线程都是在等待。这就导致python中的多线程并不能完全利用全部的cpu资源(如果是多核处理器的话).所以GIL的存在,使得python处理cpu密集型的任务时候效率低下,因为要不断切换浪费时间切换线程,而且无法利用所有的cpu资源。而在I/O密集型的任务有比较好的效率,因为处理耗时的I/O任务时,线程会释放GIL给其他线程.

关于解释器和编译器的区别: - 代码 -运行-> 解释器 --> cpu - 代码 -->编译器 -运行-> cpu

# coding=utf8
import time
import threading

def count(num):
while num > 0:
num -= 1


num = 10000000

start = time.time()
count(num)
count(num)
end = time.time()
print('共运行: {}'.format(end - start))


t1 = threading.Thread(target=count, args=(num,))
t2 = threading.Thread(target=count, args=(num,))
threads = [t1, t2]
start = time.time()
for t in threads:
t.start()
t.join()
end = time.time()
print('多线程共运行: {}'.format(end - start))

# 结果,多线程更慢
# 共运行: 0.858108997345
# 多线程共运行: 1.28467583656
# python3.6下
# 共运行: 1.553386926651001
# 多线程共运行: 1.5657341480255127

上面python3.6为什么将近慢了一倍? > python3 的 int 都默认为 long integer.所以会稍微慢一些. > 这里有一个python3 和python2 的表现的对比。部分对比中python3比python2快8%到48%。部分慢25%到54%[Speed] Benchmarks: Comparison between Python 2.7 and Python 3.6 performance

python的多线程,多进程, 协程

几种排序

快速排序

def sort_fast(alist):
pass

数据库

mysql 的索引

mysql 的 when case

先创建测试数据

create table testScore    
(
tname varchar(30) null,
ttype varchar(10) null,
tscor int null
);

insert into testScore values ('张三','语文',80);
insert into testScore values ('张三','数学',98);
insert into testScore values ('张三','英语',65);
insert into testScore values ('李四','语文',70);
insert into testScore values ('李四','数学',80);
insert into testScore values ('李四','英语',90);

查询每个人的分数

select
`tname`,
max(case `ttype` when '语文' then `tscor` else 0 end) '语文',
max(case `ttype` when '数学' then `tscor` else 0 end) '数学',
max(case `ttype` when '英语' then `tscor` else 0 end) '英语'
from testScore group by `tname`;

group 中的case when

select
`tname`,
case `ttype`
when '数学' then '理科'
else '文科'
end as '科别',
sum(`tscor`) as '总分'
from `testScore`
Group by
`tname`,
case `ttype`
when '数学' then '理科'
else '文科'
end;

orm 的 n + 1问题

缓存、队列

redis 的 持久化策略

官方说明(英文)

中文翻译

  • RDB 在指定的时间间隔内生成数据集的时间点快照
  • AOF 持久化记录数据库的所有操作命令,并在服务器重启时重新执行

缓存击穿、雪崩、穿透

  • 缓存雪崩:指大量缓存同时失效,使得查询直接落到数据库上,造成数据库短时间内承受大量请求而崩掉。
  • 缓存击穿:指某个热点key,短时间大量请求都在访问,当他过期时,所有的请求会突然都直接落到数据库上,造成数据库短时间内承受大量请求而崩掉。
  • 缓存穿透:当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增。

其他基础

tcp/ip协议,tcp的三次握手等

tcp/ip 是一个协议簇的统称,

tcp(transport control protocol)传输控制协议 udp(user datagram protocol)

http协议

Hyper Text Transfer Protocol(超文本传输协议) Hypertext Transfer Protocol -- HTTP/1.1

包括方法: GET,POST,HEAD,OPTIONS,DELETE,PUT,TRACE,CONNECT

url, uri 的区别

url(uniform resource locator) uri(uniform resource identifier) 从名字可以看出来uri是资源的唯一标识,而url是资源的定位 url是uri的一种

死锁

restful 规范

梯度下降优化算法的概览

原文链接

Gradient Descent Variants

主要有3种梯度下降,分别是Batch Gradient Descent, SGD, Mini-Batch Gradient Desceng

Batch Gradient Descent

\[ \theta = \theta - \eta \cdot \nabla_\theta J( \theta) \]

其中: \(\theta\) :参数 \(\eta\) :学习率(步长) \(J()\) :误差方程

参数 = 参数 - 学习率 * 参数变化率

for i in range(num_epochs):
params_grad = evaluate_gradient(loss_function, datas, params)
params = params - learning_rate * params_grad

SGD (Stochastic Gradient Descent)

每个样本训练时候都更新参数

for i in range(num_epochs):
np.random.shuffle(datas)
for example in datas:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad

Mini-Batch Gradient Descent

每个小的训练集更新参数

for i in range(num_epochs):
np.random.shuffle(datas)
for mini_batch in get_batches(datas, batch_size=50):
params_grad = evaluate_gradient(loss_function, mini_batch, params)
params = params - learning_rage * params_grad

Algorithms

梯度下降的一些优化算法,就是更新梯度下降过程中更新参数的算法。

Momentum

普通的算法的缺点是计算梯度和更新参数完全依靠当前batch的数据,这样容易使得梯度很不稳定,并且容易陷入局部最优(local optima) 于是Momentum引入物理中惯性的概念, 计算梯度时候一定程度上依赖之前的轨迹

\[ \begin{align} \begin{split} v_t &= \gamma v_{t-1} + \eta \nabla_\theta J( \theta) \\ \theta &= \theta - v_t \end{split} \end{align} \]

其中 \(\gamma\) 一般被设置为0.9

NAG(Nesterov Accelerated Gradient)

Momentum方法比喻为物理中的惯性,小球滚下坡。但是我们希望小球更加的聪明,能够预知什么地方该减速什么地方该加速,在上坡之前就开始减速。Momentum中我们对 \(\theta\) 求导,这里我们对 \(\theta - \eta v_{t-1}\) 求导

$$ \[\begin{align} \begin{split} v_t = \gamma v_{t-1} + \eta \nabla_\theta J(\theta - \gamma v_{t-1}) \\ \theta = \theta - v_t \end{split} \end{align}\] $$

Adagrad

前面的方法中,所有的参数都同时使用同一个学习率更新,这里我们每个参数在不同的时间使用不同的学习率更新,我们设新的梯度下降目标函数 \(g_{t, i}\) 对于参数 \(\theta_i\) ,时间 t 为:

\[ g_{t, i} = \nabla_\theta J(\theta_{t,i}) \] 所以 \[ \theta_{t+1, i} = \theta_{t, i} - \eta \cdot g_{t, i} \] 最后: \[ \theta_{t+1, i} = \theta_{t, i} - \dfrac{\eta}{\sqrt{G_{t, ii} + \epsilon}} \cdot g_{t, i} \]

其中 \(G_{t, ii} \in \mathbb{R}^{i \times i}\) 是一个对角矩阵(diagonal matrix),对角线上的值 i,i是步数, \(\epsilon\) 是用于平滑曲线的,防止分母是0,一般取值为 1e-8

出现频繁的学习率小,不频繁的学习率大,因此适合应用在分散的数据。 但是因为分母计算每个参数的平方和,所以容易出现参数爆炸

Adadelta

RMSprop

Adam

AdaMax

Nadam

AMSGrad

0%