softmax bug fix and net testing
authorYangqing Jia <jiayq84@gmail.com>
Fri, 27 Sep 2013 15:34:12 +0000 (08:34 -0700)
committerYangqing Jia <jiayq84@gmail.com>
Fri, 27 Sep 2013 15:34:12 +0000 (08:34 -0700)
src/caffe/layers/softmax_layer.cpp
src/caffe/net.cpp
src/caffe/test/test_net_proto.cpp

index ead05b3094b2929f3d5d27d85a695b694b94237b..7e8bbd1d8d28d35710b10a419d28bdba386176e5 100644 (file)
@@ -1,9 +1,10 @@
 // Copyright 2013 Yangqing Jia
 
+#include <algorithm>
+
 #include "caffe/layer.hpp"
 #include "caffe/vision_layers.hpp"
 #include "caffe/util/math_functions.hpp"
-#include <algorithm>
 
 using std::max;
 
@@ -34,11 +35,15 @@ void SoftmaxLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
   int num = bottom[0]->num();
   int dim = bottom[0]->count() / bottom[0]->num();
   memcpy(top_data, bottom_data, sizeof(Dtype) * bottom[0]->count());
-  // we need to subtract the sum to avoid numerical issues, compute the exp,
+  // we need to subtract the max to avoid numerical issues, compute the exp,
   // and then normalize.
   // Compute sum
-  caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1., bottom_data,
-      sum_multiplier_.cpu_data(), 0., scale_data);
+  for (int i = 0; i < num; ++i) {
+    scale_data[i] = bottom_data[i*dim];
+    for (int j = 0; j < dim; ++j) {
+      scale_data[i] = max(scale_data[i], bottom_data[i * dim + j]);
+    }
+  }
   // subtraction
   caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, -1.,
     scale_data, sum_multiplier_.cpu_data(), 1., top_data);
index 75c9043977a9a064375c2b03e996fc1cf5cc8e74..ac9f6a9238a24c5cdad56ae061c7b2b491673eae 100644 (file)
@@ -121,7 +121,9 @@ Dtype Net<Dtype>::Backward() {
   Dtype loss = 0;
   // TODO(Yangqing): figure out those layers that do not need backward.
   for (int i = layers_.size() - 1; i >= 0; --i) {
-    loss += layers_[i]->Backward(top_vecs_[i], true, &bottom_vecs_[i]);
+    Dtype layer_loss = layers_[i]->Backward(
+        top_vecs_[i], true, &bottom_vecs_[i]);
+    loss += layer_loss;
   }
   return loss;
 }
index f53107e688ba7f952c952e2a3a124326ea0e16b9..f0b0e7d9c0d002a1a2f30e005d4b27f96c72ce4f 100644 (file)
@@ -8,6 +8,7 @@
 #include "caffe/blob.hpp"
 #include "caffe/common.hpp"
 #include "caffe/net.hpp"
+#include "caffe/filler.hpp"
 #include "caffe/proto/caffe.pb.h"
 
 #include "caffe/test/lenet.hpp"
@@ -35,6 +36,13 @@ TYPED_TEST(NetProtoTest, TestSetup) {
   // Now, initialize a network using the parameter
   shared_ptr<Blob<TypeParam> > data(new Blob<TypeParam>(10, 1, 28, 28));
   shared_ptr<Blob<TypeParam> > label(new Blob<TypeParam>(10, 1, 1, 1));
+  FillerParameter filler_param;
+  shared_ptr<Filler<TypeParam> > filler;
+  filler.reset(new ConstantFiller<TypeParam>(filler_param));
+  filler->Fill(label.get());
+  filler.reset(new GaussianFiller<TypeParam>(filler_param));
+  filler->Fill(data.get());
+
   vector<Blob<TypeParam>*> bottom_vec;
   bottom_vec.push_back(data.get());
   bottom_vec.push_back(label.get());
@@ -43,6 +51,7 @@ TYPED_TEST(NetProtoTest, TestSetup) {
   EXPECT_EQ(caffe_net.layer_names().size(), 9);
   EXPECT_EQ(caffe_net.blob_names().size(), 10);
 
+  // Print a few statistics to see if things are correct
   for (int i = 0; i < caffe_net.blobs().size(); ++i) {
     LOG(ERROR) << "Blob: " << caffe_net.blob_names()[i];
     LOG(ERROR) << "size: " << caffe_net.blobs()[i]->num() << ", "
@@ -50,6 +59,13 @@ TYPED_TEST(NetProtoTest, TestSetup) {
         << caffe_net.blobs()[i]->height() << ", "
         << caffe_net.blobs()[i]->width();
   }
+  // Run the network without training.
+  vector<Blob<TypeParam>*> top_vec;
+  LOG(ERROR) << "Performing Forward";
+  caffe_net.Forward(bottom_vec, &top_vec);
+  LOG(ERROR) << "Performing Backward";
+  LOG(ERROR) << caffe_net.Backward();
+
 }
 
 }  // namespace caffe