caffe blob理解


  

blob數據結構是caffe中基本的數據存儲單元,它主要存儲的數據是網絡中的中間數據變量,比如各層的輸入和輸出;代價函數關於網絡各層參數的梯度。

blob中除了存儲數據外,還有一些標記數據的參數,以下就是一些blob中的數據成員:

protected:  
  shared_ptr<SyncedMemory> data_;  
  shared_ptr<SyncedMemory> diff_;  
  shared_ptr<SyncedMemory> shape_data_;  
  vector<int> shape_;  
  int count_;  
  int capacity_

data_:表示網絡各層的輸入和輸出;

diff_:表示代價函數相對於各層參數的梯度;

shape_:是一個可變數組,shape_中主要存儲4個變量:num表示一個batch中的樣本數量,從這我們可以看出Blob的存儲是以batch為基本單位的;channels表示對應層的通道,比如卷積層有20個卷積核,channels的值就是20;height和width就表示單個數據的尺寸,可能是一副圖像的尺寸,也可能表示卷積核的尺寸,在每一層所代表的含義也不相同。

count_:表示這個Blob里已經存儲的元素的個數;

capacity_:表示這個Blob的容量;

Blob同時保存了data_和diff_,其類型為SyncedMemory的指針,注意是指針。

Blob中除了數據成員之外,也有很多用於操作數據的函數成員,下面就說幾個比較重要的:

    void Blob<Dtype>::Reshape():這個函數是在原來分配的內存不夠的情況下重新分配內存。

    const Dtype* Blob<Dtype>::cpu_data():這個是獲取Blob結構體中的data_數據的指針,同時限制不能對返回的指針指向的內容進行更改。

    const Dtype* Blob<Dtype>::cpu_diff():這個是獲取Blob結構體中的diff_數據的指針,同時限制不能對返回的指針指向的內容進行更改。

    Dtype* Blob<Dtype>::mutable_cpu_data():獲取Blob結構體中的data_數據的指針,同時可以對指針指向的內容更改。

    Dtype* Blob<Dtype>::mutable_cpu_diff():獲取Blob結構體中的diff_數據的指針,同時可以對指針指向的內容更改。

    void Blob<Dtype>::ShareData(const Blob& other):讓其他Blob的data_數據和當前Blob共享。

    void Blob<Dtype>::ShareDiff(const Blob& other):讓其他Blob的diff_和當前的Blob共享。   

在blob.hpp中還有這樣幾個定義:

按照注釋的意思,這幾個函數和shape()是一樣的作用。shape本身是一個vector,這個vector的size為4,第一個位置存儲圖片的個數,第二個存儲channel的個數,以此類推。

 

邏輯上看,blob是一個四維數組。但實際上,因為數組的存儲是在內存中開辟一塊連續的、大小相同的的空間,所以blob的存儲應該是一個一維的存儲結構。只不過是利用四個參數來進行尋址(shape_里的四個參數)。並且blob是行優先的存儲方式。

所以對於一個(n, k, h, w)的blob,他的維度就是n*k*h*w,在(n, k, h, w)位置的值物理位置為((n * K + k) * H + h) * W + w。

以Blob中二維矩陣為例(如全連接網絡shape (N, D)),如圖所示。同樣的存儲方式可以推廣到多維。

 

 

動態多維數組:Blob 類可以動態改變數組的尺寸,當拓展數組導致原有內存空間不足以存放下數據時 (count > capacity),就會重新分配內存。Blob 提供了一組 Reshape 函數來完成這個功能。

void Reshape(const int num, const int channels, const int height, const int width); // Deprecated void Reshape(const vector<int>& shape); void Reshape(const BlobShape& shape); void ReshapeLike(const Blob& other); 

 Blob 類在初始化時並沒有分配內存,也是通過調用 Reshape 來分配內存的。

template <typename Dtype>
void Blob<Dtype>::Reshape(const vector<int>& shape) {
  CHECK_LE(shape.size(), kMaxBlobAxes); // 檢查維數
  count_ = 1; // 用於計算新的多維數組的大小
  shape_.resize(shape.size()); // 更新維數
  if (!shape_data_ || shape_data_->size() < shape.size() * sizeof(int)) {
    // shape_data_ 未初始化或者內存太小
    shape_data_.reset(new SyncedMemory(shape.size() * sizeof(int)));
  }
  int* shape_data = static_cast<int*>(shape_data_->mutable_cpu_data());
  for (int i = 0; i < shape.size(); ++i) {
    CHECK_GE(shape[i], 0);
    CHECK_LE(shape[i], INT_MAX / count_) << "blob size exceeds INT_MAX";
    count_ *= shape[i];
    shape_[i] = shape[i];
    shape_data[i] = shape[i];
  }
  if (count_ > capacity_) {
    // 內存不夠
    capacity_ = count_;
    data_.reset(new SyncedMemory(capacity_ * sizeof(Dtype)));
    diff_.reset(new SyncedMemory(capacity_ * sizeof(Dtype)));
  }
}

 

 

 

http://blog.csdn.net/qq_14975217/article/details/51524042

http://blog.csdn.net/mounty_fsc/article/details/51085654

http://blog.csdn.net/buyi_shizi/article/details/51506853

 http://blog.csdn.net/jyl1999xxxx/article/details/53981813


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM