-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
98 lines (68 loc) · 39.5 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[caffe 层次结构]]></title>
<url>%2F2017%2F01%2F13%2F2017-1-4%20caffe%20%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84%2F</url>
<content type="text"><![CDATA[Caffe从四个层次来理解:Blob,Layer,Net,Solver。 BlobCaffe的基本数据结构,用四维矩阵Batch\*Channel\*Height\*Width表示,存储了包括神经元的激活值、参数、以及相应的梯度(dW,db)。其中包含有cpu_data、gpu_data、cpu_diff、gpu_diff、 mutable_cpu_data、mutable_gpu_data、mutable_cpu_diff、mutable_gpu_diff这一堆很像的东西,分别表示存储在CPU和GPU上的数据(印象中二者的值好像是会自动同步成一致的)。其中带data的里面存储的是激活值和W、b,diff中存储的是残差和dW、db。另外带mutable和不带mutable的一对指针所指的位置是相同的,只是不带mutable的只读,而带mutable的可写。 for more details Layer代表神经网络的层,由各种各样的层来构成整个网络。一般一个图像或样本会从数据层中读进来,然后一层一层的往后传。除了数据层比较特殊之外,其余大部分层都包含4个函数:LayerSetUp、Reshape、 Forward、Backward。其中LayerSetup用于初始化层,开辟空间,填充初始值什么的。Reshape是对输入值进行维度变换,比如pooling接全连接层的时候要先拉成一个向量再计算。Forward是前向传播,Backward是后向传播。 那么数据是如何在层之间传递的呢?每一层都会有一个(或多个)Bottom和top,分别存储输入和输出,比如bottom[0]->cpu_data()存输入的神经元激活值,换成top存输出的,换成cpu_diff()存的是激活值的残差,换成gpu是存在GPU上的数据,再带上mutable就可写了,这些是神经元激活值相关的,如果这个层前后有多个输入输出层,就会有bottom[1],比如accuracy_layer就有两个输入,fc8和label。而每层的参数会存在this->blobs_里,一般this->blobs_[0]存W,this->blobs_[1]存b,this->blobs_[0]->cpu_data()存的是W的值,this->blobs_[0]->cpu_diff()存的梯度dW,b和db也类似,然后换成gpu是存在GPU上的数据,再带上mutable就可写了。 for more details Net Net就是把各种层按train_val.prototxt的定义堆叠在一起,首先进行每个层的初始化,然后不断进行Update,每更新一次就进行一次整体的前向传播和反向传播,然后把每层计算得到的梯度计算进去,完成一次更新,这里注意每层在Backward中只是计算dW和db,而W和b的更新是在Net的Update里最后一起更新的。而且在caffe里训练模型的时候一般会有两个Net,一个train一个test。刚开始训练网络时前面的一大堆输出,网络的结构什么的也都是这里输出的。 Solver Solver是按solver.prototxt的参数定义对Net进行训练,首先会初始化一个TrainNet和一个TestNet,然后其中的Step函数会对网络不断进行迭代,主要就是两个步骤反复迭代: ① 不断利用ComputeUpdateValue计算迭代相关参数,比如计算learning rate,把weight decay加上什么的 ② 调用Net的Update函数对整个网络进行更新。迭代中的一大堆输出也是在这里输出的,比如当前的loss和learning rate什么的。]]></content>
</entry>
<entry>
<title><![CDATA[tensorflow执行流程]]></title>
<url>%2F2017%2F01%2F04%2F2017-1-4tensorflow%E7%AE%80%E4%BB%8B%2F</url>
<content type="text"><![CDATA[计算图在TensorFlow中,算法都被表示成计算图(computational graphs)。计算图也叫数据流图,可以把计算图看做是一种有向图,图中的节点表示操作,图中的边代表在不同操作之间的数据流动。 数据流图如图所示,左边的图表示z=x+y。从图中可以看到,x、y、 z是图中的三个节点,x和y分别有一个箭头指到z,在z节点的下方有一个+号,表明是一个加法操作,因此最后的输出结果就是z=x+y。右图是一种相对复杂点的情况,随着计算图逐步分析可以得到 y^=σ(xTw+b)。在这样的数据流图中,有四个主要的元素: 操作(operations) 张量(tensors) 变量(variables) 会话(sessions) 操作把算法表示成一个个操作的叠加,可以非常清晰地看到数据之间的关系,而且这样的基本操作也具有普遍性。在TensorFlow中,当数据流过操作节点的时候就可以对数据进行操作。一个操作可以有零个或多个输入,产生零个或多个输出。一个操作可能是一次数学计算,一个变量或常量,一个数据流走向控制,一次文件IO或者是一次网络通信。其中,一个常量可以看做是没有输入,只有一个固定输出的操作。具体操作如下所示: 操作类型 例子 元素运算 Add,Mul 矩阵运算 MatMul,MatrixInverse 数值产生 Constant,Variable 神经网络单元 SoftMax,ReLU,Conv2D I/O Save,Restore 每一种操作都需要相对应的底层计算支持,比如在GPU上使用就需要实现在GPU上的操作符,在CPU上使用就要实现在CPU上的操作符。 张量在计算图中,每个边就代表数据从一个操作流到另一个操作。这些数据被表示为张量,一个张量可以看做是多维的数组或者高维的矩阵。关于TensorFlow中的张量,需要注意的是张量本身并没有保存任何值,张量仅仅提供了访问数值的一个接口,可以看做是数值的一种引用。在TensorFlow实际使用中我们也可以发现,在run之前的张量并没有分配空间,此时的张量仅仅表示了一种数值的抽象,用来连接不同的节点,表示数据在不同操作之间的流动。TensorFlow中还提供了SparseTensor数据结构,用来表示稀疏张量。 变量变量是计算图中可以改变的节点。比如当计算权重的时候,随着迭代的进行,每次权重的值会发生相应的变化,这样的值就可以当做变量。在实际处理时,一般把需要训练的值指定为变量。在使用变量的时候,需要指定变量的初始值,变量的大小和数据类型就是根据初始值来推断的。在构建计算图的时候,指定一个变量实际上需要增加三个节点: 实际的变量节点 一个产生初始值的操作,通常是一个常量节点 一个初始化操作,把初始值赋予到变量变量如图所示,v代表的是实际的变量,i是产生初始值的节点,上面的assign节点将初始值赋予变量,assign操作以后,产生已经初始化的变量值v’。 会话在TensorFlow中,所有操作都必须在会话(session)中执行,会话负责分配和管理各种资源。在会话中提供了一个run方法,可以用它来执行计算图整体或者其中的一部分节点。在进行run的时候,还需要用feed_dict把相关数据输入到计算图。当run被调用的时候,TensorFlow将会从指定的输出节点开始,向前查找所有的依赖界节点,所有依赖节点都将被执行。这些操作随后将被分配到物理执行单元上(比如CPU或GPU),这种分配规则由TensorFlow中的分配算法决定。 执行在执行的时候,TensorFlow支持两种方式:一种是单机版本,可以在单机上支持多个计算设备,还有一种是分布式版本,支持多机多设备。在TensorFlow刚出来的时候,只支持第一种方式,后来开源了分布式版本。 执行当client发出run请求时,master会将这个请求分配到不同的worker上,这些worker负责监控具体的计算设备。计算设备所有的计算任务最终都将分配到实际的硬件上执行。除了CPU和GPU之外,TensorFlow也支持自定义硬件,比如谷歌自己使用的TPU(Tensor Processing Unit)。一个worker需要管理多个设备,所以这些设备的名称需要加上worker的名字,比如 /cpu:0 表示第一个CPU。 任务分配算法如何将某个计算节点分配到具体设备上,TensorFlow提供了分配算法(placement algorithm)。分配算法首先模拟计算图的执行,从输入节点到输出节点进行遍历,在遍历过程中遇到节点v,需要决定将这个节点分配到设备D={d1,…,dn}中的某一个设备上,具体分配将使用一个成本模型Cv(d)。这个成本模型需要考虑四个方面的信息来决定最优的执行设备\( \overline {d}=\arg \min {d\varepsilon D}C{v}\left( d\right) \) 该设备是否实现了这个操作,比如某个操作不能在GPU上实现,那么所有的GPU成本都为无穷大 估计节点的输入和输出数据大小 在设备上执行时间 如果输入的数据在另一个设备上,还需要考虑数据在不同设备间传输的成本 跨设备执行如果用户系统有多个设备,任务分配算法就需要将节点分配到不同的设备上,在这个分配过程中,可能会出现一个设备中的输入依赖于另一个设备上的输出。此时就需要设备之间交叉执行。 交叉执行如图所示,设备A上有节点ν,设备B上有节点α和β,其中ν的输出是α和β的输入。在计算图中,ν→α和ν→β就需要跨设备执行。此时,TensorFlow将会自动在适当位置增加send和recv节点,在节点ν后面增加一个send节点,在α和β前面增加recv节点,send和recv节点之间使用额外的边进行链接。当数据流过这两个节点的时候就需要进行设备间通信,设备间通信方式包括TCP和RDMA等方式。此外,TensorFlow还会对recv节点进行进一步的优化,可以将设备B上的两个recv节点进行合并,减少通信次数,如图(c)所示。 优化在编译的时候,TensorFlow还会进行一些优化以提高性能。 子图消除在程序中,常常有一些重复的操作,可以把这些操作进行合并。可以将反复进行计算的同一个子图进行合并,保存其中的一个输出,在其他地方只需要直接调用就可以了。 调度优化节点的执行越晚越好,这样的话,这个节点只在内存中保留较短的时间,可以有效降低内存的使用量。合理调度也能降低send和recv节点的网络冲突。 精度优化许多机器学习算法不需要高的浮点精度,比如float32,只需要16位精度就够了,因此可以将32位精度降低为16位精度。当需要转换成32位精度时,只需要将尾部直接补0即可。 反向传播的计算图在神经网络训练中,需要使用到反向传播算法。在TensorFlow等深度学习框架中,梯度计算都是自动进行的,不需要人工进行梯度计算,这样只需要使用者定义网络的结构,其他工作都由深度学习框架自动完成,大大简化了算法验证。在TensorFlow中,梯度计算也是采用了计算图的结构。 梯度计算如图,在神经网络中常常需要对权重w进行求导。这样的函数前向计算的式子为:$$ z=h\left( x\right) ,y=g\left( x\right) ,x=f\left( w\right) $$整合一下就可以得到:$$ z=h\left( g\left( f\left( w\right) \right) $$使用链式求导法则,可以得到$$ \dfrac {dz} {dw}=\dfrac {dz} {dy}\times \dfrac {dy} {dx}\times \cdot \dfrac {dx} {dw} $$在计算图中,每个节点边上会自动增加梯度节点,然后每个梯度节点与前一个梯度节点相乘,最终在右下角可以得到\(\dfrac {dz} {dw} \)的值。 reference:http://blog.csdn.net/tinyzhao/article/details/52755647]]></content>
</entry>
<entry>
<title><![CDATA[caffe fc层源码注释]]></title>
<url>%2F2016%2F12%2F30%2F2016-12-30%2017caffe_inner_prod%2F</url>
<content type="text"><![CDATA[基本原理note : 注意理解反向传播过程中,修改的对象是bottom, 这一点与前向相反,前向修改的topbackpropgatation矩阵乘法函数 成员变量123456protected: int M_;//样本数量 int K_;//单个输入特征长度 int N_;//输出神经元数量 bool bias_term_;//是否添加偏置,上图中的(+1)。 Blob<Dtype> bias_multiplier_;//偏置的乘子 成员函数其中的构造等成员函数基本上继承父类的,子类中无需实现,但是layersetup必须自己实现,主要包括了LayerSetUp,Forward_cpu,Backward_cpu,Reshape这四个成员函数 LayerSetUp完成FC层变量初始化,从网络配置文件train_val.prototxt提取对应参数初始值完成fc层初始化。如输出维度、权重、偏置等1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950template <typename Dtype>void InnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // 从prototxt读取对应参数 const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); transpose_ = this->layer_param_.inner_product_param().transpose(); // 输出维度 N_ = num_output; // blob的CanonicalAxisIndex是为了标准化维度索引的输入,将一些非法维度输入转化为合法输入。 const int axis = bottom[0]->CanonicalAxisIndex( this->layer_param_.inner_product_param().axis()); // blob的count(int)是统计从某个维度开始,到结尾的总个数。这里第一个维度表示的是样本个数 // 也即是M_,与全连接层是独立的,其后面的是表示输入特征的个数。 // 如果输入图像的维度是(N, C, H, W),则K_ = C * H * W K_ = bottom[0]->count(axis); // 检查是否需要设置权重,如果已经初始化则直接跳过 if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weights vector<int> weight_shape(2); if (transpose_) { weight_shape[0] = K_; weight_shape[1] = N_; } else { weight_shape[0] = N_; weight_shape[1] = K_; } this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // 梯度计算标志位,fc需要计梯度(即需要被BP)的有哪些blob,这里设置所有的blob都要计算梯度 this->param_propagate_down_.resize(this->blobs_.size(), true);} Reshape调整输出层的size1234567891011121314151617181920212223242526template <typename Dtype>void InnerProductLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // Figure out the dimensions const int axis = bottom[0]->CanonicalAxisIndex( this->layer_param_.inner_product_param().axis()); const int new_K = bottom[0]->count(axis); CHECK_EQ(K_, new_K) << "Input size incompatible with inner product parameters."; // The first "axis" dimensions are independent inner products; the total // number of these is M_, the product over these dimensions. M_ = bottom[0]->count(0, axis); // The top shape will be the bottom shape with the flattened axes dropped, // and replaced by a single axis with dimension num_output (N_). vector<int> top_shape = bottom[0]->shape(); top_shape.resize(axis + 1); top_shape[axis] = N_; top[0]->Reshape(top_shape); // Set up the bias multiplier if (bias_term_) { vector<int> bias_shape(1, M_); bias_multiplier_.Reshape(bias_shape); // caffe_set(const int N, const Dtype alpha, Dtype* Y) 是用alpha的值来填充重Y开始的N个单元。 caffe_set(M_, Dtype(1), bias_multiplier_.mutable_cpu_data()); }} Forward_cpu12345678910111213141516171819202122232425262728293031template <typename Dtype> //实现的功能就是 y=wx+b // x为输入,维度 M_*K_ // y为输出,维度 M_*N_ // w为权重,维度 K_*N_ // b为偏置,维度 N_*1_ //一批次处理多个样本,在每一批次中权重矩阵与偏置矩阵是不变的 void InnerProductLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); const Dtype* weight = this->blobs_[0]->cpu_data(); //内存中的权重矩阵是N*K // bottom_data为M*K矩阵,权重为K*N矩阵,top_data为M*N矩阵 // top_data = bottom_data * weight //它的功能其实很直观,即C←αA×B+βC,前两个参数控制A,B是否转置 //其中A维度是MxK,B维度是KxN,C维度为MxN //全连接层的forward包括了两步: //这一步表示 y←wx,或者说是y←xw' //bottom_data:M*K, weight:N*K, top_data:M*N caffe_cpu_gemm<Dtype>(CblasNoTrans, transpose_ ? CblasNoTrans : CblasTrans, M_, N_, K_, (Dtype)1., bottom_data, weight, (Dtype)0., top_data); // 如果包含有偏置项 if (bias_term_) { // top_data += bias_multiplier * bias caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, M_, N_, 1, (Dtype)1., bias_multiplier_.cpu_data(), this->blobs_[1]->cpu_data(), (Dtype)1., top_data); } // 因此两步合并的结果就是 top_data = bottom_data * weight + bias_multiplier * bias } Backward_cpu反向传播主要是为了更新W和b,其中的关键就是计算偏导,因此在这个函数中主要就是做了这三件事。计算diff(W),diff(b),\deta(残差)。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960template <typename Dtype> void InnerProductLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { // Gradient with respect to weight //更新W //其中A维度是NxM,B维度是MxK,C维度为NxK //top_diff:M*N, bottom_data:M*K, this->blobs_[0]->mutable_cpu_diff():N*K //C=A'*B,this->blobs_[0]->mutable_cpu_diff()是权重梯度矩阵(N*K) if (this->param_propagate_down_[0]) { const Dtype* top_diff = top[0]->cpu_diff(); const Dtype* bottom_data = bottom[0]->cpu_data(); //data传递的是数据,diff传递的是梯度,top_diff的维度是N*M,每一列代表一个样本的error term // 求权重的偏导,weight_diff += top_diff * bottom_data if (transpose_) { caffe_cpu_gemm<Dtype>(CblasTrans, CblasNoTrans, K_, N_, M_, (Dtype)1., bottom_data, top_diff, (Dtype)1., this->blobs_[0]->mutable_cpu_diff()); } else { caffe_cpu_gemm<Dtype>(CblasTrans, CblasNoTrans, N_, K_, M_, (Dtype)1., top_diff, bottom_data, (Dtype)1., this->blobs_[0]->mutable_cpu_diff()); } } // 求偏置项的偏导,bias_diff += top_diff * bias_multiplier if (bias_term_ && this->param_propagate_down_[1]) { const Dtype* top_diff = top[0]->cpu_diff(); // Gradient with respect to bias caffe_cpu_gemv<Dtype>(CblasTrans, M_, N_, (Dtype)1., top_diff, bias_multiplier_.cpu_data(), (Dtype)1., this->blobs_[1]->mutable_cpu_diff()); } if (propagate_down[0]) { const Dtype* top_diff = top[0]->cpu_diff(); // 求bottom数据的偏导,bottom_data_diff = top_diff * weight if (transpose_) { caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasTrans, M_, K_, N_, (Dtype)1., top_diff, this->blobs_[0]->cpu_data(), (Dtype)0., bottom[0]->mutable_cpu_diff()); } else { caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, M_, K_, N_, (Dtype)1., top_diff, this->blobs_[0]->cpu_data(), (Dtype)0., bottom[0]->mutable_cpu_diff()); } } } // 如果CPU_ONLY模式则禁止Forward_gpu和Backward_gpu函数 #ifdef CPU_ONLY STUB_GPU(InnerProductLayer); #endif // 注册fclayerINSTANTIATE_CLASS(InnerProductLayer);REGISTER_LAYER_CLASS(InnerProduct);} // namespace caffe]]></content>
</entry>
<entry>
<title><![CDATA[tensorflow custom learning rate decay]]></title>
<url>%2F2016%2F12%2F26%2F2016-12-26tensorflow%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AD%A6%E4%B9%A0%E7%8E%87%E4%B8%8B%E9%99%8D%2F</url>
<content type="text"><![CDATA[基本原理通过传递一个常量tensor lr给optimizer 123456789101112131415161718192021222324252627282930# import related modulefrom tensorflow.python.framework import constant_opfrom tensorflow.python.framework import opsfrom tensorflow.python.ops import control_flow_opsfrom tensorflow.python.ops import math_ops# implementation of inv decay in caffe base_lr*(1+gamm*itear)^(-power)def inv_decay(learning_rate, global_step, gamma, power, name=None): if global_step is None: raise ValueError("global_step is required for inv_decay.") with ops.name_scope(name, "InvDecay", [learning_rate, global_step, gamma, power]) as name: learning_rate = ops.convert_to_tensor(learning_rate, name="learning_rate") dtype = learning_rate.dtype global_step = math_ops.cast(global_step, dtype) gamma = math_ops.cast(gamma, dtype) power = math_ops.cast(power, dtype) base = math_ops.multiply(gamma, global_step) return math_ops.multiply(learning_rate, math_ops.pow(1+base, -power), name=name)lr = inv_decay(learning_rate=0.0005, global_step=get_global_step_var()-2800000, gamma=0.0001, power=0.75)tf.summary.scalar('lr', lr)optimizer=tf.train.GradientDescentOptimizer(lr)]]></content>
</entry>
<entry>
<title><![CDATA[atom本地安装插件]]></title>
<url>%2F2016%2F11%2F25%2F2016-11-25-atmo%E6%9C%AC%E5%9C%B0%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6%2F</url>
<content type="text"><![CDATA[Atom 是专门为程序员推出的一个跨平台文本编辑器。具有简洁和直观的图形用户界面,并有很多有趣的特点:支持CSS,HTML,JavaScript等网页编程语言。它支持宏,自动完成分屏功能,集成了文件管理器。更稳重要的它具有很好的扩展性。由于有时候是网络原因会导致在线安装插件失败。 12345cd ~/.atom/packages# 比如:git clone git@github.com:shd101wyy/markdown-preview-enhanced.gitgit clone <你想安装的 Package 的仓库链接>cd <Package 路径> # cd markdown-preview-enhancednpm install # 或者 apm install 重启AtomDone!]]></content>
</entry>
<entry>
<title><![CDATA[my markdown template]]></title>
<url>%2F2016%2F11%2F25%2Ftemplate%2F</url>
<content type="text"><![CDATA[公式通过采用mathjax引擎,可以支持tex格式的公式显示。具体的采用 https://webdemo.myscript.com/views/math.html#/demo/equation 最后,我们在一个图片类别的evidence中加入偏置(bias),加入偏置的目的是加入一些与输入独立无关的信息。所以图片类别的evidence为 $$ evidence_{i}=\sum _{j}W_{ij}x_{j}+b_{i} $$ 其中,\( W_i \) 和 \( b_i \) 分别为类别 \( i \) 的权值和偏置。 Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Create a new post1$ hexo new "My New Post" test How many lives do we live? How many times do we die?]]></content>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<url>%2F2016%2F11%2F25%2Fhello-world%2F</url>
<content type="text"><![CDATA[Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick Start1$ hexo g -d Create a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment]]></content>
</entry>
<entry>
<title><![CDATA[深度学习模型压缩方法简介]]></title>
<url>%2F2016%2F11%2F24%2F2016-11-24-%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E6%A8%A1%E5%9E%8B%E5%8E%8B%E7%BC%A9%E6%96%B9%E6%B3%95%E7%AE%80%E4%BB%8B%2F</url>
<content type="text"><![CDATA[Shallow networkCompressing pre-trained deep networkDesigning compact layersQuantizing parametersNetwork binarization]]></content>
</entry>
<entry>
<title><![CDATA[超分重建简介]]></title>
<url>%2F2016%2F11%2F23%2F2016-11-23-%E8%B6%85%E5%88%86%E9%87%8D%E5%BB%BA%E7%AE%80%E4%BB%8B%2F</url>
<content type="text"><![CDATA[超分辨率重建简介1. 引言 图像超分辨率重建技术就是利用一组低质量、低分辨率图像(或运动序列)来产生单幅高质量、高分辨率图像。图像超分辨率重建应用领域及其宽广,在军事,医学,公共安全,计算机视觉等方面都存在着重要的应用前景。在计算机视觉领域,图像超分辨率重建技术有可能使图像实现从检出水平(detection level)向识别水平(recognition level)的转化,或更进一步实现向细辨水平(identification level)的转化。图像超分辨率重建技术可以提高图像的识别能力和识别精度。图像超分辨率重建技术可以实现目标物的专注分析,从而可以获取感兴趣区域更高空间分辨率的图像,而不必直接采用数据量巨大的高空间分辨率图像的配置。 目前超分辨率技术主要有以下两大类:基于重建的方法、 基于学习的方法 2. 基于重建的方法 基于重建的超分辨率方法的基础是均衡及非均衡采样定理。它假设低分辨率的输入采样信号(图像) 能很好地预估出原始的高分辨率信号(图像)。绝大多数超分辨率算法都属于这一类,其中主要包括频域法和空域法。 频率域方法是图像超分辨率重建中一类重要方法,其中最主要的是消混叠重建方法。消混叠重建方法是通过解混叠而改善图像的空间分辨率实现超分辨率复原,最早的研究工作是由 Tsai 和 Huang在 1984 年进行的。在原始场景信号带宽有限的假设下,利用离散傅立叶变换和连续傅立叶变换之间的平移、混叠性质,给出了一个由一系列欠采样观察图像数据复原高分辨率图像的公式。多幅观察图像经混频而得到的离散傅立叶变换系数与未知场景的连续傅立叶变换系数以方程组的形式联系起来,方程组的解就是原始图像的频率域系数,再对频率域系数进行傅立叶逆变换就可以实现原始图像的准确复原。 在空域类方法中,其线性空域观测模型涉及全局和局部运动、光学模糊、帧内运动模糊、空间可变点扩散函数、非理想采样等内容。空域方法具有很强的包含空域先验约束的能力,主要包括非均匀空间样本内插、迭代反投影方法、凸集投影法、最大后验概率以及混合 MAP/ POCS 方法、最优和自适应滤波方法、确定性重建方法等。 3. 基于学习的方法 基于学习的方法是近年来超分辨率算法研究中的热点,它采用大量的高分辨率图像构造学习库产生学习模型,在对低分辨率图像进行恢复的过程中引入由学习模型获得的先验知识,以得到图像的高频细节,获得较好的图像恢复效果。 具体步骤为: 将高分辨率图像按照降质模型进行降质,产生训练集。 根据高分辨率图像的低频部分和高频部分对应关系对图像分块,通过一定算法进行学习,获得先验知识,建立学习模型。 以输入的低分辨率块为依据,在建立好的训练集中搜索最匹配的高频块。 基于学习的超分辨率方法中关键是建立学习模型,获得先验知识。常用的学习模型有马尔科夫随机场模型、图像金字塔模型、神经网络模型、主成分分析模型等。基于学习的方法充分利用了图像本身的先验知识,在不增加输入图像样本数量的情况下仍能产生高频细节,获得比基于重建方法更好的复原结果,并能较好的应用于人脸和文字等图像的复原。 4. 研究前景目前,图像超分辨率重建的研究比较成熟,但距离实用还有较大差距。未来研究方向主要集中在以下几个方面: 发展和寻求新的退化模型,使成像模型更加精确和全面,实现对点扩散函数和噪声的精确估计。图像超分辨率增强的成功依赖于准确的、符合实际成像系统特性和成像条件的降模型,而要获得符合实际成像过程的降质模型是十分困难的,通常采用简单、确定的降质模型进行近似,这样的近似模型与实际成像过程差距较大。 压缩域的超分辨率重建。传统的超分辨率算法都是针对图像序列,而实际中最常见的图像序列是视频文件。因而下一步的工作可以针对不同的视频压缩格式和编解码技术,在超分辨率算法中综合考虑成像模型和压缩算法带来的图像降质效果,以及运动补偿和编码传输机制,实现压缩域的超分辨率重建。 效率和鲁棒性问题。目前的超分辨率算法具有很高的计算复杂度,如何减少计算量,提高算法速度,是下一步值得研究问题。同时,在目前很多算法中都做了各种假设,如照度变等,这在实际应用中是很难满足的,因此需要研究稳健的算法满足实际应用的需要。 模糊图像和三维图像的超分辨率研究。模糊一直是图像处理中的一个难点,如何对模糊图像进行超分辨率需要进一步研究。目前针对三维图像的超分辨率研究还很少,如何对三维图像进行建模也是一个值得研究的课题。 超分辨率客观评价标准研究。目前对于图像超分辨率结果主要依靠人的主观评价,缺少一种客观的评价标准,现有的 PSNR、MSE 等并不能很好的反映超分辨率效果,需要发展一种客观的评价机制。6. 5. 超分图像质量评估方式主观评价方法主观评价主要是由人在感性认识上从主观感觉和统计结果的角度对图像质量做出相应的判定,主要的方法是目视判读。人类视觉系统被认为是最精密的光学成像系统,通过人眼接收物体的反射光在大脑中成像,然后由大脑根据储存的经验知识进行分析得到结论,这个过程所需时间很短。因此主观评价方法具有直观、简单的优点。 客观的评价方式目视判读的优点是操作简单、效率高,可以有效剔除一些质量差的影像,避免无谓的工作,但是这种判定会因为观察人员的素质、经验、水平的不同以及外部环境的影响而产生较大的差异,因此需要有易于掌控和科学支持的定量评价方法。客观评价方法主要就是采用定量的评价指标对影像做定量分析,由此获取对图像质量好坏的判定。 按照对参考图像的需求,可将客观评价方法分为三类,分别为:无参考、部分参考和完全参考图像质量评价。 图像质量评价离不开视觉评价,主观评价方法可以从配准、影像的整体亮度、色彩、反差、清晰度、影像内纹理、地物边缘、是否有蒙雾或马赛克等现象出现等方面做出判定,直观地得到图像在空间分解力、清晰度等方面的差异。但是这种方法的主观性比较强,人的视觉对影像上的各种变化并不都很敏感,图像的视觉质量强烈地取决于观察者,具有主观性、不全面性全面客观视频质量评价方法是指把原始参考视频与失真视频在每一个对应帧中的每一个对应像素之问进行比较。准确的讲,这种方法得到的并不是真正的视频质量,而是失真视频相对于原始视频的相似程度或保真程度。最简单的方法如均方误差MSE和峰值信噪比PSNR,其应用比较广泛。 均方误差 MSE(Mean Square Error) 其中,fij,f’ij分别代表原始参考视频对应帧和失真视频对应帧,M,N分别表示视频帧的高和宽. 峰值信噪比 PSNR(Peak Signal to Noise Ratio) PSNR本质上与MSE相同,是MSE的对数表示。PSNR是最普遍,最广泛使用的评鉴画质的客观量测法,不过许多实验结果都显示,PSNR的分数无法和人眼看到的视觉品质完全一致,有可能PSNR较高者看起来反而比PSNR较低者差。这是因为人眼的视觉对于误差的敏感度并不是绝对的,其感知结果会受到许多因素的影响而产生变化(例如:人眼对空间频率较低的对比差异敏感度较高,人眼对亮度对比差异的敏感度较色度高,人眼对一个区域的感知结果会受到其周围邻近区域的影响. 结构相似性度量 SSIM (Structural Similarity Index) SSIM模型旨在比较参考和受损信号的结构信息,研究感知结构的损伤,而不是感知误差。上节中基于HVS的模型,采用自底向上的方法,模拟人类视觉系统中每个与质量感知相关的器官的功能,然后将每个部分联结起来实现评价模型,而SSIM是一种自顶向下的方法,模拟的是HVS整体的功能. Reference简介 各种质量评估方法 常见超分图像评估指标 开源评估工具]]></content>
</entry>
<entry>
<title><![CDATA[Linux文件批量操作]]></title>
<url>%2F2016%2F11%2F23%2F2016-11-23-Linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E6%89%B9%E9%87%8F%E6%93%8D%E4%BD%9C%2F</url>
<content type="text"><![CDATA[批量递归重命名文件后缀名:1find . -maxdepth 2 -name "*.jpg" | rename "s/.jpg/.jpeg/" 批量压缩子文件夹: 1234567#!/bin/bash#run under the root dirdirList=`ls -p $1 |grep / |tr -d /`for dir in $dirListdo tar -czvf $dir.zip $dir/done 批量删除指定名字的文件: 1find . -maxdepth 2 -name "bing*" -exec rm -f {} \; 批量修改图片尺寸 1find ./ -name '*.jpg' -exec convert -resize 600x480 {} {} \; Windows Linux 显示某个文件下收文件的全路径 123dir /B /S D:\000books\*.jpg > namelist.txtfind /000books -name "*.*"> namelist 从路径 string 中提取文件夹名字作为lable 1234line = "E:\005OCRCNNAcceleration\OCR\result7_merge_bak\0000\P8_001_train1_P2.jpg";string res = line.substr(0, line.find_last_of('\\'));string lab = res.substr(res.find_last_of('\\')+1);label = atoi(lab.c_str()); 从txt中随机抽样,抽取部分行 12#sort随机排序,然后取前500,实现出来就是随机抽取500. 重定向到val_sample.txtsort -R val.txt | head -500 > val_sample.txt 9. 12]]></content>
</entry>
<entry>
<title><![CDATA[对于finetune的理解]]></title>
<url>%2F2016%2F11%2F23%2F2016-11-23-%E5%AF%B9%E4%BA%8EFinetune%E7%9A%84%E7%90%86%E8%A7%A3%2F</url>
<content type="text"><![CDATA[Finetune问题 大家好,一直很困惑caffe在做fine-tuning时,有两个问题: 如果将imagenet训练得到的网络最后的softmax层的输出由1000改为20,那么用自己的数据进行训练后,之前net中的卷积层,全连接层的参数是否会发生更新? 假设fine-tune时网络参数发生变化,我不想让某些特定层的参数在fine-tuning的时候发生变化,是否可以将这些层的学习率置0? 1234作者:朱坚升链接:http://www.zhihu.com/question/35754716/answer/66561128来源:知乎著作权归作者所有,转载请联系作者获得授权。 解释Finetune过程 会更新,finetune的过程相当于继续训练,跟直接训练的区别是初始化的时候: 直接训练是按照网络定义指定的方式初始化(如高斯随机初始化) finetune是用你已经有的参数文件来初始化(就是之前训练好的caffemodel) 这个问题有两种情况:比如有4个全连接层A->B->C->D 你希望C层的参数不会改变,C前面的AB层的参数也不会改变,这种情况也就是D层的梯度不往前反向传播到D层的输入blob(也就是C层的输出blob 没有得到梯度),你可以通过设置D层的propagate_down为false来做到。propagate_down的数量与输入blob的数量相同,假如你某个层有2个输入blob,那么你应该在该layer的Param里面写上两行: 12propagate_down : 0 # 第1个输入blob不会得到反向传播的梯度propagate_down : 0 # 第2个输入blob不会得到反向传播的梯度 这样的话,你这个layer的梯度就不会反向传播啦,前面的所有layer的参数也就不会改变了 你希望C层的参数不会改变,但是C前面的AB层的参数会改变,这种情况,只是固定了C层的参数,C层得到的梯度依然会反向传播给前面的B层。只需要将对应的参数blob的学习率调整为0:你在layer里面加上param { lr_mult: 0 }就可以了,比如全连接层里面: 123456789layer {type: "InnerProduct"param { # 对应第1个参数blob的配置,也就是全连接层的参数矩阵的配置lr_mult: 0 # 学习率为0,其他参数可以看caffe.proto里面的ParamSpec这个类型}param { # 对应第2个参数blob的配置,也就是全连接层的偏置项的配置lr_mult: 0 # 学习率为0}}]]></content>
</entry>
<entry>
<title><![CDATA[OCR更换56947数据集测试报告]]></title>
<url>%2F2016%2F10%2F12%2F2016-10-13-OCR%E6%9B%B4%E6%8D%A2%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%E6%B5%8B%E8%AF%95%E6%8A%A5%E5%91%8A%2F</url>
<content type="text"><![CDATA[0. 测试方法0.1 **PLDA** :通过SDK提取不同CNNs(Caffenet、Googlenet)网络指定层输出作为特征,然后用plda对特征进行训练、分类。统计结果以**单字识别率**为指标。 0.2 **SSL**(structure Sparse Learning): 基于Alexnet训练得到的模型,基于上述模型SSL的模型,基于SSL模型finetune得到的调整模型 1. 模型选用1.1 Caffenet(conv5_bn) + PLDA 1.2 Alexnet 1.3 Alexnet + SSL 1.4 Alexent + SSL + ft 2. PLDA特征选取层1.1 conv5_bn 3. 数据集 3.1 train_set_1 : 共6955类(包含汉字、数字、字母) 3.2 train_set_2 : 共600类(包含部分汉字、数字、字母)用于训练PLDA模型,如果使用全部的6955类训练PLDA模型数据量过大,内存和时间消耗较大,在单机上效率很低。 3.3 test: 从2481张身份证上分割得到,包含了地址、姓名两个大类别(日期和身份证号没有包含在内,但是地址包含了部分数字)共有56947个测试样本 4. 测试结果4.1 结果Baseline1train_val_64_fintune_20160127_,单字识别率: 98.40%;姓名识别率:96.57%.200万次.----姓名+数字 模型 特征选取层 单字识别率 训练数据集 caffenet conv5_bn 86.65% train_set_2 Alexnet fc 95.56% train_set_1 Alexnet+SSL fc 92.96% train_set_1 Alexnet+SSL+ft fc 95.10% train_set_1 123graph LRAlexnet-->Alexnet+SSLAlexnet+SSL-->Alexnet+SSL+ft 注: 1231. 用于测试的Alexnet模型是通过简化过fc层的alexnet网络训练得到2. Alexnet+SSL基于Alexnet加入结构稀疏得到的模型3. Alexnet+SSL+ft是通过ALexnet+SSL模型经过finetune(微调学习率得到的测试结果) 4.2 top5 accuracy and time consumeAlexnet Alexnet+SSL Alexnet+SSL+ft]]></content>
</entry>
<entry>
<title><![CDATA[21 grams]]></title>
<url>%2F2016%2F08%2F15%2F2016-11-23-21%20grams%2F</url>
<content type="text"><![CDATA[How many lives do we live? How many times do we die? They say we lose 21grams at the exact moment of our death. Everyone. And how much fits into 21grams? How much is lost? When do we lose 21 grams? How much goes with them? How much is gained? Twenty-one grams. The weight of a stack of five nickels. The weight of a hummingbird. A chocolate bar. How much did 21 grams weigh?]]></content>
</entry>
</search>