Simon Shi的小站

人工智能,机器学习, 强化学习,大模型,自动驾驶

0%

Env Create

1
2
3
4
5
6
7
8
9
10
conda create -name tf1 python=3.7
conda activate tf1
conda search tensorflow
conda install tensorflow=1.13.2


conda create -name tf2 python=3.7
conda activate tf2
conda search tensorflow
conda install tensorflow=2.7.*

tensorflow=1.13 -> python=3.7

TF

CPU

Version Python version Compiler Build tools
tensorflow-2.12.0 3.8-3.11 MSVC 2019 Bazel 5.3.0
tensorflow-2.11.0 3.7-3.10 MSVC 2019 Bazel 5.3.0
tensorflow-2.10.0 3.7-3.10 MSVC 2019 Bazel 5.1.1
tensorflow-2.9.0 3.7-3.10 MSVC 2019 Bazel 5.0.0
tensorflow-2.8.0 3.7-3.10 MSVC 2019 Bazel 4.2.1
tensorflow-2.7.0 3.7-3.9 MSVC 2019 Bazel 3.7.2
tensorflow-2.6.0 3.6-3.9 MSVC 2019 Bazel 3.7.2
tensorflow-2.5.0 3.6-3.9 MSVC 2019 Bazel 3.7.2
tensorflow-2.4.0 3.6-3.8 MSVC 2019 Bazel 3.1.0
tensorflow-2.3.0 3.5-3.8 MSVC 2019 Bazel 3.1.0
tensorflow-2.2.0 3.5-3.8 MSVC 2019 Bazel 2.0.0
tensorflow-2.1.0 3.5-3.7 MSVC 2019 Bazel 0.27.1-0.29.1
tensorflow-2.0.0 3.5-3.7 MSVC 2017 Bazel 0.26.1
tensorflow-1.15.0 3.5-3.7 MSVC 2017 Bazel 0.26.1
tensorflow-1.14.0 3.5-3.7 MSVC 2017 Bazel 0.24.1-0.25.2
tensorflow-1.13.0 3.5-3.7 MSVC 2015 update 3 Bazel 0.19.0-0.21.0
tensorflow-1.12.0 3.5-3.6 MSVC 2015 update 3 Bazel 0.15.0
tensorflow-1.11.0 3.5-3.6 MSVC 2015 update 3 Bazel 0.15.0
tensorflow-1.10.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.9.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.8.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.7.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.6.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.5.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.4.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.3.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.2.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.1.0 3.5 MSVC 2015 update 3 Cmake v3.6.3
tensorflow-1.0.0 3.5 MSVC 2015 update 3 Cmake v3.6.3

GPU

