#include #include #include #include "caffe/common.hpp" #include "caffe/layer.hpp" #include "caffe/syncedmem.hpp" #include "caffe/util/math_functions.hpp" #include "caffe/vision_layers.hpp" namespace caffe { template __global__ void DropoutForward(const int n, const Dtype* in, const unsigned int* mask, const unsigned int threshold, const float scale, Dtype* out) { CUDA_KERNEL_LOOP(index, n) { out[index] = in[index] * (mask[index] > threshold) * scale; } } template void DropoutLayer::Forward_gpu(const vector*>& bottom, vector*>* top) { const Dtype* bottom_data = bottom[0]->gpu_data(); Dtype* top_data = (*top)[0]->mutable_gpu_data(); const int count = bottom[0]->count(); if (Caffe::phase() == Caffe::TRAIN) { unsigned int* mask = static_cast(rand_vec_.mutable_gpu_data()); caffe_gpu_rng_uniform(count, mask); // set thresholds // NOLINT_NEXT_LINE(whitespace/operators) DropoutForward<<>>( count, bottom_data, mask, uint_thres_, scale_, top_data); CUDA_POST_KERNEL_CHECK; } else { caffe_copy(count, bottom_data, top_data); } } template __global__ void DropoutBackward(const int n, const Dtype* in_diff, const unsigned int* mask, const unsigned int threshold, const float scale, Dtype* out_diff) { CUDA_KERNEL_LOOP(index, n) { out_diff[index] = in_diff[index] * scale * (mask[index] > threshold); } } template void DropoutLayer::Backward_gpu(const vector*>& top, const vector& propagate_down, vector*>* bottom) { if (propagate_down[0]) { const Dtype* top_diff = top[0]->gpu_diff(); Dtype* bottom_diff = (*bottom)[0]->mutable_gpu_diff(); if (Caffe::phase() == Caffe::TRAIN) { const unsigned int* mask = static_cast(rand_vec_.gpu_data()); const int count = (*bottom)[0]->count(); // NOLINT_NEXT_LINE(whitespace/operators) DropoutBackward<<>>( count, top_diff, mask, uint_thres_, scale_, bottom_diff); CUDA_POST_KERNEL_CHECK; } else { caffe_copy(top[0]->count(), top_diff, bottom_diff); } } } INSTANTIATE_CLASS(DropoutLayer); } // namespace caffe