From 9185cf1bc2426ffa6db9e360fbbd5e644f5a6e66 Mon Sep 17 00:00:00 2001 From: Dan Zheng Date: Wed, 1 Jul 2020 16:32:26 -0700 Subject: [PATCH] Fix `ParameterlessLayer` conformances. Associated type inference behavior was changed in https://github.com/apple/swift/pull/32578: derived conformances are now attempted before associated type inference. This broke `ParameterlessLayer`, which relied on a `TangentVector == EmptyTangentVector` same-type constraint to set a default `TangentVector` type witness for conforming types. Add explicit `TangentVector` type witnesses to `ParameterlessLayer`-conforming types to fix this regression. --- Sources/TensorFlow/Layers/Convolutional.swift | 6 +++++ Sources/TensorFlow/Layers/Core.swift | 5 ++++ Sources/TensorFlow/Layers/Dropout.swift | 8 ++++++ Sources/TensorFlow/Layers/Pooling.swift | 26 +++++++++++++++++++ Sources/TensorFlow/Layers/Upsampling.swift | 6 +++++ 5 files changed, 51 insertions(+) diff --git a/Sources/TensorFlow/Layers/Convolutional.swift b/Sources/TensorFlow/Layers/Convolutional.swift index 80176a55d..55d48e4d7 100644 --- a/Sources/TensorFlow/Layers/Convolutional.swift +++ b/Sources/TensorFlow/Layers/Convolutional.swift @@ -790,6 +790,8 @@ extension DepthwiseConv2D { /// A layer for adding zero-padding in the temporal dimension. public struct ZeroPadding1D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The padding values along the temporal dimension. @noDerivative public let padding: (Int, Int) @@ -821,6 +823,8 @@ public struct ZeroPadding1D: ParameterlessLayer /// A layer for adding zero-padding in the spatial dimensions. public struct ZeroPadding2D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The padding values along the spatial dimensions. @noDerivative public let padding: ((Int, Int), (Int, Int)) @@ -853,6 +857,8 @@ public struct ZeroPadding2D: ParameterlessLayer /// A layer for adding zero-padding in the spatial/spatio-temporal dimensions. public struct ZeroPadding3D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The padding values along the spatial/spatio-temporal dimensions. @noDerivative public let padding: ((Int, Int), (Int, Int), (Int, Int)) diff --git a/Sources/TensorFlow/Layers/Core.swift b/Sources/TensorFlow/Layers/Core.swift index ff34c82f4..9dc4d673d 100644 --- a/Sources/TensorFlow/Layers/Core.swift +++ b/Sources/TensorFlow/Layers/Core.swift @@ -19,6 +19,8 @@ import _Differentiation /// A flatten layer flattens the input when applied without affecting the batch size. @frozen public struct Flatten: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Creates a flatten layer. public init() {} @@ -37,6 +39,8 @@ public struct Flatten: ParameterlessLayer { /// A reshape layer. @frozen public struct Reshape: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The target shape. @noDerivative public var shape: Tensor @@ -70,6 +74,7 @@ public struct Reshape: ParameterlessLayer { /// A layer that encloses a custom differentiable function. public struct Function: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector public typealias Body = @differentiable (Input) -> Output @noDerivative public let body: Body diff --git a/Sources/TensorFlow/Layers/Dropout.swift b/Sources/TensorFlow/Layers/Dropout.swift index f7d82cf6b..fda981bb8 100644 --- a/Sources/TensorFlow/Layers/Dropout.swift +++ b/Sources/TensorFlow/Layers/Dropout.swift @@ -34,6 +34,8 @@ extension Tensor where Scalar: TensorFlowFloatingPoint { /// training time, which helps prevent overfitting. @frozen public struct Dropout: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + @noDerivative public let probability: Double /// Creates a dropout layer. @@ -66,6 +68,8 @@ public struct Dropout: ParameterlessLayer { /// /// The noise added always has mean zero, but has a configurable standard deviation. public struct GaussianNoise: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + @noDerivative public let standardDeviation: Tensor /// Creates a Gaussian noise layer @@ -95,6 +99,8 @@ public struct GaussianNoise: ParameterlessLayer /// Because this is a regularization layer, it is only active during training time. During inference, /// `GaussianDropout` passes through the input unmodified. public struct GaussianDropout: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + @noDerivative public let probability: Scalar @noDerivative public let standardDeviation: Scalar @@ -135,6 +141,8 @@ public struct GaussianDropout: ParameterlessLay /// Source : Self-Normalizing Neural Networks: https://arxiv.org/abs/1706.02515 @frozen public struct AlphaDropout: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + @noDerivative public let probability: Double /// Initializes an `AlphaDropout` layer with a configurable `probability`. diff --git a/Sources/TensorFlow/Layers/Pooling.swift b/Sources/TensorFlow/Layers/Pooling.swift index 0501f3b39..1a87edaaa 100644 --- a/Sources/TensorFlow/Layers/Pooling.swift +++ b/Sources/TensorFlow/Layers/Pooling.swift @@ -17,6 +17,8 @@ import _Differentiation /// A max pooling layer for temporal data. @frozen public struct MaxPool1D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The size of the sliding reduction window for pooling. @noDerivative public let poolSize: Int /// The stride of the sliding window for temporal dimension. @@ -56,6 +58,8 @@ public struct MaxPool1D: ParameterlessLayer { /// A max pooling layer for spatial data. @frozen public struct MaxPool2D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The size of the sliding reduction window for pooling. @noDerivative public let poolSize: (Int, Int, Int, Int) /// The strides of the sliding window for each dimension of a 4-D input. @@ -105,6 +109,8 @@ extension MaxPool2D { /// A max pooling layer for spatial or spatio-temporal data. @frozen public struct MaxPool3D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The size of the sliding reduction window for pooling. @noDerivative public let poolSize: (Int, Int, Int, Int, Int) /// The strides of the sliding window for each dimension of a 5-D input. @@ -171,6 +177,8 @@ extension MaxPool3D { /// An average pooling layer for temporal data. @frozen public struct AvgPool1D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The size of the sliding reduction window for pooling. @noDerivative public let poolSize: Int /// The stride of the sliding window for temporal dimension. @@ -210,6 +218,8 @@ public struct AvgPool1D: ParameterlessLayer { /// An average pooling layer for spatial data. @frozen public struct AvgPool2D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The size of the sliding reduction window for pooling. @noDerivative public let poolSize: (Int, Int, Int, Int) /// The strides of the sliding window for each dimension of a 4-D input. @@ -259,6 +269,8 @@ extension AvgPool2D { /// An average pooling layer for spatial or spatio-temporal data. @frozen public struct AvgPool3D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// The size of the sliding reduction window for pooling. @noDerivative public let poolSize: (Int, Int, Int, Int, Int) /// The strides of the sliding window for each dimension of a 5-D input. @@ -325,6 +337,8 @@ extension AvgPool3D { /// A global average pooling layer for temporal data. @frozen public struct GlobalAvgPool1D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Creates a global average pooling layer. public init() {} @@ -342,6 +356,8 @@ public struct GlobalAvgPool1D: ParameterlessLay /// A global average pooling layer for spatial data. @frozen public struct GlobalAvgPool2D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Creates a global average pooling layer. public init() {} @@ -359,6 +375,8 @@ public struct GlobalAvgPool2D: ParameterlessLay /// A global average pooling layer for spatial and spatio-temporal data. @frozen public struct GlobalAvgPool3D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Creates a global average pooling layer. public init() {} @@ -376,6 +394,8 @@ public struct GlobalAvgPool3D: ParameterlessLay /// A global max pooling layer for temporal data. @frozen public struct GlobalMaxPool1D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Creates a global max pooling layer. public init() {} @@ -396,6 +416,8 @@ public struct GlobalMaxPool1D: ParameterlessLay /// A global max pooling layer for spatial data. @frozen public struct GlobalMaxPool2D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Creates a global max pooling layer. public init() {} @@ -413,6 +435,8 @@ public struct GlobalMaxPool2D: ParameterlessLay /// A global max pooling layer for spatial and spatio-temporal data. @frozen public struct GlobalMaxPool3D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Creates a global max pooling layer. public init() {} @@ -431,6 +455,8 @@ public struct GlobalMaxPool3D: ParameterlessLay /// Note: `FractionalMaxPool` does not have an XLA implementation, and thus may have performance implications. @frozen public struct FractionalMaxPool2D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + /// Pooling ratios for each dimension of input of shape (batch, height, width, channels). /// Currently pooling in only height and width is supported. @noDerivative public let poolingRatio: (Double, Double, Double, Double) diff --git a/Sources/TensorFlow/Layers/Upsampling.swift b/Sources/TensorFlow/Layers/Upsampling.swift index b9e222b09..04dd08ead 100644 --- a/Sources/TensorFlow/Layers/Upsampling.swift +++ b/Sources/TensorFlow/Layers/Upsampling.swift @@ -17,6 +17,8 @@ import _Differentiation /// An upsampling layer for 1-D inputs. @frozen public struct UpSampling1D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + @noDerivative public let size: Int /// Creates an upsampling layer. @@ -43,6 +45,8 @@ public struct UpSampling1D: ParameterlessLayer /// An upsampling layer for 2-D inputs. @frozen public struct UpSampling2D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + @noDerivative public let size: Int /// Creates an upsampling layer. @@ -70,6 +74,8 @@ public struct UpSampling2D: ParameterlessLayer /// An upsampling layer for 3-D inputs. @frozen public struct UpSampling3D: ParameterlessLayer { + public typealias TangentVector = EmptyTangentVector + @noDerivative public let size: Int /// Creates an upsampling layer.