1. 程式人生 > >Caffe中的資料填充類Filler

Caffe中的資料填充類Filler

資料填充類caffe::Filler

Filler是一個數據填充類,採用特定的隨機演算法對Blob資料進行初始化.假設需要填充的變數為W. caffe提供常用的填充演算法有:
- “constant” : wij=v
- “gaussian” : wijN(0,σ2).
- “positive_unitball” : wij[0,1],s.t.ijwij=1
- “uniform” : xijU(a,b)
- “xavier” : wijU(3/n,3/n)
- “msra” : wijN(0,2σ)
- “bilinear” : wij(1

2i/c)(12j/c),WRc×c

用法:在定義一個layer的時候可以通過定義weight_filler和bias_filler類指定:

layer {
  name: "conv"
  type: "Convolution"
  bottom: "data"
  top: "conv"
  param{
    lr_mult:1
    decay_mult:1
  }
  param{
    lr_mult:2
    decay_mult:0
  }
  convolution_param {
    num_output: 512
    pad: 1
    kernel_size: 3
weight_filler{ type:"gaussian" std:0.01
} bias_filler{ type:"constant" value:0.1 } } }

例如上面個給出一個卷積層的prototxt.分別使用gaussian和constant方式來填充Wb

類的定義

類似與Layer,Filler的例項化也是通過一個FillerParameter來進行的.FillerParameter是定義在caffe.proto的一個message:

message FillerParameter {
  optional string
type = 1 [default = 'constant']; optional float value = 2 [default = 0]; optional float min = 3 [default = 0]; optional float max = 4 [default = 1]; optional float mean = 5 [default = 0]; optional float std = 6 [default = 1]; optional int32 sparse = 7 [default = -1]; enum VarianceNorm { FAN_IN = 0; FAN_OUT = 1; AVERAGE = 2; } optional VarianceNorm variance_norm = 8 [default = FAN_IN]; }

Filler基類的定義

Filler是對不同型別的Filler子類的抽象.

template <typename Dtype>
class Filler {
 public:
  explicit Filler(const FillerParameter& param) : filler_param_(param) {}
  virtual ~Filler() {}
  virtual void Fill(Blob<Dtype>* blob) = 0;
 protected:
  FillerParameter filler_param_;
};

virtual void Fill(Blob* blob) = 0; 為純虛擬函式,使得Filler不能被例項化,作為一個抽象基類.

函式GetFiller

不像Layer是通過LayerFactory來構造一個不同型別的網路層,Filler通過函式GetFiller來獲取制定型別的Filler.

Filler<Dtype>* GetFiller(const FillerParameter& param) {
  const std::string& type = param.type();
  if (type == "constant") {
    return new ConstantFiller<Dtype>(param);
  } else if (type == "gaussian") {
    return new GaussianFiller<Dtype>(param);
  } else if (type == "positive_unitball") {
    return new PositiveUnitballFiller<Dtype>(param);
  } else if (type == "uniform") {
    return new UniformFiller<Dtype>(param);
  } else if (type == "xavier") {
    return new XavierFiller<Dtype>(param);
  } else if (type == "msra") {
    return new MSRAFiller<Dtype>(param);
  } else if (type == "bilinear") {
    return new BilinearFiller<Dtype>(param);
  } else {
    CHECK(false) << "Unknown filler name: " << param.type();
  }
  return (Filler<Dtype>*)(NULL);
}

例如我們希望用”guassian”Filler來填充一個數據:

double* data;
FillerParameter filler_param;
filler_param.set_mean(1);
filler_param.set_std(10);
GaussianFiller<Dtype> filler(filler_param);
filler.Fill(data);

類ConstantFille

ConstantFille類簡單的將資料初始化為一個常數值.通常會賦予bias一個很小的正數來避免一開始有過多的啟用函式進入飽和區.

class ConstantFiller : public Filler<Dtype> {
 public:
  explicit ConstantFiller(const FillerParameter& param)
      : Filler<Dtype>(param) {}
  virtual void Fill(Blob<Dtype>* blob) {
    Dtype* data = blob->mutable_cpu_data();
    const int count = blob->count();
    const Dtype value = this->filler_param_.value();
    CHECK(count);
    for (int i = 0; i < count; ++i) {
      data[i] = value;
    }
    CHECK_EQ(this->filler_param_.sparse(), -1)
         << "Sparsity not supported by this Filler.";
  }
};

類GaussianFiller

GaussianFiller產生給定引數(mean,std)下的高斯分佈.引數sparse指定被填充的資料中需要有多少個非零資料.

