对DenseTensor进行Transpose

DenseTensor · 浏览次数 : 40

小编点评

**reshape** 和 **transpose** 是两种在矩阵中交换维度的方法。 **reshape** 方法允许您根据行数和列数调整矩阵的形状。例如,以下代码使用 reshape 方法将矩阵的行数从 3 到 4,列数保持不变: ```python tensor.reshape(2, 3) ``` **transpose** 方法允许您交换矩阵的维度。例如,以下代码使用 transpose 方法将矩阵的列数与行数互换: ```python tensor.transpose() ``` **reshape 和 transpose 的本质区别**如下: * **reshape** 方法改变矩阵的形状,而 **transpose** 方法改变矩阵的维度。 * **reshape** 方法可以改变矩阵的形状,但保持矩阵的维数。 * **transpose** 方法可以交换矩阵的维度,但不能改变矩阵的形状。 **总结** | 方法 | reshape | transpose | |---|---|---| | 功能 | 将矩阵的行数和列数调整 | 将矩阵的列数与行数互换 | | 改变矩阵的形状 | 是的 | 是的 | | 改变矩阵的维数 | 不一定 | 是的 |

正文

ML.NET 是微软推出的为. NET 平台设计的深度学习库,通过这个东西(ModelBuilder)可以自己构建模型,并用于后来的推理与数据处理。虽然设计是很好的,但是由于现在的 AI 发展基本上都以 python 实现作为基础,未来这个东西的发展不好说,特别是模型构建部分。我个人认为,它提供的最有价值的场景是:算法组的同学进行模型构建,然后导出 onnx 格式模型,由 ML.NET 加载并应用于生产环境中。这个流程可以进行持续集成与持续部署,性能也不错。此外,后端人员不需要太多 AI 相关知识,只需要了解怎么处理结果就可以了,这样降低了部署的门槛。

按照这个思路,最近使用 ML. NET 加载 pytorch 导出的 onnx 模型进行推理时,由于模型的输出的行顺序做了调整,我在利用之前需要进行一个 transpose 操作。

请分清楚 reshape 与 transpose 操作的区别,两者有本质不同。

但是 ML.NET 自带的数据功能太少了,后来找了一圈,发现 ML. NET 的 ONNXRUNTIME 设计之初就没有考虑过对其的后续数据处理,他们认为后续处理应当是属于另外过程的问题,需要使用其他的手段来处理数据变换等操作。

不得不说貌似非常有道理,我理解还是太肤浅了,最后使用了很多方法,甚至自己去实现了一个,但是感觉好像有点问题,不能白写,贴在这里了。

//用法
TransposeHelper.TransposeDimensions(w, new int[] { 1, 3, 80, 80, 57 }, new int[] { 1, 3, 57, 80, 80 }, new int[] { 0, 1, 4, 2, 3 })


	//貌似还是有点问题
    internal class TransposeHelper
    {
        public static float[] TransposeDimensions(float[] data, int[] inputShape, int[] outputShape, int[] permutation)
        {
            var rank = inputShape.Length;
            var indices = Enumerable.Range(0, rank).ToArray();
            var transposedIndices = permutation ?? indices.Reverse().ToArray();

            if (inputShape.Length != transposedIndices.Length || inputShape.Length != outputShape.Length)
            {
                throw new ArgumentException("Invalid input shape, output shape or permutation.");
            }

            var transposedData = new float[data.Length];
            var index = new int[rank];

            for (var i = 0; i < data.Length; i++)
            {
                index = GetIndex(i, index, inputShape);
                var transposedIndex = GetTransposedIndex(index, transposedIndices);
                var transposedOffset = GetOffset(transposedIndex, outputShape);
                transposedData[transposedOffset] = data[i];
            }

            return transposedData;
        }

        private static int[] GetIndex(int i, int[] index, int[] shape)
        {
            for (var j = shape.Length - 1; j >= 0; j--)
            {
                var div = 1;

                for (var k = j - 1; k >= 0; k--)
                {
                    div *= shape[k];
                }

                index[j] = i / div % shape[j];
            }

            return index;
        }

        private static int[] GetTransposedIndex(int[] index, int[] transposedIndices)
        {
            var transposedIndex = new int[index.Length];

            for (var i = 0; i < index.Length; i++)
            {
                transposedIndex[i] = index[transposedIndices[i]];
            }

            return transposedIndex;
        }

        private static int GetOffset(int[] index, int[] shape)
        {
            var offset = 0;
            var stride = 1;

            for (var i = shape.Length - 1; i >= 0; i--)
            {
                offset += index[i] * stride;
                stride *= shape[i];
            }

            return offset;
        }

    }

