Tensorflow预训练模型转PyTorch

news2024/11/14 15:10:43

深度学习领域是计算机科学中变化最快的领域之一。大约 5 年前,当我开始研究这个主题时,TensorFlow 被认为是主导框架。如今,大多数研究人员已经转向 PyTorch。

NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 

虽然这种快节奏令人兴奋,但也带来了很多挑战。最近,我面临着继续完成 2018 年开展的一个项目的任务。一位同事在大量临床数据集上训练了一个分割模型,并报告了出色的性能。

今天,我们的目标是在称为迁移学习的过程中,将该训练好的模型用于类似的目标。这里的直觉是,与其从头开始,不如至少部分使用预训练权重来实例化新模型的权重,这将提供一个更好的起点。

1、收集 Tensorflow 1.x 权重

这听起来比实际容易。在 tensorflow 1.x 中,模型保存在四个单独的文件中 - 其中没有一个可以直接转换为 pytorch 的 state_dict。为了解决这个问题,我们必须手动创建一个字典并从 tensorflow 后端检索权重。

为了实现这一点,你需要了解 tensorflow 实现的命名方案。每个操作都可以在创建时分配一个名称。这个名称在稍后转换为 pytorch 时很重要。

import tensorflow as tf  # tensorflow 1.x
import pickle

'''
<base_folder>
├───checkpoint
├───<model_name>.meta
├───<model_name>.data-00000-of-00001
└───<model_name>.index
'''

# First let's load meta graph and restore weights
sess = tf.Session()
saver = tf.train.import_meta_graph(r'<base_folder>\<model_name>.meta')
saver.restore(sess, tf.train.latest_checkpoint(r'<base_folder>'))

# get all trainable weights and save them in a dictionary
vars = sess.graph.get_collection('trainable_variables')
weights = {}
for v in vars:
    weights[v.name] = sess.run(v)  # retrieve the value from the tf backend

with open('weights.pickle', 'wb') as handle:
    pickle.dump(weights, handle, protocol=pickle.HIGHEST_PROTOCOL)

2、重建模型

遗憾的是,没有直接的方法将 TensorFlow 模型转换为 PyTorch。但是,尽管语法略有不同,但大多数层都存在于这两个框架中。例如,在 tf1 中,卷积层可以包含激活函数,而在 PyTorch 中,该函数需要按顺序添加。

此示例展示了 tf1 和 PyTorch 实现中流行的 UNet 架构的 upconv 块。

# >>> tf1 implementation (without encapsulating class)
import tensorflow as tf

def upconvcat(self, x1, x2, n_filter, name):
    x1 = tf.keras.layers.UpSampling2D((2, 2))(x1)
    x1 = tf.layers.conv2d(x1, filters=n_filter, kernel_size=(3, 3), padding='same', name="upsample_{}".format(name))
    return tf.concat([x1, x2], axis=-1, name="concat_{}".format(name))  # NHWC format

# >>> pytorch implementation
import torch

class UpConvCat(nn.Module):
    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.up = torch.nn.Upsample(scale_factor=2)
        self.conv = torch.nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1)

    def forward(self, x1, x2):
        x1 = self.up(x1)
        return torch.cat([x1, x2], dim=1)  # NCHW format

3、NHWC 与 NCHW

tensorflow 和 pytorch 之间的最后一个重要区别是关于轴的约定。

在旧版 tensorflow 中, data_format 属性可以指定为 channels_last 或 channels_first ,而前者是默认选项。然而,在 pytorch 中,只能使用 channels first。通常,这些格式表示为 NHWC 和 NCHW,分别表示批处理大小 (N)、高度 (H)、宽度 (W) 和通道 (C)。

np.transpose(kernel, (3, 2, 0, 1))

如果使用默认的 channels_lastoption 训练 tensorflow 中的预训练模型,则需要对内核轴进行置换才能与 torch 一起使用。为了弥补这一点,需要像这样调整 2d-conv 层权重。

4、初始化 pytorch 模型