Version Python version Compiler Build tools cuDNN CUDA
tensorflow_gpu-2.10.0 3.7-3.10 MSVC 2019 Bazel 5.1.1 8.1 11.2
tensorflow_gpu-2.9.0 3.7-3.10 MSVC 2019 Bazel 5.0.0 8.1 11.2
tensorflow_gpu-2.8.0 3.7-3.10 MSVC 2019 Bazel 4.2.1 8.1 11.2
tensorflow_gpu-2.7.0 3.7-3.9 MSVC 2019 Bazel 3.7.2 8.1 11.2
tensorflow_gpu-2.6.0 3.6-3.9 MSVC 2019 Bazel 3.7.2 8.1 11.2
tensorflow_gpu-2.5.0 3.6-3.9 MSVC 2019 Bazel 3.7.2 8.1 11.2
tensorflow_gpu-2.4.0 3.6-3.8 MSVC 2019 Bazel 3.1.0 8.0 11.0
tensorflow_gpu-2.3.0 3.5-3.8 MSVC 2019 Bazel 3.1.0 7.6 10.1
tensorflow_gpu-2.2.0 3.5-3.8 MSVC 2019 Bazel 2.0.0 7.6 10.1
tensorflow_gpu-2.1.0 3.5-3.7 MSVC 2019 Bazel 0.27.1-0.29.1 7.6 10.1
tensorflow_gpu-2.0.0 3.5-3.7 MSVC 2017 Bazel 0.26.1 7.4 10
tensorflow_gpu-1.15.0 3.5-3.7 MSVC 2017 Bazel 0.26.1 7.4 10
tensorflow_gpu-1.14.0 3.5-3.7 MSVC 2017 Bazel 0.24.1-0.25.2 7.4 10
tensorflow_gpu-1.13.0 3.5-3.7 MSVC 2015 update 3 Bazel 0.19.0-0.21.0 7.4 10
tensorflow_gpu-1.12.0 3.5-3.6 MSVC 2015 update 3 Bazel 0.15.0 7.2 9.0
tensorflow_gpu-1.11.0 3.5-3.6 MSVC 2015 update 3 Bazel 0.15.0 7 9
tensorflow_gpu-1.10.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 7 9
tensorflow_gpu-1.9.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 7 9
tensorflow_gpu-1.8.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 7 9
tensorflow_gpu-1.7.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 7 9
tensorflow_gpu-1.6.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 7 9
tensorflow_gpu-1.5.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 7 9
tensorflow_gpu-1.4.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 6 8
tensorflow_gpu-1.3.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 6 8
tensorflow_gpu-1.2.0 3.5-3.6 MSVC 2015 update 3 Cmake v3.6.3 5.1 8
tensorflow_gpu-1.1.0 3.5 MSVC 2015 update 3 Cmake v3.6.3 5.1 8
tensorflow_gpu-1.0.0 3.5 MSVC 2015 update 3 Cmake v3.6.3 5.1 8

MediaPipe基础(2)人脸网格

摘要:机器学习流水线我们的管道由两个协同工作的实时深度神经网络模型组成一个对完整图像进行操作并计算人脸位置的检测器,以及一个对这些位置进行操作并通过回归预测近似表面几何形状的人脸地标模型。

1.摘要

MediaPipe Face Mesh 是一种面部几何解决方案,即使在移动设备上也能实时估计 468 个 3D 面部标志。它采用机器学习 (ML) 来推断 3D 表面几何形状,只需要一个摄像头输入,无需专用深度传感器。该解决方案在整个管道中利用轻量级模型架构和 GPU 加速,提供对实时体验至关重要的实时性能。

此外,该解决方案与人脸几何模块捆绑在一起,弥合了人脸地标估计和有用的实时增强现实 (AR) 应用程序之间的差距。它建立了一个可度量的3D空间,并使用面部地标屏幕位置来估计该空间内的面部几何形状。人脸几何数据由常见的三维几何基元组成,包括人脸姿态变换矩阵和三角化人脸网格。在幕后,使用一种被称为普鲁克分析的轻量级的统计分析方法,用来驱动一个健壮的、性能好的、可移植的逻辑。该分析在CPU上运行,并且在ML模型推理的基础上具有最小的速度/内存占用。

Read more »

ChatGPT

文心一言(百度)

通义千问(阿里)

  • 代码:https://github.com/QwenLM/Qwen

  • 体验地址:https://modelscope.cn/studios/qwen/Qwen-7B-Chat-Demo/summary

  • 18亿(1.8B)、70亿(7B)、140亿(14B)和720亿(72B)。本次开源包括基础模型Qwen,即Qwen-1.8B、Qwen-7B、Qwen-14B、Qwen-72B,以及对话模型Qwen-Chat,即Qwen-1.8B-Chat、Qwen-7B-Chat、Qwen-14B-Chat和Qwen-72B-Chat。

  • 利用SFT和RLHF技术实现对齐,从基座模型训练得到对话模型。Qwen-Chat具备聊天、文字创作、摘要、信息抽取、翻译等能力,同时还具备一定的代码生成和简单数学推理的能力。

ChatGLM(清华)

chatglm ,chatglm2

项目地址:https://github.com/THUDM/ChatGLM2-6B

HuggingFace:https://huggingface.co/THUDM/chatglm2-6b

MOSS (复旦NLP团队)

