caffe 데이터 구조 깊이 학습 (4) - blob 데이터 구조 blob. hpp 파일 상세 해석

blob 는 caffe 의 기본 데이터 구조 입 니 다. blob. hpp 에서 이 파일 은 caffe 루트 디 렉 터 리 의 include/caffe/경로 에 있 습 니 다. 이 글 에서 저 희 는 blob. hpp 파일 을 상세 하 게 해석 하여 blob 데이터 구조 에 대해 깊 은 인식 을 가지 도록 합 니 다.
#ifndef CAFFE_BLOB_HPP_
#define CAFFE_BLOB_HPP_

#include 
#include 
#include 

#include "caffe/common.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/syncedmem.hpp"

        이 몇 줄 의 코드 는 blob. hpp 파일 의 시작 이 며, 주로 이 파일 에 포 함 된 헤더 파일 입 니 다.
const int kMaxBlobAxes = 32;

이 줄 은 int 형 변 수 를 정의 합 니 다. 이것 은 blob 의 최대 비트 를 표시 합 니 다. 오래된 버 전의 caffe 에 포 함 된 비트 는 num, channels, height, width 는 모두 네 개의 비트 이 고 새로운 버 전의 caffe 는 최대 32 개의 비트 를 지원 할 수 있 습 니 다.
namespace caffe {

이 줄 은 caff 네 임 스페이스 를 정의 합 니 다.
template 

이 줄 은 이 클래스 가 템 플 릿 클래스 이 고 D type 은 형식 이름 이 며 c++ 에서 이 방법 을 통 해 다양한 데이터 형식의 처 리 를 실현 할 수 있 음 을 나타 낸다. 예 를 들 어 D type 은 float, double 등 이다.
class Blob {
 public:
  Blob()
       : data_(), diff_(), count_(0), capacity_(0) {}

이 몇 줄 은 Blob 클래스 를 정의 하고 Blob 의 기본 구조 함 수 를 설명 합 니 다.
  explicit Blob(const int num, const int channels, const int height, const int width);
  explicit Blob(const vector& shape);

이 두 줄 은 두 개의 Blob 의 명시 적 구조 함 수 를 설명 했다. 각각 두 가지 서로 다른 데이터 유형 으로 Blob 류 를 구성 했다. 첫 번 째 함 수 는 num, channels, height, width 등 네 가지 차원 정 보 를 사용 하여 Blob 류 를 구성 하 는 것 이다. 이 는 오래된 버 전의 caffe 를 호 환 하 는 것 이 고 두 번 째 함 수 는 int 형의 벡터 shape 를 사용 하여 Blob 를 구성 하 는 것 이 며 shape 의 최대 차원 은 32 이다.
  void Reshape(const int num, const int channels, const int height, const int width);

이 줄 은 하나의 변형 함 수 를 정의 합 니 다. 그 역할 은 num, channels, height, width 라 는 네 가지 차원 정 보 를 통 해 원래 의 Blob 모양 을 바 꾸 는 것 입 니 다. 이 함 수 는 주로 오래된 버 전의 caffe 를 호 환 하 는 데 사 용 됩 니 다.
  void Reshape(const vector& shape);

이 줄 은 shape 벡터 를 통 해 Blob 의 모양 을 바 꾸 는 또 다른 변형 함 수 를 정의 합 니 다.
  void Reshape(const BlobShape& shape);

이 줄 에서 정의 하 는 변형 함 수 는 Blob 설명 파일 의 모양 정보 에 따라 변 형 된 함수 입 니 다.
  void ReshapeLike(const Blob& other);

이 줄 은 여전히 변형 함수 로 서, 이 종류의 형상 을 other 종류의 형상 과 동일 하 게 변 한다.
  inline string shape_string() const {
    ostringstream stream;
    for (int i = 0; i < shape_.size(); ++i) {
      stream << shape_[i] << " ";
    }
    stream << "(" << count_ << ")";
    return stream.str();
  }

Blob 의 모양 정 보 를 문자열 로 바 꾸 고 되 돌려 주 는 함수 로 정의 되 어 있 습 니 다.함수 에서 먼저 스 트림 출력 변 수 를 정의 한 다음 for 순환 에서 shape모든 차원 을 문자열 로 변환 하여 stream 뒤에 걸 고 마지막 으로 요소 수 countstream 뒤에 연결 하여 문자열 출력 을 만 듭 니 다.그 중, shape와 countBlob 의 멤버 변수 입 니 다. shapeBlob 모양 을 나타 내 는 벡터 입 니 다. countBlob 요소 의 수 를 나타 내 는 int 형 변수 입 니 다.caffe 에서 구성원 변 수 는 다음 과 같은 밑줄 로 끝 나 는 것 이 고 비교 번 호 는 구분 된다.
  inline const vector& shape() const { return shape_; }

이 줄 은 Blob 모양 의 함 수 를 읽 고 구성원 변수 shape 로 돌아 가 는 것 을 정의 합 니 다.
  inline int shape(int index) const {
    return shape_[CanonicalAxisIndex(index)];
  }

이 줄 에서 정의 하 는 함 수 는 특정한 차원 의 사 이 즈 를 읽 는 것 입 니 다. 함수 에서 CanonicalAxis Index () 함 수 를 호출 했 습 니 다. 차원 index 가 사용 가능 한 지 확인 하 는 역할 을 합 니 다. 아래 에 상세 한 정의 가 있 습 니 다.
  inline int num_axes() const { return shape_.size(); }

이 함 수 는 Blob 의 차원 수 를 읽 고 구성원 변수 shape 를 되 돌려 줍 니 다.라 고 적 었 다.
  inline int count() const { return count_; }

이 함 수 는 Blob 의 요소 수 를 읽 고 구성원 변수 count 를 되 돌려 줍 니 다.
  inline int count(int start_axis, int end_axis) const {
    CHECK_LE(start_axis, end_axis);
    CHECK_GE(start_axis, 0);
    CHECK_GE(end_axis, 0);
    CHECK_LE(start_axis, num_axes());
    CHECK_LE(end_axis, num_axes());
    int count = 1;
    for (int i = start_axis; i < end_axis; ++i) {
      count *= shape(i);
    }
    return count;
  }

위의 이 함 수 는 시작 차원 start 를 계산 하 는 데 사 용 됩 니 다.axis 끝 차원 endaxis 의 부분 집합 요소 수, 함수 의 앞 줄 은 차원 수가 규정 에 맞 는 지 여 부 를 검사 하 는 데 사 용 됩 니 다. 그 중에서 CHECKLE(start_axis, end_axis);startaxis 는 end 보다 작 거나 같 아야 합 니 다.axis.CHECK_LE 는 검출 함수 이 며, LE 는 검출 된 변수의 앞 변 수 는 뒤의 변수 보다 작 거나 같 아야 함 을 나타 낸다.GE 는 크 거나 같 음 을 나타 낸다.LT 는 작 다 는 뜻 이 고 GT 는 크다 는 뜻 이다.다른 몇 줄 의 독자 들 은 스스로 작용 하 는 작용 을 분석 할 수 있다.다음은 하나의 for 순환 을 통 해 요소 수 를 계산 하고 계산 방법 은 count 로 지정 한 차원 의 사 이 즈 를 곱 합 니 다.마지막 으로 원소 수 를 되 돌려 줍 니 다.
  inline int count(int start_axis) const {
    return count(start_axis, num_axes());
  }

이 함 수 는 계산 시작 차원 startaxis 에서 마지막 차원 의 부분 집합 요소 수 를 첫 번 째 count 함수 로 계산 합 니 다.
  inline int CanonicalAxisIndex(int axis_index) const {
    CHECK_GE(axis_index, -num_axes())
        << "axis " << axis_index << " out of range for " << num_axes()
        << "-D Blob with shape " << shape_string();
    CHECK_LT(axis_index, num_axes())
        << "axis " << axis_index << " out of range for " << num_axes()
        << "-D Blob with shape " << shape_string();
    if (axis_index < 0) {
      return axis_index + num_axes();
    }
    return axis_index;
  }

이 함수 의 역할 은 차원 수가 규정 에 맞 는 지 확인 하 는 것 입 니 다. 오래된 버 전의 caffe 를 호 환 하기 위해 차원 색인 의 수치 범 위 는 [num axes (), num axes () 입 니 다. 이 함 수 는 먼저 판 단 된 차원 값 axis index 가 이 범위 내 에 있 는 지 판단 하고 없 으 면 종료 합 니 다. 만약 조건 이 만족 하면 axis index 를 일반 색인 [0, num axes () 로 변환 합 니 다.) 범위 내 에서 음수 의 변환 방법 은 axis index + num axes () 입 니 다. 마지막 으로 변 환 된 차원 수 를 되 돌려 줍 니 다.
  inline int num() const { return LegacyShape(0); }
  inline int channels() const { return LegacyShape(1); }
  inline int height() const { return LegacyShape(2); }
  inline int width() const { return LegacyShape(3); }

이 몇 개의 함 수 는 오래된 버 전의 num, channels, height, width 를 호 환 하 는 네 가지 차원 의 사 이 즈 를 되 돌려 줍 니 다. 함수 에서 Legacy Shape () 함 수 를 호출 하여 설명 합 니 다.
  inline int LegacyShape(int index) const {
    CHECK_LE(num_axes(), 4)
        << "Cannot use legacy accessors on Blobs with > 4 axes.";
    CHECK_LT(index, 4);
    CHECK_GE(index, -4);
    if (index >= num_axes() || index < -num_axes()) {
      return 1;
    }
    return shape(index);
  }

이 함 수 는 오래된 버 전의 특정한 차원 모양 을 되 돌려 주 는 함 수 를 지원 합 니 다. 먼저 차원 색인 index 가 규정 에 맞 는 지 판단 하고 규칙 에 따라 위의 shape 함 수 를 호출 하여 제 index 차원 의 사 이 즈 를 되 돌려 줍 니 다.
  inline int offset(const int n, const int c = 0, const int h = 0,
      const int w = 0) const {
    CHECK_GE(n, 0);
    CHECK_LE(n, num());
    CHECK_GE(channels(), 0);
    CHECK_LE(c, channels());
    CHECK_GE(height(), 0);
    CHECK_LE(h, height());
    CHECK_GE(width(), 0);
    CHECK_LE(w, width());
    return ((n * channels() + c) * height() + h) * width() + w;
  }

이 함 수 는 Blob 의 메모리 에 있 는 요소 의 오프셋 값 을 되 돌려 주 는 역할 을 합 니 다. Blob 의 데 이 터 는 다 차원 배열 이지 만 데 이 터 는 메모리 에 순서대로 배열 되 어 있 습 니 다. 이 함 수 는 num, channels, height, width 라 는 네 가지 차원 의 값 을 입력 하여 [n] [c] [h] [w] 위치 에 있 는 요소 의 오프셋 으로 출력 합 니 다.
  inline int offset(const vector& indices) const {
    CHECK_LE(indices.size(), num_axes());
    int offset = 0;
    for (int i = 0; i < num_axes(); ++i) {
      offset *= shape(i);
      if (indices.size() > i) {
        CHECK_GE(indices[i], 0);
        CHECK_LT(indices[i], shape(i));
        offset += indices[i];
      }
    }
    return offset;
  }

위의 코드 는 다른 offset 함 수 를 정의 합 니 다. 입력 은 indices 벡터 이 고 indices 에는 각 차원 의 색인 값 이 포함 되 어 있 습 니 다.
  void CopyFrom(const Blob& source, bool copy_diff = false,
      bool reshape = false);

이 함수 의 역할 은 source 대상 에서 현재 클래스 로 데 이 터 를 복사 하 는 것 입 니 다. copy diff 플래그 위 치 는 data 를 복사 할 지, diff 를 복사 할 지 지정 합 니 다. reshape 플래그 위 치 는 Blob 모양 을 변경 할 수 있 는 지 여 부 를 지정 합 니 다.
  inline Dtype data_at(const int n, const int c, const int h,
      const int w) const {
    return cpu_data()[offset(n, c, h, w)];
  }

이 함수 의 역할 은 num, channels, height, width 네 차원 의 n, c, h, w 색인 에 있 는 data 요소 값 을 되 돌려 주 는 것 입 니 다. offset 함 수 를 호출 하여 메모리 에 있 는 data 값 을 되 돌려 줍 니 다.
  inline Dtype diff_at(const int n, const int c, const int h,
      const int w) const {
    return cpu_diff()[offset(n, c, h, w)];
  }

이 함수 의 역할 은 num, channels, height, width 네 차원 의 n, c, h, w 색인 에 있 는 diff 요소 값 을 되 돌려 주 는 것 입 니 다. offset 함 수 를 호출 하여 메모리 에 있 는 diff 값 을 되 돌려 줍 니 다.
  inline Dtype data_at(const vector& index) const {
    return cpu_data()[offset(index)];
  }

이 함수 의 역할 은 위의 첫 번 째 data at () 함수 와 유사 합 니 다. 메모리 에 있 는 data 요소 값 을 되 돌려 줍 니 다. 색인 으로 입력 한 벡터 에 불과 합 니 다.
  inline Dtype diff_at(const vector& index) const {
    return cpu_diff()[offset(index)];
  }

이 함 수 는 이전 함수 와 유사 하 며, 색인 의 벡터 를 통 해 메모리 의 diff 값 을 되 돌려 줍 니 다.
  inline const shared_ptr& data() const {
    CHECK(data_);
    return data_;
  }

위의 함 수 는 메모리 에 있 는 data 의 주 소 를 되 돌려 주 는 데 사 용 됩 니 다. 그 중에서 Synced Memory 는 CPU 와 GPU 의 데 이 터 를 동기 화 하 는 클래스 입 니 다. caffe 루트 디 렉 터 리 에 있 는 include/caffe/syncedmem. hpp 파일 에서 정 의 됩 니 다. 관심 이 있 으 면 이 파일 이 Synced Memory 의 역할 에 대해 연구 할 수 있 습 니 다.
  inline const shared_ptr& diff() const {
    CHECK(diff_);
    return diff_;
  }

위의 함 수 는 메모리 의 diff 주 소 를 되 돌려 주 는 데 사 용 됩 니 다.
  const Dtype* cpu_data() const;

이 줄 은 cpu 의 data 주 소 를 되 돌려 주 는 함 수 를 설명 합 니 다. cpu data 에 대한 접근 은 읽 기 전용 모드 입 니 다.
  void set_cpu_data(Dtype* data);

이 줄 에서 설명 하 는 함수 의 역할 은 cpu data 를 설정 하고 데이터 원본 은 data 입 니 다.
  const int* gpu_shape() const;

이 줄 의 역할 은 gpu shape 로 돌아 가 는 함 수 를 설명 하 는 것 입 니 다.
  const Dtype* gpu_data() const;

이 줄 의 역할 은 gpu data 의 주 소 를 되 돌려 주 는 것 입 니 다. 접근 방식 은 읽 기 전용 입 니 다.
  void set_gpu_data(Dtype* data);

이 줄 에서 설명 하 는 함수 의 역할 은 gpu data 를 설정 하고 데이터 원본 은 data 입 니 다.
  const Dtype* cpu_diff() const;

이 줄 의 역할 은 cpu diff 의 주 소 를 되 돌려 주 는 것 입 니 다. 접근 방식 은 읽 기 전용 입 니 다.
  const Dtype* gpu_diff() const;

이 줄 의 역할 은 gpu diff 의 주 소 를 되 돌려 주 는 것 입 니 다. 접근 방식 은 읽 기 전용 입 니 다.
  Dtype* mutable_cpu_data();
  Dtype* mutable_gpu_data();
  Dtype* mutable_cpu_diff();
  Dtype* mutable_gpu_diff();

이 네 줄 은 cpu data, gpu data, cpu diff, gpu diff 네 가지 데 이 터 를 읽 기와 쓰기 로 접근 하 는 함수 입 니 다.
  void Update();

Blob 의 업데이트 함 수 는 data 와 diff 의 대응 요 소 를 계산 하 는 역할 을 합 니 다.
  void FromProto(const BlobProto& proto, bool reshape = true);

위의 이 함수 의 역할 은 BlobProto 에서 Blob 에서 이 클래스 로 읽 어 내 는 것 입 니 다.
  void ToProto(BlobProto* proto, bool write_diff = false) const;

이 종 류 를 BlobProto 에 기록 합 니 다.
  Dtype asum_data() const;
  Dtype asum_diff() const;

이 두 함수 의 작용 은 data 와 diff 에 있 는 원소 의 절대 값 의 합 (L1 범 수) 을 계산 하 는 것 이다.
  Dtype sumsq_data() const;
  Dtype sumsq_diff() const;

이 두 함수 의 작용 은 data 와 diff 의 원소 의 제곱 합 (L2 범 수) 을 계산 하 는 것 이다.
  void scale_data(Dtype scale_factor);
  void scale_diff(Dtype scale_factor);

이 두 함수 의 역할 은 data 와 diff 의 각 요 소 를 하나의 스칼라 계수 로 곱 하 는 것 이다.
  void ShareData(const Blob& other);
  void ShareDiff(const Blob& other);

이 두 함수 의 역할 은 다른 Blob 의 data 와 diff 를 공유 하 는 것 입 니 다.
  bool ShapeEquals(const BlobProto& other);

이 함수 의 역할 은 이 종류의 Blob 와 other 의 모양 이 같 는 지 판단 하 는 것 입 니 다.
 protected:
  shared_ptr data_;
  shared_ptr diff_;
  shared_ptr shape_data_;
  vector shape_;
  int count_;
  int capacity_;

  DISABLE_COPY_AND_ASSIGN(Blob);
};  // class Blob

}  // namespace caffe

이 코드 들 은 blob. hpp 의 마지막 부분 으로 Blob 의 몇몇 구성원 변 수 를 정의 합 니 다. data 는 data 의 메모리 주소 이 고, diff 는 diff 의 메모리 주소 이 며, shape data 는 shape 데이터 의 주소 이 며, shape 는 shape 의 벡터 이 며, count 는 Blob 의 요소 수 입 니 다. capacity 는 blob 의 용량 정보 입 니 다. DISABLE COPY AND ASSIGN (Blob); 복사 구조 함수, 할당 연산 자 를 다시 불 러 오지 않 음 을 표시 합 니 다.
        이로써 우 리 는 blob. hpp 파일 의 해석 을 완성 했다.

좋은 웹페이지 즐겨찾기