将权重转换为正确的格式后,我们可以将它们加载到 pytorch 模型中。为此,我们随机实例化一个模型并遍历命名参数列表。然后我们使用来自 tensorflow 的权重就地修改参数。

    # set new weights from loaded tf values
    with torch.no_grad():
        for (name, param), (tf_name, tf_param) in zip(m.named_parameters(), tf_weights.items()):
            # convert NHWC to NCHW format and copy to change memory layout
            tf_param = np.transpose(tf_param, (3, 2, 0, 1)).copy() if len(tf_param.shape) == 4 else tf_param
            assert tf_param.shape == param.detach().numpy().shape, name

            # https://discuss.pytorch.org/t/how-to-assign-an-arbitrary-tensor-to-models-parameter/44082/3
            param.copy_(torch.tensor(tf_param, requires_grad=True, dtype=param.dtype))

5、结束语

按照这些步骤,可以提取在 tensorflow 1.x 中训练的模型并将其转换为 pytorch 模型。我希望这对与我处境相似的人有所帮助。


原文链接:TF预训练模型转PyTorch - BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1990533.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Opencv学习-窗口交互

交互操作能够增加用户对程序流程的控制&#xff0c;使程序可以根据用户需求实现不同的处理结果。有时某一个参数需要反复尝试不同的数值&#xff0c;这时交互操作可以实现在程序运行过程中改变参数数值的作用&#xff0c;避免重复运行程序&#xff0c;节省时间&#xff0c;同时…

AI智能名片小程序源码在付费媒体与企业营销策略中的创新应用

摘要&#xff1a;在数字化浪潮的推动下&#xff0c;付费媒体已成为企业营销战略的核心组成部分。从视频流媒体平台到社交媒体&#xff0c;企业需不断探索新颖且高效的营销手段以吸引目标受众并促进业务增长。AI智能名片小程序源码&#xff0c;作为融合人工智能、小程序技术与传…

什么是实时数据仓库?它有哪些不可替代之处?

【实时数据仓库】可以分开来理解&#xff1a; ✅【实时数据】&#xff1a;即能够快速处理数据&#xff0c;且几乎无延迟的提供最新的数据的能力。 ✅【仓库管理】&#xff1a;可以理解为对仓库的库存控制、对仓库的存储优化以及协调物流。 那么实时数据仓库就是&#xff1a;…

Windows 找不到音频输入/输出设备

0.具体现象 系统音量为0&#xff0c;且无法通过任何方式调整。音量表示非静音表示&#xff0c;而是下图这个叉。 1. 解决方案 以Windows 11电脑为例&#xff0c;从搜索框输入【设备管理器】&#xff0c;进入界面如下&#xff1a; 发现一个感叹号的设备【Intel High Defini…

对象与类的一些基本定义与例子(C++)

1.例题要求&#xff0c;设计一个学生类&#xff0c;实例化对象&#xff0c;并且进行赋值 我们通过创建学生的类&#xff0c;给予了学生名字和年龄的两个属性&#xff0c;我们在main函数中创建了学生类的对象s1,通过s1调用了学生类的属性并给予赋值&#xff0c;最后调用学生类打…

Nginx统计PV、NV

目录 PV 分析 UV 分析 在 Nginx 的配置文件中设置 access_log 主要涉及到以下几个方面&#xff1a; 以下是一个基本的 access_log 配置示例&#xff1a; 使用命令行工具对日志进行基本分析&#xff1a; 后端记录 对于 nginx 的 access.log 日志&#xff0c;我们可以根据日…

进程的等待(非阻塞轮询+阻塞)和替换控制详解

引言 在Linux系统中&#xff0c;进程管理是核心功能之一。理解进程的创建、执行和终止是系统编程中的基础。本文将深入探讨Linux中的进程控制机制&#xff0c;包括进程的生命周期、父子进程的交互、以及进程状态的管理 1. 进程创建&#xff1a;fork()函数 在Linux操作系统中…

Prompt万能框架与常用评估指标

引言 在人工智能的飞速发展中&#xff0c;大型语言模型&#xff08;LLM&#xff09;已成为研究和应用的热点。LLM以其强大的语言理解和生成能力&#xff0c;在诸如自然语言处理、文本生成、问答系统等多个领域展现出巨大潜力。然而&#xff0c;要充分发挥LLM的能力&#xff0c…