LLaMa(Meta)

    由Meta研发的一系列大语言模型,包括多种不同参数规模的版本,如7B、13B、33B和65B(650亿参数)

    LLaMA-13B在大多数基准上优于GPT-3,尽管其参数只有GPT-3的十分之一。此外,LLaMA-65B和LLaMA-33B是在1.4万亿个token上训练的,而最小的模型LLaMA-7B是在1万亿个token上训练的

LLaMA模型的训练数据集来源于公开数据集,无任何定制数据集,这保证了其工作与开源兼容和可复现。整个训练数据集在token化之后大约包含1.4T的token。LLaMA模型的一个显著特点是它可以在单块V100 GPU上运行,这使得LLaMA模型在计算预算有限的情况下也能提供良好的性能,有助于使大型语言模型的使用和研究更加普及。

LLaMa-2

Llama-2相比Llama-1有不少技术层面的改进,从而带来了模型性能、推理效率以及安全性等方面的有效提升。具体而言,重要的改进有以下几点:

模型架构上使用Group-Query-Attention(GQA)来提高模型推理效率,语境长度从2K增加一倍到4K。预训练语料从1.4T tokens增加到2T tokens。在监督微调(SFT)阶段更加注重数据集质量,使用更少但质量更高的SFT数据相比使用百万量级的公开SFT数据,效果显著提升。引入了三项安全训练技术Supervised Safety Fine-Tuning、Safety RLHF、Safety Context Distillation 提升模型的安全性。

Alpaca

miniChatGPT

https://zhuanlan.zhihu.com/p/652735189

通义千问(模型参数GPU资源)

模型 开源日期 最大上下文长度 System Prompt强化 预训练token数 微调(Q-Lora)最小GPU用量 生成2048个token的最小显存占用 工具调用
Qwen-1.8B 23.11.30 32K 2.2T 5.8GB 2.9GB
Qwen-7B 23.08.03 32K 2.4T 11.5GB 8.2GB
Qwen-14B 23.09.25 8K 3.0T 18.7GB 13.0GB
Qwen-72B 23.11.30 32K 3.0T 61.4GB 48.9GB

名词解释

HuggingFace AI开发者社区,等同于GitHub;

主要是HuggingFace把AI项目的研发流程标准化,即准备数据集、定义模型、训练和测试,如下所示:

REF:

大模型的实践应用4-ChatGLM-6b大模型的结构与核心代码解读,最全的ChatGLM模型架构介绍与源码解读-CSDN博客

Zhihu 大模型设计与升级之道:ChatGLM、LLAMA、Baichuan及LLM结构解析

# 大模型升级与设计之道:ChatGLM、LLAMA、Baichuan及LLM结构解析

Tensorflow权重迁移至Pytorch_tensorflow权重转pytorch_古月萝北的博客-CSDN博客

Conv2D层

Tensorflow的数据维度为(B,H,W,C), 而Pytorch的数据维度为(B,C,H,W), 因此二者卷积层的权重矩阵也是不一样的。Pytorch的为(out_channels,in_channels,H,W), Tensorflow的为(H,W,in_channels,out_channels), 因此权重迁移时需要转置权重矩阵。

此外,如果卷积带有bias,layer.get_weights()返回长度为2的列表,第一个元素为权重矩阵,第二个元素为bias.

Read more »

Caffe、Tensorflow和Pytorch通道维度顺序小结

N: batch;

C: channel

H: height

W: width

Caffe 的Blob通道顺序是:NCHW;

Tensorflow的tensor通道顺序:默认是NHWC, 也支持NCHW,使用cuDNN会更快;

Pytorch中tensor的通道顺序:NCHW

TensorRT中的tensor 通道顺序: NCHW

numpy image: H x W x C
torch image: C X H X W


目前世面上深度学习框架比较多,常用的有三大类:Caffe、Tensorflow和Pytorch,这三种深度学习框架都主要在英伟达显卡上面进行训练和测试,很奇怪的是,它们之间的通道维度顺序并没有保持一致,在多个框架中替换着使用,很容易让人混淆了,所以做一个小结。

