Hello from lk's World

28 Apr 2014 » std::unique_ptr & std::make_unique

今天继续来一弹,这次是比较简单的 unqiue_ptr。 用来持有 ownership 的指针。unique 顾名思义,不可以像 shared 随便来拿。

c++11 的 rvalue ref 和 move 无疑是让 unique_ptr 方便了许多,当然没有他们的时候, unqiue_ptr 也是可以被模拟出来的

不过先不管这些,直接来看新标准新代码。还是 libstdc++v3。为了简单起见,这里只说最简单的 unique_ptr,不看 数组版的 unique_ptr。

27 Apr 2014 » 简析 gcc 中 lambda 表达式的实现

昨天下午搞了 std::function, 晚上在想要不顺便把 lambda 原理大概看一下好了,顺便了解一下 gcc。于是今天下午就搞起~

prerequisite 1. c++ lambda 2. 编译基础知识

代码来源于 gcc trunk,如果图方便可以直接到 github 下一个 zip 回来,或者直接在线看。

首先 grep lambda

发现在这里有粗线。 gcc/cp/parser.c line 1965

static tree cp_parser_lambda_expression
  (cp_parser *);
static void cp_parser_lambda_introducer
  (cp_parser *, tree);
static bool cp_parser_lambda_declarator_opt
  (cp_parser *, tree);
static void cp_parser_lambda_body
  (cp_parser *, tree);

26 Apr 2014 » 简析 std::function 实现原理

本篇基于 libstdc++v3,在线代码可以到 libstdc++ 上面看,或者直接在自己机器上看(/usr/include/c++/4…..)。不做特殊说明的话,代码都是源自 bits/stl_functional.h,如果是老版本的有的代码在 functional 。当然老版本和新版本的行号是不一样的。

一元和二元的函数实现非常简单,在 bits/stl_function.h 中

  template<typename _Arg, typename _Result>
    struct unary_function
    {
      /// @c argument_type is the type of the argument
      typedef _Arg argument_type;
      /// @c result_type is the return type
      typedef _Result result_type;
    };
  /**
   * This is one of the @link functors functor base classes@endlink.
   */
  template<typename _Arg1, typename _Arg2, typename _Result>
    struct binary_function
    {
      /// @c first_argument_type is the type of the first argument
      typedef _Arg1 first_argument_type;
      /// @c second_argument_type is the type of the second argument
      typedef _Arg2 second_argument_type;
      /// @c result_type is the return type
      typedef _Result result_type;
    };

最简单的例子: algorithm 里的 plus, minus 等 functor

  template<typename _Tp>
    struct plus : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x + __y; }
    };
  /// One of the @link logical_functors Boolean operations functors@endlink.
  template<typename _Tp>
    struct logical_not : public unary_function<_Tp, bool>
    {
      bool
      operator()(const _Tp& __x) const
      { return !__x; }
    };
  /** @} */

14 Mar 2014 » CNN, from a novice view (II)

LeNet-5

上篇 blog 的结尾有说到 neogonitron 和后来 LeCun89 的 CNN 都存在一定问题。他们都用某一个 output cell 的输出作为某一个 class 的 likelihood。也就是说,对于一个训练好的网络,输入一个图片,最后 output layer 中的 cell 谁的输出大,那么这个图片就会被认为是这个 cell 的 label。

  • 就拿手写的 l,1,O, 0,o 来说,如果没有上下文语义的帮助,无论人和计算机都很难搞定。一方面是很难训练;另一方面这样输出只是字符,很难结合语义分析。试想,如果我们的 cell 是在“输入是一个圈”时激发,那么我们接下来就可以根据语义继续判断是 uppercase O,lowercase O 或者零了。

  • 对于 sigmoid unit 来说,采用这种近乎 uniform distribution 的 label 分布在 cell 上方法表现很差,特别是类多的时候。这是因为我们总是期望只有一个 cell 激发,其他全部 off。

  • 除了 accept character 之外,对于 reject non-character 来说,sigmoid 的表现并不够好。

下面是盗图自 wikipedia 的 sigmoid function。

LeNet-5 利用 Euclidean Radial Basis Function units (RBF) 组成 output layer 来避免这三个问题(其实这里是倒叙啦,原文是因为这三个原因所以采用 RBF =_=b)。

13 Mar 2014 » CNN, from a novice view

Intro

第一次听说 CNN (Convolutional Neural Network) 是在上课的时候,见人用 CNN 做的服装图像检索,效果很不错。据说都是高分辨率图片,GPU 上跑了一周 = =,似乎很厉害的样子。终于现在我也要去尝试 Deep Learning 黑魔法了,于是把学到的总结一下,也算是为 blog 做开场白。

首先,让我们回到上世纪的 70,80 年代,那时候天还是蓝的,山还是绿的,SVM 还不知道在哪的时候,作为仿生学和人工智能的儿子的神经网络正在向前发展。生物、心理学上对于神经网络的研究,对人工智能领域神经网络的发展起到了一定推动作用。

neocognitron

而 neocognitron Fukushima 这个,就是受到生物学 Hubel 上的启发。其实在 neocognitron 之前,也有用来做视觉模式识别的神经网络,比如说 neocognitron 的爸爸 cognitron。不过这些网络大多都会受到输入的位移和形变严重影响,导致模式识别的能力并不是很强。而 neocognitron 可以根据几何相似性自主学习(representation & classification),而不会被位移或者小范围扭曲影响。

neocognitron 的结构如下:

neocognitron arch

neocognitron 中有两种 cell,C-cell(complex) 和 S-cell(simple)。neocognitron 认为神经网络的每一个 module 都由一层 S-layer (由S-cell组成)和 C-layer (由C-cell组成)组成。$U_0$ 表示输入层,$U{C1}$,$U{S1}$ 等表示中间的 cell layer。