活不能不干,总得想想办法,经过查找,发现 NumSharp 支持 numpy 的 transpose 功能,实现起来和在 numpy 上一样简单:

NumSharp 实现在 C# 上用 numpy 的语法实现其功能,以下代码使用 RoslynPad 运行并测试。

#r "nuget: NumSharp, 0.30.0"  
#r "nuget: System.Numerics.Tensors, 0.1.0"  
  
using System.Numerics.Tensors;  
using NumSharp.Utilities;  
using NumSharp;  
  
var tensor = new DenseTensor<float>(new float[] { 1, 2, 3, 4, 5, 6 }, new[] { 2, 3 });  
//tensor.Dump();  
tensor.Reshape(new int[]{ 3, 2}).Dump();  
NDArray nDArray = new NDArray(tensor.ToArray(), new Shape(new []{ 2, 3}));  
//nDArray.Dump();  
nDArray = nDArray.transpose(new int[]{1,0});  
nDArray.Dump();

与对DenseTensor进行Transpose相似的内容:

对DenseTensor进行Transpose

`ML.NET` 是微软推出的为. NET 平台设计的深度学习库,通过这个东西(`ModelBuilder`)可以自己构建模型,并用于后来的推理与数据处理。虽然设计是很好的,但是由于现在的 AI 发展基本上都以 `python` 实现作为基础,未来这个东西的发展不好说,特别是模型构建部分。我个人认为

对Transformer的一些理解

在学习Transformer这个模型前对seq2seq架构有个了解时很有必要的 先上图 输入和输出 首先理解模型时第一眼应该理解输入和输出最开始我就非常纠结 有一个Inputs,一个Outputs(shift right)和一个Output Probabilities,首先需要借助这三个输入/输出来

.NET实现获取NTP服务器时间并同步(附带Windows系统启用NTP服务功能)

对某个远程服务器启用和设置NTP服务(Windows系统) 打开注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 将 Enabled 的值设置为 1,这将启用NTP服务器功

[转帖]JMETER性能监控之serverAgent

对linux服务器的服务进行压测时,服务器的运行情况可以通过添加插件serverAgent来观察,可以实时监控性能指标。 1 (一)环境准备 1、下载zip包ServerAgent-2.2.3.zip 2、在服务器中,创建一个文件夹serveragent,名字随便起 mkdir serveragen

[转帖]对磁盘进行基准检验

对磁盘进行基准检验https://learn.microsoft.com/zh-cn/azure/virtual-machines/disks-benchmarks 适用于:✔️ Linux VM ✔️ Windows VM ✔️ 灵活规模集 ✔️ 统一规模集 基准测试是指模拟应用程序的不同工作负荷

对 Pulsar 集群的压测与优化

前言 这段时间在做 MQ(Pulsar)相关的治理工作,其中一个部分内容关于消息队列的升级,比如: 一键创建一个测试集群。 运行一批测试用例,覆盖我们线上使用到的功能,并输出测试报告。 模拟压测,输出测试结果。 本质目的就是想直到新版本升级过程中和升级后对现有业务是否存在影响。 一键创建集群和执行测

自然语言处理 Paddle NLP - 情感分析技术及应用-理论

对带有感情色彩的主观性文本进行 分析、处理、归纳和推理的过程,输入文本 => (描述实体/entity,属性/aspect,情感/opinion ,观点持有者/holder,时间/time)

一文让你彻底掌握ThreadLocal

对共享变量加锁虽然能够保证线程的安全,但是却增加了开发人员对锁的使用技能,如果锁使用不当,则会导致死锁的问题。而ThreadLocal能够做到在创建变量后,每个线程对变量访问时访问的是线程自己的本地变量。

带你揭开神秘的Javascript AST面纱之Babel AST 四件套的使用方法

对 AST 有了初步的认识,还有常规的代码改造应用实践,现在我们来详细说说使用 AST, 如何进行代码改造?

《对线面试官》| 高频 Python 面试题 pt.1

**1.聊聊 python 中的值传递和引用传递吧** - 值传递: 值传递意味着在函数调用时,将实际参数的值复制一份传递给函数的形式参数 在函数内部,形式参数将作为局部变量使用,对形式参数的修改不会影响原始变量的值 - 引用传递 引用传递意味着在函数调用时,将实际参数的引用(内存地址)传递给函数的