Caffe 的通道顺序是NCHW;

Tensorflow的通道顺序默认是NHWC(但可以设置成NCHW),NHWC 的访存局部性更好(每三个输入像素即可得到一个输出像素),NCHW 则必须等所有通道输入准备好才能得到最终输出结果,需要占用较大的临时空间。

TensorFlow 为什么选择 NHWC 格式作为默认格式?因为早期开发都是基于 CPU,使用 NHWC 比 NCHW 稍快一些(不难理解,NHWC 局部性更好,cache 利用率高)。

NCHW 则是 Nvidia cuDNN 默认格式,使用 GPU 加速时用 NCHW 格式速度会更快(也有个别情况例外)。

最佳实践:设计网络时充分考虑两种格式,最好能灵活切换,在 GPU 上训练时使用 NCHW 格式,在 CPU 上做预测时使用 NHWC 格式。

Pytorch的通道顺序是NCHW

下采样

常见下采样方法
最大池化
平均池化
卷积(strides>1)
空洞卷积(Atrous Convolution / Dilated Convolution) 也是一种变相的下采样方式,但它通常用于保持特征图尺寸的同时增加感受野
自适应下采样(Adaptive Sampling):

上采样

(将低分辨率特征图放大至高分辨率)

Option Function
Nearest Neighbor Upsampling
(最近邻插值
Bilinear Interpolation Upsampling
(双线性插值)
old函数 nn.Upsample()
F.interpolate (1.6版本之后)
Transposed Convolution(转置卷积/反卷积) nn.ConvTranspose2d
PixelShuffle(像素重组) nn.PixelShuffle

spectral_norm

是深度学习中的一种正则化技术,主要用于稳定和约束神经网络中的权重矩阵,特别是对于生成对抗网络(GANs)和其他涉及大型权重矩阵的模型,可以有效地解决训练过程中的梯度消失或爆炸问题,以及防止模型过度拟合。

Spectral normalization(谱范数归一化)通过对权重矩阵的谱范数(即该矩阵的最大奇异值)进行规范化,强制限制权重矩阵的影响范围,从而使网络的训练更加稳定。

  1. 给定一个卷积层 conv,我们可以应用谱范数归一化:
1
2
3
4
5
6
7
8
from torch.nn.utils import spectral_norm
from torch import nn

# 创建一个卷积层
conv = nn.Conv2d(in_channels, out_channels, kernel_size, bias=False)

# 对权重矩阵应用谱范数归一化
conv = spectral_norm(conv)
  1. 或者在初始化时直接使用 nn.SpectralNorm
1
2
3
4
5
from torch.nn import SpectralNorm

# 创建并直接应用谱范数归一化的卷积层
conv = nn.Conv2d(in_channels, out_channels, kernel_size, bias=False)
conv = SpectralNorm(conv)

Container Class

nn.Sequential

是一个有序的模块容器,其中的子模块会按照添加的顺序依次执行。它非常适用于堆叠一系列简单的线性操作序列,如连续的卷积和全连接层。定义和使用方式如下:

1
2
3
4
5
6
7
8
from torch.nn import Sequential, Conv2d, Linear

model = Sequential(
Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1),
ReLU(),
MaxPool2d(kernel_size=2),
Linear(64 * reduced_image_size * reduced_image_size, num_classes)
)

nn.ModuleList

 是一个可迭代的模块容器,但不保持顺序索引。它可以容纳任意数量的 nn.Module 子类实例,并且可以通过索引访问和修改。

1
2
3
4
from torch.nn import ModuleList, Conv2d
conv_layers = ModuleList([Conv2d(32, 64, 3), Conv2d(64, 128, 3)])

self_layers = ModuleList([MyModule(12, 24), MyModule2(24,12)])

nn.ModuleDict

nn.ModuleDict 是一个键值对形式的模块容器,其中键是字符串类型,值是 nn.Module 实例。它允许通过字符串关键字来访问和管理子模块,这对于具有命名组件的复杂网络结构非常有用。