class GaussianFiller : public Filler<Dtype> {
 public:
  explicit GaussianFiller(const FillerParameter& param)
      : Filler<Dtype>(param) {}
  virtual void Fill(Blob<Dtype>* blob) {
    Dtype* data = blob->mutable_cpu_data();
    CHECK(blob->count());
    // 生成高斯資料
    caffe_rng_gaussian<Dtype>(blob->count(), Dtype(this->filler_param_.mean()),
        Dtype(this->filler_param_.std()), blob->mutable_cpu_data());
    // 處理稀疏的情況
    int sparse = this->filler_param_.sparse();
    CHECK_GE(sparse, -1);
    if (sparse >= 0) {
      CHECK_GE(blob->num_axes(), 1);
      const int num_outputs = blob->shape(0);
      Dtype non_zero_probability = Dtype(sparse) / Dtype(num_outputs);
      rand_vec_.reset(new SyncedMemory(blob->count() * sizeof(int)));
      int* mask = reinterpret_cast<int*>(rand_vec_->mutable_cpu_data());
      caffe_rng_bernoulli(blob->count(), non_zero_probability, mask);
      for (int i = 0; i < blob->count(); ++i) {
        data[i] *= mask[i];
      }
    }
  }
protected:
 shared_ptr<SyncedMemory> rand_vec_;
};

類PositiveUnitballFiller

類PositiveUnitballFiller使得被填充的資料滿足一下的關係:

wij[0,1],s.t.ijwij=1
class PositiveUnitballFiller : public Filler<Dtype> {
 public:
  explicit PositiveUnitballFiller(const FillerParameter& param)
      : Filler<Dtype>(param) {}
  virtual void Fill(Blob<Dtype>* blob) {
    Dtype* data = blob->mutable_cpu_data();
    DCHECK(blob->count());
    caffe_rng_uniform<Dtype>(blob->count(), 0, 1, blob->mutable_cpu_data());
    // We expect the filler to not be called very frequently, so we will
    // just use a simple implementation
    int dim = blob->count() / blob->num();
    CHECK(dim);
    for (int i = 0; i < blob->num(); ++i) {
      Dtype sum = 0;
      for (int j = 0; j < dim; ++j) {
        sum += data[i * dim + j];
      }
      for (int j = 0; j < dim; ++j) {
        data[i * dim + j] /= sum;
      }
    }
    CHECK_EQ(this->filler_param_.sparse(), -1)
         << "Sparsity not supported by this Filler.";
  }
};

類XavierFiller

類XavierFiller同樣是使得填充的方式滿足均勻分佈U[3/n,3/n],只是均勻分佈的引數有給定的資料形狀決定.
假設待填充的引數為W的大小是(N,C,W,H).那麼fan_in=C×W\tiemsH. fan_out=N\tiemesW×H.
n的選取通過enum VarianceNorm指定:
- n=fan_in,選擇FAN_IN.
- n=fan_out,選擇FAN_OUT.

- n=(fan_in+fan_out)/2,選擇AVERAGE.

class XavierFiller : public Filler<Dtype> {
 public:
  explicit XavierFiller(const FillerParameter& param)
      : Filler<Dtype>(param) {}
  virtual void Fill(Blob<Dtype>* blob) {
    CHECK(blob->count());
    int fan_in = blob->count() / blob->num();
    int fan_out = blob->count() / blob->channels();
    Dtype n = fan_in;  // default to fan_in
    if (this->filler_param_.variance_norm() ==
        FillerParameter_VarianceNorm_AVERAGE) {
      n = (fan_in + fan_out) / Dtype(2);
    } else if (this->filler_param_.variance_norm() ==
        FillerParameter_VarianceNorm_FAN_OUT) {
      n = fan_out;
    }
    Dtype scale = sqrt(Dtype(3) / n);
    caffe_rng_uniform<Dtype>(blob->count(), -scale, scale,
        blob->mutable_cpu_data());
    CHECK_EQ(this->filler_param_.sparse(), -1)
         << "Sparsity not supported by this Filler.";
  }
};

類MSRAFiller

類MSRAFiller同樣是使得填充的方式滿足高斯分佈N(0,2/σ),只是高斯分佈的引數有給定的資料形狀決定.假設待填充的引數為W的大小是(N,C,W,H).那麼fan

相關推薦

Caffe資料填充Filler

資料填充類caffe::Filler Filler是一個數據填充類,採用特定的隨機演算法對Blob資料進行初始化.假設需要填充的變數為W. caffe提供常用的填充演算法有: - “constant” : wij=v - “gaussian” : wij∼

caffe的Net

