1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#[macro_export]
macro_rules! impl_ilayer_common {
() => {
fn exact_num_output_blobs(&self) -> Option<usize> {
Some(1)
}
fn exact_num_input_blobs(&self) -> Option<usize> {
Some(1)
}
};
}
pub use self::convolution::{Convolution, ConvolutionConfig};
pub use self::dropout::{Dropout, DropoutConfig};
pub use self::linear::{Linear, LinearConfig};
pub use self::log_softmax::LogSoftmax;
pub use self::pooling::{Pooling, PoolingConfig, PoolingMode};
pub use self::rnn::{Rnn, RnnConfig};
pub use self::softmax::Softmax;
pub mod convolution;
pub mod dropout;
pub mod linear;
pub mod log_softmax;
pub mod pooling;
pub mod rnn;
pub mod softmax;
pub trait FilterLayer {
fn calculate_spatial_output_dims(
input_dims: &[usize],
filter_dims: &[usize],
padding: &[usize],
stride: &[usize],
) -> Vec<usize> {
let mut output_dims = Vec::with_capacity(input_dims.len());
for (i, _) in input_dims.iter().enumerate() {
output_dims.push(((input_dims[i] + (2 * padding[i]) - filter_dims[i]) / stride[i]) + 1);
}
output_dims
}
fn calculate_output_shape(&self, input_shape: &[usize]) -> Vec<usize>;
fn num_spatial_dims(&self, input_shape: &[usize]) -> usize;
fn spatial_filter_dims(&self, num_spatial_dims: usize) -> Vec<usize> {
let mut spatial_dims = Vec::with_capacity(num_spatial_dims);
let filter_shape = self.filter_shape();
if filter_shape.len() == 1 {
for i in 0..num_spatial_dims {
spatial_dims.push(filter_shape[0]);
}
} else if filter_shape.len() == num_spatial_dims {
panic!("unimplemented: You can not yet specify one filter dimension per spatial dimension");
} else {
panic!(
"Must either specify one filter_shape or one filter_shape per spatial dimension. Supplied {:?}",
filter_shape.len()
);
}
spatial_dims
}
fn stride_dims(&self, num_spatial_dims: usize) -> Vec<usize> {
let mut stride_dims = Vec::with_capacity(num_spatial_dims);
let stride = self.stride();
if stride.len() == 1 {
for i in 0..num_spatial_dims {
stride_dims.push(stride[0]);
}
} else if stride.len() == num_spatial_dims {
panic!("unimplemented: You can not yet specify one stride per spatial dimension");
} else {
panic!(
"Must either specify one stride or one stride per spatial dimension. Supplied {:?}",
stride.len()
);
}
stride_dims
}
fn padding_dims(&self, num_spatial_dims: usize) -> Vec<usize> {
let mut padding_dims = Vec::with_capacity(num_spatial_dims);
let padding = self.padding();
if padding.len() == 1 {
for i in 0..num_spatial_dims {
padding_dims.push(padding[0]);
}
} else if padding.len() == num_spatial_dims {
panic!("unimplemented: You can not yet specify one padding per spatial dimension");
} else {
panic!(
"Must either specify one padding or one padding per spatial dimension. Supplied {:?}",
padding.len()
);
}
padding_dims
}
fn filter_shape(&self) -> &[usize];
fn stride(&self) -> &[usize];
fn padding(&self) -> &[usize];
}