@@ -292,21 +292,30 @@ package object tensorflow {
292292 * */
293293 object dtflearn {
294294
295+ /**
296+ * Constructs a feed-forward layer.
297+ *
298+ * @param num_units The number of neurons in the layer
299+ * @param id A unique integer id for constructing the layer name.
300+ *
301+ * */
302+ def feedforward (num_units : Int )(id : Int ) = tf.learn.Linear (" Linear_" + id, num_units)
303+
295304 /**
296305 * Constructs a symmetric (square) convolutional layer from the provided dimensions.
297306 *
298307 * [[org.platanios.tensorflow.api.ops.NN.SamePadding ]] is used as the padding mode.
299308 *
300309 * @param size The size of each square filter e.g. 2*2, 3*3 etc
301- * @param num_channels The number of channels in the input
310+ * @param num_channels_input The number of channels in the input
302311 * @param num_filters The number of channels in the layer output
303312 * @param strides A [[Tuple2 ]] with strides, for each direction i.e. breadth and height.
304313 * @param index The layer id or index, helps in creating a unique layer name
305314 * */
306- def conv2d (size : Int , num_channels : Int , num_filters : Int , strides : (Int , Int ))(index : Int ) =
315+ def conv2d (size : Int , num_channels_input : Int , num_filters : Int , strides : (Int , Int ))(index : Int ) =
307316 tf.learn.Conv2D (
308317 " Conv2D_" + index,
309- Shape (size, size, num_channels , num_filters),
318+ Shape (size, size, num_channels_input , num_filters),
310319 strides._1, strides._2,
311320 SamePadding )
312321
@@ -330,6 +339,60 @@ package object tensorflow {
330339 tf.learn.ReLU (" ReLU_" + i, relu_param)
331340 }
332341
342+ /**
343+ * Constructs an inverted convolutional pyramid, consisting of
344+ * stacked versions of [Conv2d --> ReLU --> Dropout] layers.
345+ *
346+ * The number of filters learned in each Conv2d layer are
347+ * arranged in decreasing exponents of 2. They are costructed
348+ * using calls to [[conv2d_unit() ]]
349+ *
350+ * ... Conv_unit(128) --> Conv_unit(64) --> Conv_unit(32) --> Conv_unit(16) ...
351+ *
352+ * @param size The size of the square convolutional filter to be applied
353+ * in each segment.
354+ * @param num_channels_input The number of channels in the input.
355+ * @param start_num_bits The exponent of 2 which determines size/depth of the starting layer
356+ * e.g. set to 4 for a depth of 16.
357+ *
358+ * @param end_num_bits The exponent of 2 which determines the size/depth of the end layer.
359+ *
360+ * @param relu_param The activation barrier of the ReLU activation.
361+ *
362+ * @param dropout Set to true, if dropout units should be placed in each unit.
363+ *
364+ * @param keep_prob If dropout is enabled, then this determines the retain probability.
365+ * */
366+ def conv2d_pyramid (
367+ size : Int , num_channels_input : Int )(
368+ start_num_bits : Int , end_num_bits : Int )(
369+ relu_param : Float = 0.1f , dropout : Boolean = true ,
370+ keep_prob : Float = 0.6f ) = {
371+
372+ require(
373+ start_num_bits > end_num_bits,
374+ " To construct a 2d-convolutional pyramid, you need to start_num_bits > end_num_bits" )
375+
376+ // Create the first layer segment.
377+ val head_segment = conv2d_unit(
378+ Shape (size, size, num_channels_input, math.pow(2 , start_num_bits).toInt),
379+ stride = (1 , 1 ), relu_param, dropout, keep_prob)(0 )
380+
381+ // Create the rest of the pyramid
382+ val tail_segments = (end_num_bits until start_num_bits).reverse.zipWithIndex.map(bitsAndIndices => {
383+ val (bits, index) = bitsAndIndices
384+
385+ conv2d_unit(
386+ Shape (size, size, math.pow(2 , bits+ 1 ).toInt, math.pow(2 , bits).toInt),
387+ stride = (math.pow(2 , index+ 1 ).toInt, math.pow(2 , index+ 1 ).toInt),
388+ relu_param, dropout, keep_prob)(index+ 1 )
389+
390+ }).reduceLeft((a,b) => a >> b)
391+
392+ // Join head to tail.
393+ head_segment >> tail_segments
394+ }
395+
333396 }
334397
335398}
0 commit comments