建構函式:Net類有兩個建構函式,分別是Net(const NetParameter& param, const Net* root_net)和Net(const string& param_file, Phase phase, const Net* root

關於面對物件過程的三大架構以及資料訪問層(實體資料操作

關於面對物件過程中的三大架構以及資料訪問層(實體類、資料操作類) 面向物件開發專案三層架構: 介面層、業務邏輯層、資料訪問層 資料訪問層,分為實體類和資料訪問類 在專案的下面新增一個App_Code資料夾把所有的類放在App_Code這個資料夾下邊。

有關C++資料成員變數定義的一些想法

最近開始學習C++,以前是學C的,對C++新生的類不是很懂,最近在看一些教程,發現有的教程只是簡單的告訴你什麼是類,還有怎麼使用類,但對於類的標準啥的並沒有進行標準化的介紹。 關於C++類中成員變數的定義,一般都是推薦這樣定義: 1.類中的屬性(不是函式)最好定義標準化,並且取名字能讓其

laravel資料遷移和資料填充

laravel中的資料遷移和資料填充 標籤(空格分隔): php 生成遷移檔案兩種方式: 1 新建一個表的遷移檔案 php artisan make:migration create_students_table --create=students 2 建立模型的時候同時建立遷移檔案 php

關於安卓專案統計資料achartengine(包括餅狀圖,柱狀圖,折線圖等)的使用

       最近由於專案中需要統計資料,通過比較直觀的方式展示給使用者,所以就抽時間學習了一個統計圖的類庫achartengine,裡面包含統計中所需的餅狀圖,柱狀圖,折線圖等等,所以就拿出來給大家分享一下,希望大家相互學習,如有不足之處

ssd-caffe的annotationDatum資料結構

這篇部落格講解的非常好,我這裡只是搬運和總結 SSD目標檢測lmdb資料結構剖析 先看一張圖,完美解釋了AnnotationDatum的資料結構。   um的資料結,SSD讀取資料,需要將label和圖片封裝到一個數據結構下,這時候老版本caffe的Datum資料

java 反射的包裝與基本資料型別

寫了個執行反射方法的函式,但是卻老出問題,搗鼓了下,原來是基本資料型別出了問題, 呼叫反射中的方法時,需要知道方法的引數型別, Method getDeclaredMethod(String name, Class<?>... parameterTypes) 但是因為引數是可

機器學習的sklearn的聚資料生成器

引數的意思: n_samples: int, optional (default=100)待生成的樣本的總數。n_features: int, optional (default=2)每個樣本的特徵數。centers: int or array of shape [n_centers, n_

Flask的模型以及資料的增刪改查操作

總結: 模型類如下: class Role(db.Model): """使用者角色/身份表""" __tablename__ = "tbl_roles" # 表名 # 欄位名 型別 約束 id = db.Colum

Caffe資料轉換

1.cv2.imread()和caffe.io.loadimage的區別 https://blog.csdn.net/lovelyaiq/article/details/70254583 使用opencv和caffe的夥伴們,可能會有一個疑問,那就是對於同時讀取圖片的cv2.imread()

三層架構使用實體填充泛型集合代替DataTable解決方案(ASP.NET+C#)

用三層架構開發專案,經常會遇到如下場景:       D層負責與資料庫互動,一般是得到DataTable或DataSet物件,然後返回給B層,B層進行類似的處理來讀取資料:dt.Rows[0][“xxx”];或者dt.Rows[0][1];(強烈

Windows CaffeMNIST資料格式轉換實現

                Caffe原始碼中src/caffe/caffe/examples/mnist/convert_mnist_data.cpp提供的實現程式碼並不能直接在Windows下執行,這裡在原始碼的基礎上進行了改寫,使其可以直接在Windows 64位上直接執行,改寫程式碼如下:#inc

C#通過Type訪問資料型別資訊

C#中通過Type類可以訪問任意資料型別資訊。 1.獲取給定型別的Type引用有3種方式:    a.使用typeof運算子,如Type t = typeof(int);    b.使用GetType()方法,如int i;Type t = i.GetType();    c.使用Type類的靜態方法GetT

caffe訓練資料出現[data_layer.cpp:73] Restarting data prefetching from start. 的問題

        一開始在網上查了許多的,有人回答說是之前的一些prototxt檔案引數設定有問題,還有人說是batch_size相對於整個資料集太大的問題。         我一開始也以為這是個warning提示,會

QueryRunner實現對資料庫表資料的增刪改查以及八種結果集

update()方法實現增刪改        QueryRunner的update方法 update(Connection conn, String sql, Object… params) 能夠實現對錶中資料的增刪改,返回int型別的數值,表

CaffeLMDB介面實現多標籤資料準備及訓練

有不少部落格講Caffe多標籤輸入的問題,但總覺得講的不夠透徹,在實踐角度上沒有給出詳細的指導,所以本文力求能給出詳細的實踐過程和說明。 Caffe多標籤輸入常用的的方法有以下幾種: 1. 修改Caffe原始碼使其支援多標籤輸入,參考CSDN部落格《

Sql Server儲存過程從一個表抓取資料填充到另一張表

  set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go -- ============================================= -- Author:  <alex,,Name> -- Create

怎麼解析Json資料,然後把解析到的Json資料填充到佈局

一.首先把需要解析的Json資料如下所示: { "res_code": 0, "res_error": "", "res_body": { "Counts": 11596, "PageCount": 580,

在分類過程對連續資料劃分

分類中對連續資料的類劃分: 在 C4.5 演算法中採用二分法對連續值進行處理。 Markdown Code 對於連續的屬性 XX 假設共出現了 n 個不同的取值,將這些取值從小到大排序{x1,x2,x3,…,xn}{x1,x2,x3,…,xn},其中找一點作為劃分點 t ,則將資料