namespace caffeine {
template <typename Dtype>
-void Blob<Dtype>::Reshape(const int num, const int height,
- const int width, const int channels) {
+void Blob<Dtype>::Reshape(const int num, const int channels, const int height,
+ const int width) {
CHECK_GT(num, 0);
+ CHECK_GT(channels, 0);
CHECK_GT(height, 0);
CHECK_GT(width, 0);
- CHECK_GT(channels, 0);
num_ = num;
+ channels_ = channels;
height_ = height;
width_ = width;
- channels_ = channels;
- count_ = num_ * height_ * width_ * channels_;
+ count_ = num_ * channels_ * height_ * width_;
data_.reset(new SyncedMemory(count_ * sizeof(Dtype)));
diff_.reset(new SyncedMemory(count_ * sizeof(Dtype)));
}
template <typename Dtype>
-Blob<Dtype>::Blob(const int num, const int height,
- const int width, const int channels) {
- Reshape(num, height, width, channels);
+Blob<Dtype>::Blob(const int num, const int channels, const int height,
+ const int width) {
+ Reshape(num, channels, height, width);
}
template <typename Dtype>
if (source.count() == 0) {
Blob();
} else {
- Reshape(source.num(), source.height(), source.width(), source.count());
+ Reshape(source.num(), source.channels(), source.height(), source.width());
// create the synced memories.
data_.reset(new SyncedMemory(count_ * sizeof(Dtype)));
diff_.reset(new SyncedMemory(count_ * sizeof(Dtype)));
template <typename Dtype>
void Blob<Dtype>::FromProto(const BlobProto& proto) {
- Reshape(proto.num(), proto.height(), proto.width(), proto.channels());
+ Reshape(proto.num(), proto.channels(), proto.height(), proto.width());
// copy data
Dtype* data_vec = mutable_cpu_data();
for (int i = 0; i < count_; ++i) {
template <typename Dtype>
void Blob<Dtype>::ToProto(BlobProto* proto) {
proto->set_num(num_);
+ proto->set_channels(channels_);
proto->set_height(height_);
proto->set_width(width_);
- proto->set_channels(channels_);
proto->clear_data();
proto->clear_diff();
const Dtype* data_vec = cpu_data();
Blob()
: num_(0), channels_(0), height_(0), width_(0), count_(0), data_(),
diff_() {};
- explicit Blob(const int num, const int height,
- const int width, const int channels);
+ explicit Blob(const int num, const int channels, const int height,
+ const int width);
Blob(const Blob<Dtype>& source);
virtual ~Blob() {};
void Reshape(const int num, const int height,
const int width, const int channels);
inline int num() const { return num_; }
+ inline int channels() const { return channels_; }
inline int height() const { return height_; }
inline int width() const { return width_; }
- inline int channels() const { return channels_; }
inline int count() const {return count_; }
const Dtype* cpu_data() const;
shared_ptr<SyncedMemory> data_;
shared_ptr<SyncedMemory> diff_;
int num_;
+ int channels_;
int height_;
int width_;
- int channels_;
int count_;
}; // class Blob
CHECK_EQ(bottom.size(), 1) << "IP Layer takes a single blob as input.";
CHECK_EQ(top->size(), 1) << "IP Layer takes a single blob as output.";
const int num_output = this->layer_param_.num_output();
- const bool gemm_last_dim = this->layer_param_.gemm_last_dim();
biasterm_ = this->layer_param_.biasterm();
// Figure out the dimensions
- if (gemm_last_dim) {
- M_ = bottom[0]->count() / bottom[0]->channels();
- K_ = bottom[0]->channels();
- N_ = num_output;
- (*top)[0]->Reshape(bottom[0]->num(), bottom[0]->height(),
- bottom[0]->width(), num_output);
- } else {
- M_ = bottom[0]->num();
- K_ = bottom[0]->count() / bottom[0]->num();
- N_ = num_output;
- (*top)[0]->Reshape(bottom[0]->num(), 1, 1, num_output);
- }
+ M_ = bottom[0]->num();
+ K_ = bottom[0]->count() / bottom[0]->num();
+ N_ = num_output;
+ (*top)[0]->Reshape(bottom[0]->num(), num_output, 1, 1);
if (biasterm_) {
this->blobs_.resize(2);
} else {
Dtype InnerProductLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down,
vector<Blob<Dtype>*>* bottom) {
- // TODO: gradient w.r.t the params
- if (propagate_down) {
- // TODO: gradient w.r.t. the bottom
- }
+ const Dtype* top_diff = top[0]->cpu_diff();
+ CHECK(false);
return Dtype(0);
}
package caffeine;
+message BlobProto {
+ optional int32 num = 1 [default = 0];
+ optional int32 height = 2 [default = 0];
+ optional int32 width = 3 [default = 0];
+ optional int32 channels = 4 [default = 0];
+ repeated float data = 5;
+ repeated float diff = 6;
+}
+
+message FillerParameter {
+ // The filler type. In default we will set it to Gaussian for easy
+ // debugging.
+ required string type = 1 [default = 'gaussian'];
+ optional float value = 2 [default = 0]; // the value in constant filler
+ optional float min = 3 [default = 0]; // the min value in uniform filler
+ optional float max = 4 [default = 1]; // the max value in uniform filler
+ optional float mean = 5 [default = 0]; // the mean value in gaussian filler
+ optional float std = 6 [default = 1]; // the std value in gaussian filler
+}
+
message LayerParameter {
required string name = 1; // the layer name
required string type = 2; // the string to specify the layer type
optional float alpha = 13 [default = 1.]; // for local response norm
optional float beta = 14 [default = 0.75]; // for local response norm
- // for innerproduct: if true, carry out inner product computation on the
- // last dim only
- optional bool gemm_last_dim = 15 [ default = false];
-}
-
-message FillerParameter {
- // The filler type. In default we will set it to Gaussian for easy
- // debugging.
- required string type = 1 [default = 'gaussian'];
- optional float value = 2 [default = 0]; // the value in constant filler
- optional float min = 3 [default = 0]; // the min value in uniform filler
- optional float max = 4 [default = 1]; // the max value in uniform filler
- optional float mean = 5 [default = 0]; // the mean value in gaussian filler
- optional float std = 6 [default = 1]; // the std value in gaussian filler
-}
-
-message BlobProto {
- optional int32 num = 1 [default = 0];
- optional int32 height = 2 [default = 0];
- optional int32 width = 3 [default = 0];
- optional int32 channels = 4 [default = 0];
- repeated float data = 5;
- repeated float diff = 6;
+ repeated BlobProto blobs = 50; // for possible data.
}
EXPECT_TRUE(this->blob_);
EXPECT_TRUE(this->blob_preshaped_);
EXPECT_EQ(this->blob_preshaped_->num(), 2);
- EXPECT_EQ(this->blob_preshaped_->height(), 3);
- EXPECT_EQ(this->blob_preshaped_->width(), 4);
- EXPECT_EQ(this->blob_preshaped_->channels(), 5);
+ EXPECT_EQ(this->blob_preshaped_->channels(), 3);
+ EXPECT_EQ(this->blob_preshaped_->height(), 4);
+ EXPECT_EQ(this->blob_preshaped_->width(), 5);
EXPECT_EQ(this->blob_preshaped_->count(), 120);
EXPECT_EQ(this->blob_->num(), 0);
EXPECT_EQ(this->blob_->channels(), 0);
TYPED_TEST(BlobSimpleTest, TestReshape) {
this->blob_->Reshape(2, 3, 4, 5);
EXPECT_EQ(this->blob_->num(), 2);
- EXPECT_EQ(this->blob_->height(), 3);
- EXPECT_EQ(this->blob_->width(), 4);
- EXPECT_EQ(this->blob_->channels(), 5);
+ EXPECT_EQ(this->blob_->channels(), 3);
+ EXPECT_EQ(this->blob_->height(), 4);
+ EXPECT_EQ(this->blob_->width(), 5);
EXPECT_EQ(this->blob_->count(), 120);
}
Blob<TypeParam> target(source);
const TypeParam* source_data = source.cpu_data();
const TypeParam* target_data = target.cpu_data();
+ EXPECT_EQ(target.num(), source.num());
+ EXPECT_EQ(target.channels(), source.channels());
+ EXPECT_EQ(target.height(), source.height());
+ EXPECT_EQ(target.width(), source.width());
+ EXPECT_EQ(target.count(), source.count());
for (int i = 0; i < source.count(); ++i) {
EXPECT_EQ(source_data[i], target_data[i]);
}
-#include <iostream>
#include <cstdlib>
+#include <cstdio>
+#include <iostream>
#include <cuda_runtime.h>
#include <glog/logging.h>
#include <gtest/gtest.h>
-using namespace std;
+namespace caffeine {
cudaDeviceProp CAFFEINE_TEST_CUDA_PROP;
+} // namespace caffeine
+
+using namespace caffeine;
+using namespace std;
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::google::InitGoogleLogging(argv[0]);
return RUN_ALL_TESTS();
}
+
#include "caffeine/filler.hpp"
#include "caffeine/vision_layers.hpp"
-extern cudaDeviceProp CAFFEINE_TEST_CUDA_PROP;
-
namespace caffeine {
+
+extern cudaDeviceProp CAFFEINE_TEST_CUDA_PROP;
template <typename Dtype>
class InnerProductLayerTest : public ::testing::Test {
EXPECT_EQ(this->blob_top_->height(), 1);
EXPECT_EQ(this->blob_top_->width(), 1);
EXPECT_EQ(this->blob_top_->channels(), 10);
- layer_param.set_gemm_last_dim(true);
- layer.reset(new InnerProductLayer<TypeParam>(layer_param));
- layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
- EXPECT_EQ(this->blob_top_->num(), 2);
- EXPECT_EQ(this->blob_top_->height(), 3);
- EXPECT_EQ(this->blob_top_->width(), 4);
- EXPECT_EQ(this->blob_top_->channels(), 10);
}
TYPED_TEST(InnerProductLayerTest, TestCPU) {
#include "caffeine/vision_layers.hpp"
#include "caffeine/test/test_gradient_check_util.hpp"
+
namespace caffeine {
+
+extern cudaDeviceProp CAFFEINE_TEST_CUDA_PROP;
template <typename Dtype>
class NeuronLayerTest : public ::testing::Test {
TYPED_TEST(NeuronLayerTest, TestDropoutGradientGPU) {
- LayerParameter layer_param;
- Caffeine::set_mode(Caffeine::GPU);
- DropoutLayer<TypeParam> layer(layer_param);
- GradientChecker<TypeParam> checker(1e-2, 1e-3);
- checker.CheckGradient(layer, this->blob_bottom_vec_, this->blob_top_vec_);
+ if (CAFFEINE_TEST_CUDA_PROP.major >= 2) {
+ LayerParameter layer_param;
+ Caffeine::set_mode(Caffeine::GPU);
+ DropoutLayer<TypeParam> layer(layer_param);
+ GradientChecker<TypeParam> checker(1e-2, 1e-3);
+ checker.CheckGradient(layer, this->blob_bottom_vec_, this->blob_top_vec_);
+ } else {
+ LOG(ERROR) << "Skipping test to spare my laptop.";
+ }
}