1
2
3
4
5
6
from torch.nn import ModuleDict, Conv2d

conv_blocks = ModuleDict({
'block1': Conv2d(3, 32, 3),
'block2': Conv2d(32, 64, 5),
})

functional

Leak_relu

F.leaky_relu_() 和 F.leaky_relu() 都是用来实现Leaky ReLU激活函数的,它们的区别在于是否原地修改输入张量:

  1. F.leaky_relu(): 这是一个普通的函数调用,它接收一个张量作为输入,计算并返回带有Leaky ReLU激活的输出张量。这个操作不会改变原始输入张量的内容,而是返回一个新的张量。

    1
    2
    3
    1import torch.nn.functional as F
    2input = torch.randn(10, 10)
    3output = F.leaky_relu(input, negative_slope=0.01) # 返回一个新的张量
  2. F.leaky_relu_(): 这是一个原地(in-place)操作符版本,它会在原始输入张量上直接进行Leaky ReLU激活计算,覆盖掉原来的值,不返回新的张量,而是直接修改输入张量。

    1
    2
    3
    1import torch.nn.functional as F
    2input = torch.randn(10, 10)
    3F.leaky_relu_(input, negative_slope=0.01) # 直接在原始输入上修改

总结来说,如果你希望保留原始输入张量以便后续使用,请使用 F.leaky_relu();如果你愿意直接在原始输入上进行操作且不需要保留原始值,可以使用 F.leaky_relu_(),这在内存有限的情况下有助于节省存储空间。

[已经验证], 需要根据网络模块修改

将tensorpack的inference改为pytorch_.pb转换为.pth_云端一散仙的博客-CSDN博客

将pb文件转为pth文件

  • 相关的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import torch
