77
88contains
99
10- module function locally_connected2d_layer_cons (filters , kernel_size , activation ) result(res)
10+ module function locally_connected2d_layer_cons (filters , kernel_size , activation , stride ) result(res)
1111 integer , intent (in ) :: filters
1212 integer , intent (in ) :: kernel_size
1313 class(activation_function), intent (in ) :: activation
14+ integer , intent (in ) :: stride
1415 type (locally_connected2d_layer) :: res
1516
1617 res % kernel_size = kernel_size
1718 res % filters = filters
1819 res % activation_name = activation % get_name()
20+ res % stride = stride
1921 allocate (res % activation, source = activation)
2022 end function locally_connected2d_layer_cons
2123
@@ -24,8 +26,11 @@ module subroutine init(self, input_shape)
2426 integer , intent (in ) :: input_shape(:)
2527
2628 self % channels = input_shape(1 )
27- self % width = input_shape(2 ) - self % kernel_size + 1
29+ self % width = ( input_shape(2 ) - self % kernel_size) / self % stride + 1
2830
31+ if (mod (input_shape(2 ) - self % kernel_size , self % stride) /= 0 ) self % width = self % width + 1
32+
33+ ! Output of shape: filters x width
2934 allocate (self % output(self % filters, self % width))
3035 self % output = 0
3136
@@ -52,14 +57,17 @@ end subroutine init
5257 pure module subroutine forward(self, input)
5358 class(locally_connected2d_layer), intent (in out ) :: self
5459 real , intent (in ) :: input(:,:)
60+ integer :: input_width
5561 integer :: j, n
5662 integer :: iws, iwe
63+
64+ input_width = size (input, dim= 2 )
5765
5866 do j = 1 , self % width
59- iws = j
60- iwe = j + self % kernel_size - 1
67+ iws = self % stride * (j -1 ) + 1
68+ iwe = min (iws + self % kernel_size - 1 , input_width)
6169 do n = 1 , self % filters
62- self % z(n, j) = sum (self % kernel(n, j, :, : ) * input(:, iws:iwe)) + self % biases(n, j)
70+ self % z(n, j) = sum (self % kernel(n, j, :, 1 :iwe - iws +1 ) * input(:, iws:iwe)) + self % biases(n, j)
6371 end do
6472 end do
6573 self % output = self % activation % eval(self % z)
@@ -69,12 +77,15 @@ pure module subroutine backward(self, input, gradient)
6977 class(locally_connected2d_layer), intent (in out ) :: self
7078 real , intent (in ) :: input(:,:)
7179 real , intent (in ) :: gradient(:,:)
80+ integer :: input_width
7281 integer :: j, n, k
7382 integer :: iws, iwe
7483 real :: gdz(self % filters, self % width)
7584 real :: db_local(self % filters, self % width)
7685 real :: dw_local(self % filters, self % width, self % channels, self % kernel_size)
7786
87+ input_width = size (input, dim= 2 )
88+
7889 do j = 1 , self % width
7990 gdz(:, j) = gradient(:, j) * self % activation % eval_prime(self % z(:, j))
8091 end do
@@ -90,11 +101,11 @@ pure module subroutine backward(self, input, gradient)
90101
91102 do n = 1 , self % filters
92103 do j = 1 , self % width
93- iws = j
94- iwe = j + self % kernel_size - 1
104+ iws = self % stride * (j -1 ) + 1
105+ iwe = min (iws + self % kernel_size - 1 , input_width)
95106 do k = 1 , self % channels
96- dw_local(n, j, k, : ) = dw_local(n, j, k, : ) + input(k, iws:iwe) * gdz(n, j)
97- self % gradient(k, iws:iwe) = self % gradient(k, iws:iwe) + self % kernel(n, j, k, : ) * gdz(n, j)
107+ dw_local(n, j, k, 1 :iwe - iws +1 ) = dw_local(n, j, k, 1 :iwe - iws +1 ) + input(k, iws:iwe) * gdz(n, j)
108+ self % gradient(k, iws:iwe) = self % gradient(k, iws:iwe) + self % kernel(n, j, k, 1 :iwe - iws +1 ) * gdz(n, j)
98109 end do
99110 end do
100111 end do
@@ -131,5 +142,4 @@ module subroutine get_gradients_ptr(self, dw_ptr, db_ptr)
131142 db_ptr(1 :size (self % db)) = > self % db
132143 end subroutine get_gradients_ptr
133144
134-
135145end submodule nf_locally_connected2d_layer_submodule
0 commit comments