Skip to content

Commit

Permalink
Fixed contrastive loss layer to be the same as proposed in Hadsell et…
Browse files Browse the repository at this point in the history
… al 2006
  • Loading branch information
Nick Carlevaris-Bianco committed Apr 17, 2015
1 parent f8dc62c commit 7e2fceb
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 9 deletions.
9 changes: 6 additions & 3 deletions src/caffe/layers/contrastive_loss_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ void ContrastiveLossLayer<Dtype>::Forward_cpu(
if (static_cast<int>(bottom[2]->cpu_data()[i])) { // similar pairs
loss += dist_sq_.cpu_data()[i];
} else { // dissimilar pairs
loss += std::max(margin-dist_sq_.cpu_data()[i], Dtype(0.0));
Dtype dist = std::max(margin - sqrt(dist_sq_.cpu_data()[i]), 0.0);
loss += dist*dist;
}
}
loss = loss / static_cast<Dtype>(bottom[0]->num()) / Dtype(2);
Expand Down Expand Up @@ -76,10 +77,12 @@ void ContrastiveLossLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
Dtype(0.0),
bout + (j*channels));
} else { // dissimilar pairs
if ((margin-dist_sq_.cpu_data()[j]) > Dtype(0.0)) {
Dtype dist = sqrt(dist_sq_.cpu_data()[j]);
Dtype mdist = (margin - dist);
if (mdist > Dtype(0.0)) {
caffe_cpu_axpby(
channels,
-alpha,
-alpha * mdist / dist,
diff_.cpu_data() + (j*channels),
Dtype(0.0),
bout + (j*channels));
Expand Down
13 changes: 8 additions & 5 deletions src/caffe/layers/contrastive_loss_layer.cu
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ void ContrastiveLossLayer<Dtype>::Forward_gpu(
if (static_cast<int>(bottom[2]->cpu_data()[i])) { // similar pairs
loss += dist_sq_.cpu_data()[i];
} else { // dissimilar pairs
loss += std::max(margin-dist_sq_.cpu_data()[i], Dtype(0.0));
Dtype dist = std::max(margin - sqrt(dist_sq_.cpu_data()[i]), Dtype(0.0));
loss += dist*dist;
}
}
loss = loss / static_cast<Dtype>(bottom[0]->num()) / Dtype(2);
top[0]->mutable_cpu_data()[0] = loss;
}

template <typename Dtype>
__global__ void CLLForward(const int count, const int channels,
__global__ void CLLBackward(const int count, const int channels,
const Dtype margin, const Dtype alpha,
const Dtype* y, const Dtype* diff, const Dtype* dist_sq,
Dtype *bottom_diff) {
Expand All @@ -54,8 +55,10 @@ __global__ void CLLForward(const int count, const int channels,
if (static_cast<int>(y[n])) { // similar pairs
bottom_diff[i] = alpha * diff[i];
} else { // dissimilar pairs
if ((margin-dist_sq[n]) > 0.0) {
bottom_diff[i] = -alpha * diff[i];
Dtype dist = sqrt(dist_sq[n]);
Dtype mdist = (margin - dist);
if (mdist > 0.0) {
bottom_diff[i] = -alpha * mdist / dist * diff[i];
} else {
bottom_diff[i] = 0;
}
Expand All @@ -75,7 +78,7 @@ void ContrastiveLossLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const Dtype alpha = sign * top[0]->cpu_diff()[0] /
static_cast<Dtype>(bottom[0]->num());
// NOLINT_NEXT_LINE(whitespace/operators)
CLLForward<Dtype><<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS>>>(
CLLBackward<Dtype><<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS>>>(
count, channels, margin, alpha,
bottom[2]->gpu_data(), // pair similarity 0 or 1
diff_.gpu_data(), // the cached eltwise difference between a and b
Expand Down
3 changes: 2 additions & 1 deletion src/caffe/test/test_contrastive_loss_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ TYPED_TEST(ContrastiveLossLayerTest, TestForward) {
if (this->blob_bottom_y_->cpu_data()[i]) { // similar pairs
loss += dist_sq;
} else {
loss += std::max(margin-dist_sq, Dtype(0));
Dtype dist = std::max(margin - sqrt(dist_sq), 0.0);
loss += dist*dist;
}
}
loss /= static_cast<Dtype>(num) * Dtype(2);
Expand Down

0 comments on commit 7e2fceb

Please sign in to comment.