从零手写Resnet50实战篇——权值另存为

本文介绍了如何从零开始编写Resnet50模型,不依赖任何第三方库或框架。作者通过Python脚本将预训练的Resnet50模型权重保存为txt文本文件,便于在不同环境下读取和调试。通过验证存储的权重数量,确认了转换的正确性,为后续自定义实现神经网络推理提供了基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

​大家好啊,我是董董灿。

这是《从零手写Resnet50实战》的第二篇文章。

往期文章列表:
从零手写Resnet50,chatGPT是我的第一个合伙伙伴

权值怎么处理

在制定了不用第三方库和框架,从零手写Resnet50的前提下,面临的第一个问题就是网络的权值怎么处理。

网上有不少教程是基于已有的模型和推理框架来加载权值,然后完成的推理运算。

而如果不依赖已有的框架,就需要对模型中的权值做一次自定义的格式转存。

权值转存成文本文件

第一步,把模型中的权值,另存为一个可以随意被操控的文件格式——最常见的 txt 文本格式。

这样做的好处就是,以txt文件存储的模型参数,可以随时随地的,以读文件的方式随意加载。

由于不再是结构化的数据,而是我们可以随意操控的数据(甚至可以修改),也方便神经网络中每一层的调试。

于是,我写了个脚本,用来将参数数据保存下来。

import torch
import torchvision
import numpy as np
from torchvision import models
resnet50 = models.resnet50(pretrained=True)
print(resnet50)def save(data, file):
  d = np.array(data.weight.data.cpu().numpy())
  np.savetxt(file+str(".txt"), d.reshape(-1, 1))
  
save(resnet50.conv1, "resnet50_conv1")
save(resnet50.bn1, "resnet50_bn1")def save_bottle_neck(layer, layer_index):
  bottle_neck_idx = 0
  layer_name = "resnet50_layer" + str(layer_index) + "_bottleneck"
  for bottleNeck in layer:
    save(bottleNeck.conv1, layer_name + str(bottle_neck_idx) + "_conv1")
    save(bottleNeck.bn1, layer_name + str(bottle_neck_idx) + "_bn1")
    save(bottleNeck.conv2, layer_name + str(bottle_neck_idx) + "_conv2")
    save(bottleNeck.bn2, layer_name + str(bottle_neck_idx) + "_bn2")
    save(bottleNeck.conv3, layer_name + str(bottle_neck_idx) + "_conv3")
    save(bottleNeck.bn3, layer_name + str(bottle_neck_idx) + "_bn3")
    if bottleNeck.downsample:
      save(bottleNeck.downsample[0], layer_name + str(bottle_neck_idx) + "_downsample_conv2d")
      save(bottleNeck.downsample[1], layer_name + str(bottle_neck_idx) + "_downsample_batchnorm")
    bottle_neck_idx = bottle_neck_idx + 1
​
save_bottle_neck(resnet50.layer1, 1)
save_bottle_neck(resnet50.layer2, 2)
save_bottle_neck(resnet50.layer3, 3)
save_bottle_neck(resnet50.layer4, 4)
​
save(resnet50.fc, "resnet50.fc")

这个脚本可以自动地从网上下载已经训练好的模型,然后打印出Resnet50的网络结构,并且将有参数的层(主要是卷积层和BN层和FC层)中的参数保存下来。
保存的每一层参数

简单验证存储的权值对不对

Resnet50中的第一层卷积,卷积核大小为 7x7,channel 数是3,共 64 个卷积核,因此这一层的权值参数有 64x7x7x3 = 9408个。

Resnet50中最后一层全连接层,将通道 2048 转为通道 1000,算法上为一个简单地 [m, k] x [k, n] = [m, n] 的矩阵乘法。
最后一层的矩阵乘法
这一层的权值参数个数为 2048 x 1000 = 2048000个。

查看保存的 resnet50_conv1.txt 和 resnet50_fc.txt 的行数:

$ wc -l resnet50_conv1.txt
9408 resnet50_conv1.txt
​
$ wc -l resnet50_fc.txt
2048000 resnet50_fc.txt

txt文件每一行保存一个参数,可以看到参数个数是正确的。

这样就完成了Resnet50权值的格式转存,转存到txt中,无论python环境,还是C++环境,都可以很友好的读入文件数据,然后进行计算。

代码和保存的权值参数文件已经上传到了仓库——从零手写Resnet50。

说明:txt文件中的数据类型都是浮点型,浮点型能确保整个神经网络推理的精度达标,不至于误差太大,后续算法实现,也需要是浮点运算。

v v v v v v

本文为作者原创,请勿转载,转载请联系作者。
点击下方卡片,关注我的公众号,有最新的文章和项目动态。

v v v v v v

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董董灿是个攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值