@@ -10,6 +10,27 @@ namespace Tensorflow | |||||
{ | { | ||||
public static class nn | public static class nn | ||||
{ | { | ||||
/// <summary> | |||||
/// Computes dropout. | |||||
/// </summary> | |||||
/// <param name="x">A floating point tensor.</param> | |||||
/// <param name="keep_prob">(deprecated) A deprecated alias for `(1-rate)`.</param> | |||||
/// <param name="noise_shape"></param> | |||||
/// <param name="seed">Used to create random seeds.</param> | |||||
/// <param name="name"></param> | |||||
/// <param name="rate">A scalar `Tensor` with the same type as `x`.</param> | |||||
/// <returns>A Tensor of the same shape of `x`.</returns> | |||||
public static Tensor dropout(Tensor x, Tensor keep_prob = null, Tensor noise_shape = null, int? seed = null, string name = null, | |||||
float? rate = null) | |||||
{ | |||||
Tensor keep = null; | |||||
if (keep_prob != null) | |||||
keep = 1.0f - keep_prob; | |||||
var rate_tensor = keep; | |||||
return nn_ops.dropout_v2(x, rate: rate_tensor, noise_shape: noise_shape, seed: seed, name: name); | |||||
} | |||||
public static (Tensor, Tensor) moments(Tensor x, | public static (Tensor, Tensor) moments(Tensor x, | ||||
int[] axes, | int[] axes, | ||||
string name = null, | string name = null, | ||||
@@ -43,6 +43,58 @@ namespace Tensorflow | |||||
}); | }); | ||||
} | } | ||||
/// <summary> | |||||
/// Computes dropout. | |||||
/// </summary> | |||||
/// <param name="x"></param> | |||||
/// <param name="rate"></param> | |||||
/// <param name="noise_shape"></param> | |||||
/// <param name="seed"></param> | |||||
/// <param name="name"></param> | |||||
/// <returns></returns> | |||||
public static Tensor dropout_v2(Tensor x, Tensor rate, Tensor noise_shape = null, int? seed = null, string name = null) | |||||
{ | |||||
return with(ops.name_scope(name, "dropout", x), scope => | |||||
{ | |||||
name = scope; | |||||
x = ops.convert_to_tensor(x, name: "x"); | |||||
if (!x.dtype.is_floating()) | |||||
throw new NotImplementedException($"x has to be a floating point tensor since it's going to" + | |||||
$" be scaled. Got a {x.dtype} tensor instead."); | |||||
rate = ops.convert_to_tensor(rate, dtype: x.dtype, name: "rate"); | |||||
// Do nothing if we know rate == 0 | |||||
var val = tensor_util.constant_value(rate); | |||||
if (!(val is null) && val.Data<float>(0) == 0) | |||||
return x; | |||||
noise_shape = _get_noise_shape(x, noise_shape); | |||||
// Sample a uniform distribution on [0.0, 1.0) and select values larger than | |||||
// rate. | |||||
// | |||||
// NOTE: Random uniform actually can only generate 2^23 floats on [1.0, 2.0) | |||||
// and subtract 1.0. | |||||
var random_tensor = random_ops.random_uniform(noise_shape, seed: seed, dtype: x.dtype); | |||||
var keep_prob = 1.0f - rate; | |||||
var scale = 1.0f / keep_prob; | |||||
// NOTE: if (1.0 + rate) - 1 is equal to rate, then we want to consider that | |||||
// float to be selected, hence we use a >= comparison. | |||||
var keep_mask = random_tensor >= rate; | |||||
var ret = x * scale * math_ops.cast(keep_mask, x.dtype); | |||||
ret.SetShape(x.GetShape()); | |||||
return ret; | |||||
}); | |||||
} | |||||
private static Tensor _get_noise_shape(Tensor x, Tensor noise_shape) | |||||
{ | |||||
if (noise_shape == null) | |||||
return array_ops.shape(x); | |||||
else | |||||
return noise_shape; | |||||
} | |||||
public static Tensor log_softmax(Tensor logits, int axis = -1, string name = null) | public static Tensor log_softmax(Tensor logits, int axis = -1, string name = null) | ||||
{ | { | ||||
return _softmax(logits, gen_nn_ops.log_softmax, axis, name); | return _softmax(logits, gen_nn_ops.log_softmax, axis, name); | ||||
@@ -76,7 +76,7 @@ namespace Tensorflow | |||||
{ | { | ||||
name = scope; | name = scope; | ||||
var minTensor = ops.convert_to_tensor(minval, dtype: dtype, name: "min"); | var minTensor = ops.convert_to_tensor(minval, dtype: dtype, name: "min"); | ||||
var maxTensor = ops.convert_to_tensor(maxval, dtype: dtype, name: "max"); | |||||
var maxTensor = ops.convert_to_tensor(maxval == null ? 1 : maxval, dtype: dtype, name: "max"); | |||||
var (seed1, seed2) = random_seed.get_seed(seed); | var (seed1, seed2) = random_seed.get_seed(seed); | ||||
if (dtype.is_integer()) | if (dtype.is_integer()) | ||||
{ | { | ||||
@@ -24,6 +24,7 @@ namespace Tensorflow | |||||
public static Tensor operator /(Tensor x, Tensor y) => BinaryOpWrapper("truediv", x, y); | public static Tensor operator /(Tensor x, Tensor y) => BinaryOpWrapper("truediv", x, y); | ||||
public static Tensor operator /(Tensor x, float y) => BinaryOpWrapper("truediv", x, y); | public static Tensor operator /(Tensor x, float y) => BinaryOpWrapper("truediv", x, y); | ||||
public static Tensor operator /(float x, Tensor y) => BinaryOpWrapper("truediv", x, y); | |||||
public static Tensor operator /(Tensor x, double y) => BinaryOpWrapper("truediv", x, y); | public static Tensor operator /(Tensor x, double y) => BinaryOpWrapper("truediv", x, y); | ||||
public static Tensor operator %(Tensor x, Tensor y) => BinaryOpWrapper("mod", x, y); | public static Tensor operator %(Tensor x, Tensor y) => BinaryOpWrapper("mod", x, y); | ||||
@@ -163,7 +163,7 @@ namespace TensorFlowNET.Examples | |||||
var y = tf.placeholder(tf.int32, new TensorShape(-1), name: "y"); | var y = tf.placeholder(tf.int32, new TensorShape(-1), name: "y"); | ||||
var is_training = tf.placeholder(tf.@bool, new TensorShape(), name: "is_training"); | var is_training = tf.placeholder(tf.@bool, new TensorShape(), name: "is_training"); | ||||
var global_step = tf.Variable(0, trainable: false); | var global_step = tf.Variable(0, trainable: false); | ||||
var keep_prob = tf.where(is_training, 0.5, 1.0); | |||||
var keep_prob = tf.where(is_training, 0.5f, 1.0f); | |||||
Tensor x_emb = null; | Tensor x_emb = null; | ||||
with(tf.name_scope("embedding"), scope => | with(tf.name_scope("embedding"), scope => | ||||
@@ -200,7 +200,7 @@ namespace TensorFlowNET.Examples | |||||
with(tf.name_scope("dropout"), delegate | with(tf.name_scope("dropout"), delegate | ||||
{ | { | ||||
// var h_drop = tf.nn.dropout(h_pool_flat, self.keep_prob); | |||||
var h_drop = tf.nn.dropout(h_pool_flat, keep_prob); | |||||
}); | }); | ||||
return graph; | return graph; | ||||