| File: NasBert\Modules\Layers\EncConvLayer.cs | Web Access |
| Project: src\src\Microsoft.ML.TorchSharp\Microsoft.ML.TorchSharp.csproj (Microsoft.ML.TorchSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Text; using Microsoft.ML.TorchSharp.Extensions; using TorchSharp; using TorchSharp.Modules; namespace Microsoft.ML.TorchSharp.NasBert.Modules.Layers { internal sealed class EncConvLayer : Layer { #pragma warning disable MSML_PrivateFieldName // Private field name not in: _camelCase format private readonly Sequential Conv1; private readonly LayerNorm LayerNorm1; private readonly Sequential Conv2; private readonly LayerNorm LayerNorm2; private bool _disposedValue; #pragma warning restore MSML_PrivateFieldName // Private field name not in: _camelCase format public EncConvLayer(int channel, int kernelSize, double dropoutRate, string activationFn, double activationDropoutRate) : base(nameof(EncConvLayer)) { Conv1 = torch.nn.Sequential( ("conv", new ConvSeparable(channel, channel, kernelSize, kernelSize / 2, dropoutRate)), ("activation", new ActivationFunction(activationFn)), ("dropout", torch.nn.Dropout(activationDropoutRate)) ); LayerNorm1 = torch.nn.LayerNorm(new long[] { channel }); Conv2 = torch.nn.Sequential( ("conv", new ConvSeparable(channel, channel, kernelSize, kernelSize / 2, dropoutRate)), ("activation", new ActivationFunction(activationFn)), ("dropout", torch.nn.Dropout(activationDropoutRate)) ); LayerNorm2 = torch.nn.LayerNorm(new long[] { channel }); RegisterComponents(); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "MSML_GeneralName:This name should be PascalCased", Justification = "Need to match TorchSharp.")] public override torch.Tensor forward(torch.Tensor x, Dictionary<string, object> param = null) { if (!ParseArguments(param, out var selfAttentionPaddingMask)) { throw new ArgumentException($"Invalid arguments: {param}."); } using var x1 = ForwardOneLayer(x, selfAttentionPaddingMask, Conv1, LayerNorm1); return ForwardOneLayer(x1, selfAttentionPaddingMask, Conv2, LayerNorm2); } private static torch.Tensor ForwardOneLayer(torch.Tensor input, torch.Tensor selfAttentionPaddingMask, torch.nn.Module<torch.Tensor, torch.Tensor> convLayer, torch.nn.Module<torch.Tensor, torch.Tensor> layerNorm) { using var disposeScope = torch.NewDisposeScope(); torch.Tensor x = selfAttentionPaddingMask.IsNull() ? input.alias() : input.masked_fill(selfAttentionPaddingMask.T.unsqueeze(-1), 0); var conv = convLayer.forward(x); conv.add_(input); var norm = layerNorm.forward(conv); return norm.MoveToOuterDisposeScope(); } public override void CloseLayerNormTraining() { LayerNorm1.eval(); LayerNorm2.eval(); } private static bool ParseArguments(IReadOnlyDictionary<string, object> param, out torch.Tensor selfAttentionPaddingMask) { selfAttentionPaddingMask = null; if (param == null) return false; if (param.ContainsKey(PaddingMaskKey)) selfAttentionPaddingMask = (torch.Tensor)param[PaddingMaskKey]; return true; } protected override void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { Conv1.Dispose(); LayerNorm1.Dispose(); Conv2.Dispose(); LayerNorm2.Dispose(); _disposedValue = true; } } base.Dispose(disposing); } } }