@@ -333,6 +333,127 @@ public extension Dense {
333
333
}
334
334
}
335
335
336
+ /// A 1-D convolution layer (e.g. temporal convolution over a time-series).
337
+ ///
338
+ /// This layer creates a convolution filter that is convolved with the layer input to produce a
339
+ /// tensor of outputs.
340
+ @_fixed_layout
341
+ public struct Conv1D < Scalar: TensorFlowFloatingPoint > : Layer {
342
+ /// The 3-D convolution kernel `[width, inputChannels, outputChannels]`.
343
+ public var filter : Tensor < Scalar >
344
+ /// The bias vector `[outputChannels]`.
345
+ public var bias : Tensor < Scalar >
346
+ /// An activation function.
347
+ public typealias Activation = @differentiable ( Tensor < Scalar > ) -> Tensor < Scalar >
348
+ /// The element-wise activation function.
349
+ @noDerivative public let activation : Activation
350
+ /// The stride of the sliding window for temporal dimension.
351
+ @noDerivative public let stride : Int32
352
+ /// The padding algorithm for convolution.
353
+ @noDerivative public let padding : Padding
354
+
355
+ /// Creates a `Conv1D` layer with the specified filter, bias, activation function, stride, and
356
+ /// padding.
357
+ ///
358
+ /// - Parameters:
359
+ /// - filter: The 3-D convolution kernel `[width, inputChannels, outputChannels]`.
360
+ /// - bias: The bias vector `[outputChannels]`.
361
+ /// - activation: The element-wise activation function.
362
+ /// - stride: The stride of the sliding window for temporal dimension.
363
+ /// - padding: The padding algorithm for convolution.
364
+ public init (
365
+ filter: Tensor < Scalar > ,
366
+ bias: Tensor < Scalar > ,
367
+ activation: @escaping Activation ,
368
+ stride: Int ,
369
+ padding: Padding
370
+ ) {
371
+ self . filter = filter
372
+ self . bias = bias
373
+ self . activation = activation
374
+ self . stride = Int32 ( stride)
375
+ self . padding = padding
376
+ }
377
+
378
+ /// Returns the output obtained from applying the layer to the given input.
379
+ ///
380
+ /// - Parameters:
381
+ /// - input: The input to the layer `[batchCount, width, inputChannels]`.
382
+ /// - context: The contextual information for the layer application, e.g. the current learning
383
+ /// phase.
384
+ /// - Returns: The output `[batchCount, newWidth, outputChannels]`.
385
+ @differentiable
386
+ public func applied( to input: Tensor < Scalar > , in _: Context ) -> Tensor < Scalar > {
387
+ let conv2D = input. expandingShape ( at: 1 ) . convolved2D (
388
+ withFilter: filter. expandingShape ( at: 0 ) , strides: ( 1 , 1 , stride, 1 ) , padding: padding)
389
+ return activation ( conv2D. squeezingShape ( at: 1 ) + bias)
390
+ }
391
+ }
392
+
393
+ public extension Conv1D where Scalar. RawSignificand: FixedWidthInteger {
394
+ /// Creates a `Conv1D` layer with the specified filter shape, stride, padding, and
395
+ /// element-wise activation function. The filter tensor is initialized using Glorot uniform
396
+ /// initialization with the specified generator. The bias vector is initialized with zeros.
397
+ ///
398
+ /// - Parameters:
399
+ /// - filterShape: The 3-D shape of the filter, representing
400
+ /// `[width, inputChannels, outputChannels]`.
401
+ /// - stride: The stride of the sliding window for temporal dimension.
402
+ /// - padding: The padding algorithm for convolution.
403
+ /// - activation: The element-wise activation function.
404
+ /// - generator: The random number generator for initialization.
405
+ ///
406
+ /// - Note: Use `init(filterShape:stride:padding:activation:seed:)` for faster random
407
+ /// initialization.
408
+ init < G: RandomNumberGenerator > (
409
+ filterShape: ( Int , Int , Int ) ,
410
+ stride: Int = 1 ,
411
+ padding: Padding = . valid,
412
+ activation: @escaping Activation = identity,
413
+ generator: inout G
414
+ ) {
415
+ let filterTensorShape = TensorShape ( [
416
+ Int32 ( filterShape. 0 ) , Int32 ( filterShape. 1 ) , Int32 ( filterShape. 2 ) ] )
417
+ self . init (
418
+ filter: Tensor ( glorotUniform: filterTensorShape) ,
419
+ bias: Tensor ( zeros: TensorShape ( [ Int32 ( filterShape. 2 ) ] ) ) ,
420
+ activation: activation,
421
+ stride: stride,
422
+ padding: padding)
423
+ }
424
+ }
425
+
426
+ public extension Conv1D {
427
+ /// Creates a `Conv1D` layer with the specified filter shape, strides, padding, and
428
+ /// element-wise activation function. The filter tensor is initialized using Glorot uniform
429
+ /// initialization with the specified seed. The bias vector is initialized with zeros.
430
+ ///
431
+ /// - Parameters:
432
+ /// - filterShape: The 3-D shape of the filter, representing
433
+ /// `[width, inputChannels, outputChannels]`.
434
+ /// - stride: The stride of the sliding window for temporal dimension.
435
+ /// - padding: The padding algorithm for convolution.
436
+ /// - activation: The element-wise activation function.
437
+ /// - seed: The random seed for initialization. The default value is random.
438
+ init (
439
+ filterShape: ( Int , Int , Int ) ,
440
+ stride: Int = 1 ,
441
+ padding: Padding = . valid,
442
+ activation: @escaping Activation = identity,
443
+ seed: ( Int64 , Int64 ) = ( Int64 . random ( in: Int64 . min..< Int64 . max) ,
444
+ Int64 . random ( in: Int64 . min..< Int64 . max) )
445
+ ) {
446
+ let filterTensorShape = TensorShape ( [
447
+ Int32 ( filterShape. 0 ) , Int32 ( filterShape. 1 ) , Int32 ( filterShape. 2 ) ] )
448
+ self . init (
449
+ filter: Tensor ( glorotUniform: filterTensorShape, seed: seed) ,
450
+ bias: Tensor ( zeros: TensorShape ( [ Int32 ( filterShape. 2 ) ] ) ) ,
451
+ activation: activation,
452
+ stride: Int32 ( stride) ,
453
+ padding: padding)
454
+ }
455
+ }
456
+
336
457
/// A 2-D convolution layer (e.g. spatial convolution over images).
337
458
///
338
459
/// This layer creates a convolution filter that is convolved with the layer input to produce a
@@ -347,8 +468,7 @@ public struct Conv2D<Scalar: TensorFlowFloatingPoint>: Layer {
347
468
public typealias Activation = @differentiable ( Tensor < Scalar > ) -> Tensor < Scalar >
348
469
/// The element-wise activation function.
349
470
@noDerivative public let activation : Activation
350
- /// The strides of the sliding window for each dimension of a 4-D input.
351
- /// Strides in non-spatial dimensions must be `1`.
471
+ /// The strides of the sliding window for spatial dimensions.
352
472
@noDerivative public let strides : ( Int32 , Int32 )
353
473
/// The padding algorithm for convolution.
354
474
@noDerivative public let padding : Padding
@@ -357,11 +477,11 @@ public struct Conv2D<Scalar: TensorFlowFloatingPoint>: Layer {
357
477
/// padding.
358
478
///
359
479
/// - Parameters:
360
- /// - filter: The filter .
361
- /// - bias: The bias.
362
- /// - activation: The activation activation.
363
- /// - strides: The strides.
364
- /// - padding: The padding.
480
+ /// - filter: The 4-D convolution kernel .
481
+ /// - bias: The bias vector .
482
+ /// - activation: The element-wise activation function .
483
+ /// - strides: The strides of the sliding window for spatial dimensions .
484
+ /// - padding: The padding algorithm for convolution .
365
485
public init (
366
486
filter: Tensor < Scalar > ,
367
487
bias: Tensor < Scalar > ,
@@ -397,10 +517,10 @@ public extension Conv2D {
397
517
/// initialization with the specified generator. The bias vector is initialized with zeros.
398
518
///
399
519
/// - Parameters:
400
- /// - filterShape: The shape of the filter, represented by a tuple of `4` integers .
401
- /// - strides: The strides.
402
- /// - padding: The padding.
403
- /// - activation: The activation function.
520
+ /// - filterShape: The shape of the 4-D convolution kernel .
521
+ /// - strides: The strides of the sliding window for spatial dimensions .
522
+ /// - padding: The padding algorithm for convolution .
523
+ /// - activation: The element-wise activation function.
404
524
/// - generator: The random number generator for initialization.
405
525
///
406
526
/// - Note: Use `init(filterShape:strides:padding:activation:seed:)` for faster random
@@ -430,14 +550,11 @@ public extension Conv2D {
430
550
/// initialization with the specified seed. The bias vector is initialized with zeros.
431
551
///
432
552
/// - Parameters:
433
- /// - filterShape: The shape of the filter, represented by a tuple of `4` integers .
434
- /// - strides: The strides.
435
- /// - padding: The padding.
436
- /// - activation: The activation function.
553
+ /// - filterShape: The shape of the 4-D convolution kernel .
554
+ /// - strides: The strides of the sliding window for spatial dimensions .
555
+ /// - padding: The padding algorithm for convolution .
556
+ /// - activation: The element-wise activation function.
437
557
/// - seed: The random seed for initialization. The default value is random.
438
- ///
439
- /// - Note: Use `init(filterShape:strides:padding:activation:seed:)` for faster random
440
- /// initialization.
441
558
init (
442
559
filterShape: ( Int , Int , Int , Int ) ,
443
560
strides: ( Int , Int ) = ( 1 , 1 ) ,
@@ -450,11 +567,11 @@ public extension Conv2D {
450
567
Int32 ( filterShape. 0 ) , Int32 ( filterShape. 1 ) ,
451
568
Int32 ( filterShape. 2 ) , Int32 ( filterShape. 3 ) ] )
452
569
self . init (
453
- filter: Tensor ( glorotUniform: filterTensorShape, seed: seed) ,
454
- bias: Tensor ( zeros: TensorShape ( [ Int32 ( filterShape. 3 ) ] ) ) ,
455
- activation: activation,
456
- strides: ( Int32 ( strides. 0 ) , Int32 ( strides. 1 ) ) ,
457
- padding: padding)
570
+ filter: Tensor ( glorotUniform: filterTensorShape, seed: seed) ,
571
+ bias: Tensor ( zeros: TensorShape ( [ Int32 ( filterShape. 3 ) ] ) ) ,
572
+ activation: activation,
573
+ strides: ( Int32 ( strides. 0 ) , Int32 ( strides. 1 ) ) ,
574
+ padding: padding)
458
575
}
459
576
}
460
577
@@ -583,6 +700,47 @@ public struct BatchNorm<Scalar: TensorFlowFloatingPoint>: Layer {
583
700
}
584
701
}
585
702
703
+ /// A max pooling layer for temporal data.
704
+ @_fixed_layout
705
+ public struct MaxPool1D < Scalar: TensorFlowFloatingPoint > : Layer {
706
+ /// The size of the sliding reduction window for pooling.
707
+ @noDerivative let poolSize : Int32
708
+ /// The stride of the sliding window for temporal dimension.
709
+ @noDerivative let stride : Int32
710
+ /// The padding algorithm for pooling.
711
+ @noDerivative let padding : Padding
712
+
713
+ /// Creates a max pooling layer.
714
+ ///
715
+ /// - Parameters:
716
+ /// - poolSize: The size of the sliding reduction window for pooling.
717
+ /// - stride: The stride of the sliding window for temporal dimension.
718
+ /// - padding: The padding algorithm for pooling.
719
+ public init (
720
+ poolSize: Int ,
721
+ stride: Int ,
722
+ padding: Padding
723
+ ) {
724
+ self . poolSize = Int32 ( poolSize)
725
+ self . stride = Int32 ( stride)
726
+ self . padding = padding
727
+ }
728
+
729
+ /// Returns the output obtained from applying the layer to the given input.
730
+ ///
731
+ /// - Parameters:
732
+ /// - input: The input to the layer.
733
+ /// - context: The contextual information for the layer application, e.g. the current learning
734
+ /// phase.
735
+ /// - Returns: The output.
736
+ @differentiable
737
+ public func applied( to input: Tensor < Scalar > , in _: Context ) -> Tensor < Scalar > {
738
+ return input. expandingShape ( at: 1 ) . maxPooled (
739
+ kernelSize: ( 1 , 1 , poolSize, 1 ) , strides: ( 1 , 1 , stride, 1 ) , padding: padding
740
+ ) . squeezingShape ( at: 1 )
741
+ }
742
+ }
743
+
586
744
/// A max pooling layer for spatial data.
587
745
@_fixed_layout
588
746
public struct MaxPool2D < Scalar: TensorFlowFloatingPoint > : Layer {
@@ -629,7 +787,48 @@ public struct MaxPool2D<Scalar: TensorFlowFloatingPoint>: Layer {
629
787
@differentiable
630
788
public func applied( to input: Tensor < Scalar > , in _: Context ) -> Tensor < Scalar > {
631
789
return input. maxPooled (
632
- kernelSize: poolSize, strides: strides, padding: padding)
790
+ kernelSize: poolSize, strides: strides, padding: padding)
791
+ }
792
+ }
793
+
794
+ /// An average pooling layer for temporal data.
795
+ @_fixed_layout
796
+ public struct AvgPool1D < Scalar: TensorFlowFloatingPoint > : Layer {
797
+ /// The size of the sliding reduction window for pooling.
798
+ @noDerivative let poolSize : Int32
799
+ /// The stride of the sliding window for temporal dimension.
800
+ @noDerivative let stride : Int32
801
+ /// The padding algorithm for pooling.
802
+ @noDerivative let padding : Padding
803
+
804
+ /// Creates an average pooling layer.
805
+ ///
806
+ /// - Parameters:
807
+ /// - poolSize: The size of the sliding reduction window for pooling.
808
+ /// - stride: The stride of the sliding window for temporal dimension.
809
+ /// - padding: The padding algorithm for pooling.
810
+ public init (
811
+ poolSize: Int ,
812
+ stride: Int ,
813
+ padding: Padding
814
+ ) {
815
+ self . poolSize = Int32 ( poolSize)
816
+ self . stride = Int32 ( stride)
817
+ self . padding = padding
818
+ }
819
+
820
+ /// Returns the output obtained from applying the layer to the given input.
821
+ ///
822
+ /// - Parameters:
823
+ /// - input: The input to the layer.
824
+ /// - context: The contextual information for the layer application, e.g. the current learning
825
+ /// phase.
826
+ /// - Returns: The output.
827
+ @differentiable
828
+ public func applied( to input: Tensor < Scalar > , in _: Context ) -> Tensor < Scalar > {
829
+ return input. expandingShape ( at: 1 ) . averagePooled (
830
+ kernelSize: ( 1 , 1 , poolSize, 1 ) , strides: ( 1 , 1 , stride, 1 ) , padding: padding
831
+ ) . squeezingShape ( at: 1 )
633
832
}
634
833
}
635
834
0 commit comments