forked from SciSharp/TensorFlow.NET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConv.cs
More file actions
115 lines (105 loc) · 3.91 KB
/
Conv.cs
File metadata and controls
115 lines (105 loc) · 3.91 KB
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
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Keras.Engine;
using Tensorflow.Keras.Utils;
using Tensorflow.Operations;
using Tensorflow.Operations.Activation;
namespace Tensorflow.Keras.Layers
{
public class Conv : Tensorflow.Layers.Layer
{
protected int rank;
protected int filters;
protected int[] kernel_size;
protected int[] strides;
protected string padding;
protected string data_format;
protected int[] dilation_rate;
protected IActivation activation;
protected bool use_bias;
protected IInitializer kernel_initializer;
protected IInitializer bias_initializer;
protected RefVariable kernel;
protected RefVariable bias;
protected Convolution _convolution_op;
public Conv(int rank,
int filters,
int[] kernel_size,
int[] strides = null,
string padding = "valid",
string data_format = null,
int[] dilation_rate = null,
IActivation activation = null,
bool use_bias = true,
IInitializer kernel_initializer = null,
IInitializer bias_initializer = null,
bool trainable = true,
string name = null) : base(trainable: trainable, name: name)
{
this.rank = rank;
this.filters = filters;
this.kernel_size = kernel_size;
this.strides = strides;
this.padding = padding;
this.data_format = data_format;
this.dilation_rate = dilation_rate;
this.activation = activation;
this.use_bias = use_bias;
this.kernel_initializer = kernel_initializer;
this.bias_initializer = bias_initializer;
input_spec = new InputSpec(ndim: rank + 2);
}
protected override void build(TensorShape input_shape)
{
int channel_axis = data_format == "channels_first" ? 1 : -1;
int input_dim = input_shape.Dimensions[input_shape.NDim - 1];
var kernel_shape = new int[] { kernel_size[0], kernel_size[1], input_dim, filters };
kernel = add_weight(name: "kernel",
shape: kernel_shape,
initializer: kernel_initializer,
trainable: true,
dtype: _dtype);
if (use_bias)
bias = add_weight(name: "bias",
shape: new int[] { filters },
initializer: bias_initializer,
trainable: true,
dtype: _dtype);
var axes = new Dictionary<int, int>();
axes.Add(-1, input_dim);
input_spec = new InputSpec(ndim: rank + 2, axes: axes);
string op_padding;
if (padding == "causal")
op_padding = "valid";
else
op_padding = padding;
var df = conv_utils.convert_data_format(data_format, rank + 2);
_convolution_op = nn_ops.Convolution(input_shape,
kernel.shape,
op_padding.ToUpper(),
strides,
dilation_rate,
data_format: df);
built = true;
}
protected override Tensor call(Tensor inputs, Tensor training = null)
{
var outputs = _convolution_op.__call__(inputs, kernel);
if (use_bias)
{
if (data_format == "channels_first")
{
throw new NotImplementedException("call channels_first");
}
else
{
outputs = nn_ops.bias_add(outputs, bias._AsTensor(), data_format: "NHWC");
}
}
if (activation != null)
return activation.Activate(outputs);
return outputs;
}
}
}