NSSCTF练习记录:[SWPUCTF 2021 新生赛]caidao

题目&#xff1a; 图片上给出了代码&#xff0c;是php的一句话木马 eval($_POST[wllm]);符号 符号表示后面的语句即使执行错误&#xff0c;也不报错。 eval()函数 eval()函数的作用是把括号内的字符串全部当作php代码来执行。 ** P O S T [ ′ w l l m ′ ] ∗ ∗ p o s t …

一起学习LeetCode热题100道(30/100)

30.两两交换链表中的节点(学习) 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head …

【LVS】调度算法概念

fd相当于静态 ovf相当于动态

界面控件DevExpress WinForms,支持HTML CSS提升用户体验(二)

DevExpress WinForms现在可以利用HTML/CSS强大的功能&#xff0c;帮助受DevExpress驱动的WinForms应用程序引入现代的UI元素和用户体验&#xff01; P.S&#xff1a;DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。Dev…

室内定位导航技术:蓝牙信号强度(RSSI)与三角定位算法应用

在数字化时代&#xff0c;位置服务已成为连接物理世界与数字世界的桥梁。在室内环境中&#xff0c;由于GPS信号受建筑物遮挡而失效&#xff0c;传统的室外定位技术难以满足需求&#xff0c;无法精准指引我们在商场、机场、医院等庞大而复杂的建筑内部寻路。室内定位导航技术不仅…

在 Manim 中,kwargs 传递的关键字参数

在 Manim 中&#xff0c;kwargs 用于传递关键字参数&#xff0c;常用于构造对象时。这里的关键参数有那些。我都要&#xff0c;给我整理一下 Sider Fusion 在 Manim 中&#xff0c;kwargs 允许您传递可选的关键字参数来控制动画、对象的外观和行为。尽管具体可用的参数会因对象…

【开端】通过Java 过滤器灵活配置URL访问权限,并返回403

一、绪论 在JAVA项目系统中&#xff0c;后端给前端提供接口。但是在某些场景我们需要临时控制接口是否能被访问。或关闭某一接口的访问权限。 比如某一接口被攻击了或者某一接口存在漏洞&#xff0c;在系统不关闭的情况下&#xff0c;如何控制系统的访问权限。 二、控制接口访…

CVE-2017-15715~Apache解析漏洞【春秋云境靶场渗透】

Apache解析漏洞 漏洞原理 # Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执行不同的指令。比如如下配置文件&#xff1a; AddType text/html .html AddLanguage zh-CN .cn# 其给 .html 后缀增加了 media-type &#xff0c;值为 text/html &#xff1b;给 …

【案例35】销售订单公式问题导致系统宕机

问题现象 经过顾问反馈&#xff0c;发现系统现在出现卡顿&#xff0c;NCC一直在转圈。 问题分析 远程排查&#xff0c;发现在服务器从机上defalut-7发生了内存溢出&#xff0c;宕机。 生成了宕机日志。分析结果如下&#xff1a; 销售订单相关操作&#xff0c;vo太多了导致…

Java stream流支持多字段排序

背景 对于排序而言,比较常见的场景是前端传递所需的排序字段名和排序方向,然后通过stream流或者数据库来实现排序. 为动态接收参数,继承Map来支持多字段传入.另外stream流原生的sorted写起来相对比较繁琐,通过compartor方法封装构建多字段排序的逻辑.具体就是通过反射拿到对应…

怎么在 React Native 应用中处理深度链接?

深度链接是一种技术&#xff0c;其中给定的 URL 或资源用于在移动设备上打开特定页面或屏幕。因此&#xff0c;深度链接可以引导用户到应用程序内的特定屏幕&#xff0c;而不仅仅是启动移动设备上的应用程序&#xff0c;从而提供更好的用户体验。这个特定的屏幕可能位于一系列层…

docker 好用的加速器

cd /etc/docker vi daemon.json { "registry-mirrors":["https://docker.rainbond.cc"] }