from collections import OrderedDict
import tensorflow as tf
from tensorflow.python.framework import tensor_util
def view_params():
pb_file = 'ocr/checkpoint/text_recognition_377500.pb'
graph = tf.Graph()
with graph.as_default():
with tf.gfile.FastGFile(pb_file, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
_ = tf.import_graph_def(graph_def, name='')
graph_nodes=[n for n in graph_def.node]
wts = [n for n in graph_nodes if n.op=='Const']

odic = OrderedDict()
for n in wts:
param = tensor_util.MakeNdarray(n.attr['value'].tensor)
if not param.size == 0:
odic[n.name] = tensor_util.MakeNdarray(n.attr['value'].tensor)
torch.save(odic, 'pb_377500.pth')

模型代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class TextRecognition(nn.Module):
def __init__(self):
super(TextRecognition, self).__init__()
self.features = nn.Sequential(OrderedDict([
('Conv2d_1a_3x3', BasicConv2d(3, 32, kernel_size=3, stride=2, padding='SAME')),
('Conv2d_2a_3x3', BasicConv2d(32, 32, kernel_size=3, stride=1, padding='SAME')),
...
('Mixed_6h', Inception_B()),
]))
self.attention_lstm = AttentionLstm()

def forward(self, x):
x = self.features(x)
x = self.attention_lstm(x)
return x

class LinearBias(nn.Module):
def __init__(self, size):
super(LinearBias, self).__init__()
self.param = nn.Parameter(torch.Tensor(size))

def forward(self, x):
x = x + self.param
return x

class AttentionLstm(nn.Module):
def __init__(self, seq_len=33, is_training=False, num_classes=7569,
wemb_size=256, channel=1024, lstm_size=512):
super(AttentionLstm, self).__init__()
self.seq_len = seq_len # 33
...
self.W_wemb = nn.Linear(self.num_classes, self.wemb_size, bias=False)
self.lstm_b = LinearBias(self.lstm_size*4)
self.tanh = nn.Tanh()
self.softmax_1d = nn.Softmax(dim=1)
self.sigmoid = nn.Sigmoid()
self.dropout_1d = nn.Dropout(0.)

def forward(self, cnn_feature): # bs, 1024, h, w
_, _, self.height, self.width = cnn_feature.size()
...
return output_array, attention_array

Pytorch 与 TensorFlow 二维卷积(Conv2d)填充(padding)上的差异,写卷积层的时候遇到的坑。
这种差异是由 TensorFlow 和 Pytorch 在卷积运算时使用的填充方式不同导致的。Pytorch 在填充的时候,上、下、左、右各方向填充的大小是一样的,但 TensorFlow 却允许不一样。
参考博客1Pytorch 与 TensorFlow 二维卷积(Conv2d)填充(padding)上的差异 - 简书
参考博客2tensorflow与pytorch卷积填充方式的差异 - 简书

在AttentionLstm中,有一个LinearBias类,该类会将pack和self.lstm_b加起来,但是如果在forward中写成相加的形式,就不能将该self.lstm_b保存下来,写成类可以使模型加载参数的时候可以一次加载完成。

1
2
3
4
5
6
7
8
9
10
11
12
class AttentionLstm(nn.Module):
def __init__(self):
super(AttentionLstm, self).__init__()
self.seq_len = 33 # 33
self.W_wemb = nn.Linear(10, 20, bias=False)
self.lstm_b = LinearBias(4)
self.a = nn.Parameter(torch.Tensor(1))
self.b = torch.randn(1, 3)

test = AttentionLstm()
# odict_keys(['a', 'W_wemb.weight', 'lstm_b.param']),self.b不会保存在state_dict中,而self.lstm_b会保存
print(test.state_dict())
1
2
pack = self.lstm_W(wemb_prev) + self.lstm_U(h_prev) + self.lstm_Z(attention_feature)  # bs, 2048
pack_with_bias = self.lstm_b(pack)

原代码使用的大都是tensorflow的函数,所以要改成相应的pytorch的函数。

tensorflow pytorch
tf.matmul torch.matmul
tf.multiply torch.mul
tf.sigmoid torch.nn.Sigmoid
tf.nn .dropout torch.nn.Dropout
tf.nn .softmax torch.nn.Softmax
tf.tanh torch.tanh
tf.split torch.split
tf.shape torch.size
tf.reshape / tf.transpose torch.reshape / view
tf.expand_dims torch.unsqueeze
tf.add_n /tf.add torch.add
tf.reduce_sum torch.sum
tf.reduce_mean torch.mean
tf.transpose torch.permute
tf.concat torch.cat
tf.nn .embedding_lookup torch.index_select

加载参数

最后加载参数验证

1
2
net = attention_ocr_pytorch.TextRecognition()
net.load_state_dict(torch.load('log/pytorch/pb_377500_fl.pth'))

end

Sequence 使用Reshape

pytorch中没有nn.Reshape层,如果想使用 reshape 功能,通常:

1
2
3
4
5
6
7
8
class Net(nn.Module):
def __init__(self):
super().__init__()
...
def forward(self, x):
...
h = h.view(-1, 128)
...

如果要想在 nn.Sequential 中使用 Reshape 功能,可以自定义Reshape层:

1
2
3
4
5
6
class Reshape(nn.Module):
def __init__(self, *args):
super(Reshape, self).__init__()
self.shape = args
def forward(self, x):
return x.view((x.size(0),)+self.shape)

然后就可以直接在nn.Sequential中使用Reshape功能了:

1
2
3
4
5
nn.Sequential(
nn.Linear(10, 64*7*7),
Reshape(64, 7, 7),
...
)

原文链接:https://blog.csdn.net/d14665/article/details/112218767

Reference

pytorch 模型与tf模型转换_tf.cast如何用pytorch实现_zhurui_xiaozhuzaizai的博客-CSDN博客

使用Transformers将TF模型转化成PyTorch模型_tf模型转pytorch_亚林瓜子的博客-CSDN博客

https://github.com/huggingface/transformers/blob/ad7196524695f3bb3e178d57d280bd18fa175ca6/src/transformers/models/bert/convert_bert_pytorch_checkpoint_to_original_tf.py

Tensor初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//1 数组 -> Tensor
int data[10] = {3,4,6}
torch::Tensor x_data = torch::from_blob(data,{3},torch::kFloat)

//2 vector -> Tensor
std::vector<float> std_vector = {346};
torch::Tensor vector_data = torch::from_brob(std_vector.data(),{3},torch::kFloat);

//3 Tensor like
torch::Tensor x = torch::zeros({3,4});
torch::Tensor x_zeros = torch::zeros_like(x);
torch::Tensor x_ones = torch::ones_like(x);
torch::Tensor x_rand = torch::rand_like(x);
//浅拷贝
torch::Tensor y = x
//深拷贝
torch::Tensor z = x.clone();


//4 new shape Tensor
torch::Tensor x_ones = torch::ones({3,4});
torch::Tensor x_zeros = torch::zeros({3,4});
torch::Tensor x_eye = torch::eye(4);
torch::Tensor x_full = torch::full({3,4},10);
torch::Tensor x_rand = torch::rand({3,4});
torch::Tensor x_randn = torch::randn({3,4});
torch::Tensor x_randint = torch::randint(0,4,{3,3});

Tensor 操作

index_select

提取指定元素形成新的张量(关键字index:就代表是提取出来相应的元素组成新的张量)

1
2
3
4
5
6
7
8
9
10
11
12
std::cout<<b.index_select(0,torch::tensor({0, 3, 3})).sizes();//选择第0维的0,3,3组成新张量[3,3,28,28]
std::cout<<b.index_select(1,torch::tensor({0,2})).sizes(); //选择第1维的第0和第2的组成新张量[10, 2, 28, 28]
std::cout<<b.index_select(2,torch::arange(0,8)).sizes(); //选择十张图片每个通道的前8列的所有像素[10, 3, 8, 28]

Tensor x_data = torch::rand({3,4});
Tensor mask = torch::zeros({3,4});

mask[1][1] = 1;
mask[0][0] = 1;

//index()方法输入参量为布尔值组成的数组,输出参量为对应index的值组成新的张量(新的内存空间)
Tensor x = x_data.index({ mask.to(kBool) });

torch::topk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
torch::Tensor torch::topk(const torch::Tensor& input, int k, int dim=-1, bool largest=true, bool sorted=false)

// input:输入张量。
// k:最大的 k 个值的数量。
// dim:要获取最大值的位置的维度,默认为 -1(最后一位)。
// largest:如果为 true,则返回最大的 k 个值;如果为 false,则返回最小的 k 个值。默认为 true。
// sorted:如果为 true,则返回的值是排序的;如果为 false,则不保证排序。默认为 false。

/// return
// 一个张量,包含最大的 k 个值(如果 largest=true)或最小的 k 个值(如果 largest=false)。
// 一个张量,包含这些值的索引。

torch::Tensor x = torch::tensor({3, 1, 2, 0, 4, 0, 5, 9, 6});
auto [values, indices] = torch::topk(x, 3);

// values: tensor([9, 7, 6])
// indices: tensor([8, 5, 4])

E2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
torch::Tensor scores = torch::rand({10});
std::tuple<torch::Tensor,torch::Tensor> sort_ret = torch::sort(scores.unsqueeze(1), 0, 1);
torch::Tensor v = std::get<0>(sort_ret).squeeze(1).to(scores.device());
torch::Tensor idx = std::get<1>(sort_ret).squeeze(1).to(scores.device());
std::cout<<scores<<std::endl;
std::cout<<v<<std::endl;
std::cout<<idx<<std::endl;

for(int i=0;i<10;i++)
{
int idx_1 = idx[i].item<int>();
float s = v[i].item<float>();

std::cout<<idx_1<<" "<<s<<std::endl;
}

Reference

libtorch 常用api函数示例(史上最全、最详细)_无左无右的博客-CSDN博客

Libtorch教程(二):基于Libtorch分类模型推理_脆皮茄条的博客-CSDN博客_libtorch 推理