-
Notifications
You must be signed in to change notification settings - Fork 91
Dropout layer #194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Dropout layer #194
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
e40883b
First stab at dropout; conflict with base type TODO
milancurcic 37aa7a5
Partial dropout integration
milancurcic 820b081
Test uninitialized dropout layer
milancurcic 75ef184
Test dropout state that follows an input layer
milancurcic 796ae74
Enable forward pass for dropout; backward pass TODO
milancurcic b04d447
Version bump and add dropout to the features table
milancurcic 544b23a
Add dropout to CMake
milancurcic 56dbd52
Enable preprocessing in fpm.toml (needed with recent versions of fpm)
milancurcic 3b5cc27
Small change in scale implementation
milancurcic 703f802
Integration of backward pass for dropout
milancurcic 1dfe6b3
Reduce tolerance in conv2d convergence tests
milancurcic 59cc7e1
Fix bug in dropout scaling
milancurcic c984b15
disable dropout in inference mode (net % predict); TODO enable in net…
milancurcic e9772a0
Set dropout's training mode to true in net % train(); add tests
milancurcic 5ae7e9d
WIP dropout tests
milancurcic d323175
Merge main
milancurcic 0934f7f
Dropout layers always in training mode; except when is called, when …
milancurcic 0f64044
Update the layers table
milancurcic 53b9663
Resolve merge conflicts
milancurcic aa19f69
Ensure the actual dropout rate == requested dropout rate in most cases
milancurcic a99d800
Accumulate the gradient in dropout % backward and flush in network % …
milancurcic ea0012a
Guard against bad dropout rate
milancurcic 0350c7d
Connect the backward pass; expand tests
milancurcic 183e82f
Expand tests
milancurcic 6c07cd7
Use the reference scaling in dropout; don't accumulate gradients beca…
milancurcic a904c6e
Add dropout to MNIST example; small model changes
milancurcic 35671dd
Add reference
milancurcic 31ebd69
Update print_info dropout
1cd9e2c
Update print_info
8961f75
Compute scale once in dropout constructor
milancurcic ee7fdc9
dropout % backward() doesn't need input from the previous layer
milancurcic be06f51
Merge pull request #3 from jvdp1/dropout
milancurcic a542e7c
Merge branch 'dropout' of github.com:milancurcic/neural-fortran into …
milancurcic a272634
Timing info of dropout
milancurcic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
module nf_dropout_layer | ||
|
||
!! Dropout layer by Srivastava et al. (2014). | ||
!! | ||
!! Srivastava, N., Hinton, G., Krizhevsky, A., Sutskever, I. and | ||
!! Salakhutdinov, R., 2014. Dropout: a simple way to prevent neural networks | ||
!! from overfitting. The Journal of Machine Learning Research, 16(1), | ||
!! pp.1929-1958. | ||
|
||
use nf_base_layer, only: base_layer | ||
|
||
implicit none | ||
|
||
private | ||
public :: dropout_layer | ||
|
||
type, extends(base_layer) :: dropout_layer | ||
!! Concrete implementation of a dropout layer type | ||
|
||
integer :: input_size = 0 | ||
|
||
real, allocatable :: output(:) | ||
real, allocatable :: gradient(:) | ||
real, allocatable :: mask(:) ! binary mask for dropout | ||
|
||
real :: dropout_rate ! probability of dropping a neuron | ||
real :: scale ! scale factor to preserve the input sum | ||
logical :: training = .true. ! set to .false. for inference | ||
|
||
contains | ||
|
||
procedure :: backward | ||
procedure :: forward | ||
procedure :: init | ||
|
||
end type dropout_layer | ||
|
||
interface dropout_layer | ||
module function dropout_layer_cons(rate) & | ||
result(res) | ||
!! This function returns the `dropout_layer` instance. | ||
real, intent(in) :: rate | ||
!! Dropout rate | ||
type(dropout_layer) :: res | ||
!! dropout_layer instance | ||
end function dropout_layer_cons | ||
end interface dropout_layer | ||
|
||
interface | ||
|
||
pure module subroutine backward(self, gradient) | ||
!! Apply the backward gradient descent pass. | ||
!! Only weight and bias gradients are updated in this subroutine, | ||
!! while the weights and biases themselves are untouched. | ||
class(dropout_layer), intent(in out) :: self | ||
!! Dropout layer instance | ||
real, intent(in) :: gradient(:) | ||
!! Gradient from the next layer | ||
end subroutine backward | ||
|
||
module subroutine forward(self, input) | ||
!! Propagate forward the layer. | ||
!! Calling this subroutine updates the values of a few data components | ||
!! of `dropout_layer` that are needed for the backward pass. | ||
class(dropout_layer), intent(in out) :: self | ||
!! Dense layer instance | ||
real, intent(in) :: input(:) | ||
!! Input from the previous layer | ||
end subroutine forward | ||
|
||
module subroutine init(self, input_shape) | ||
!! Initialize the layer data structures. | ||
!! | ||
!! This is a deferred procedure from the `base_layer` abstract type. | ||
class(dropout_layer), intent(in out) :: self | ||
!! Dropout layer instance | ||
integer, intent(in) :: input_shape(:) | ||
!! Shape of the input layer | ||
end subroutine init | ||
|
||
end interface | ||
|
||
end module nf_dropout_layer |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
submodule (nf_dropout_layer) nf_dropout_layer_submodule | ||
use nf_random, only: shuffle | ||
!! This submodule implements the procedures defined in the | ||
!! nf_dropout_layer module. | ||
|
||
contains | ||
|
||
module function dropout_layer_cons(rate) result(res) | ||
real, intent(in) :: rate | ||
type(dropout_layer) :: res | ||
res % dropout_rate = rate | ||
res % scale = 1 / (1 - rate) | ||
end function dropout_layer_cons | ||
|
||
|
||
module subroutine init(self, input_shape) | ||
class(dropout_layer), intent(in out) :: self | ||
integer, intent(in) :: input_shape(:) | ||
|
||
self % input_size = input_shape(1) | ||
|
||
! Allocate arrays | ||
allocate(self % output(self % input_size)) | ||
allocate(self % gradient(self % input_size)) | ||
allocate(self % mask(self % input_size)) | ||
|
||
! Initialize arrays | ||
self % output = 0 | ||
self % gradient = 0 | ||
self % mask = 1 ! Default mask is all ones (no dropout) | ||
|
||
end subroutine init | ||
|
||
|
||
module subroutine forward(self, input) | ||
class(dropout_layer), intent(in out) :: self | ||
real, intent(in) :: input(:) | ||
|
||
! Generate random mask for dropout, training mode only | ||
if (self % training) then | ||
|
||
! Set the first dropout_rate number of elements to 0, the rest to 1, | ||
! and shuffle. Note that the selection of the elements rounds down to | ||
! the nearest integer, so in cases where size(input) * dropout_rate is | ||
! not an integer, the actual dropout rate will be slightly lower. | ||
self % mask = 1 | ||
self % mask(:int(size(self % mask) * self % dropout_rate)) = 0 | ||
call shuffle(self % mask) | ||
|
||
! Apply dropout mask | ||
self % output = input * self % mask * self % scale | ||
|
||
else | ||
! In inference mode, we don't apply dropout; simply pass through the input | ||
self % output = input | ||
|
||
end if | ||
|
||
end subroutine forward | ||
|
||
|
||
pure module subroutine backward(self, gradient) | ||
class(dropout_layer), intent(in out) :: self | ||
real, intent(in) :: gradient(:) | ||
self % gradient = gradient * self % mask * self % scale | ||
end subroutine backward | ||
|
||
end submodule nf_dropout_layer_submodule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.