多模型图像特征可视化

news2024/11/17 23:59:10

        特征图可视化是指将网络中某一层的特征图可视化出来,以便观察网络在不同层次上学到的特征。卷积可视化可以帮助深度学习研究者更好地理解卷积的概念和原理,从而更好地设计和优化卷积神经网络。通过可视化,研究者可以更清晰地看到卷积运算中的每一个步骤,包括输入、卷积核、卷积操作和输出,从而更好地理解卷积的本质和作用。此外,卷积可视化还可以帮助研究者更好地理解卷积神经网络中的高级概念,如池化、批量归一化等,从而更好地设计和优化深度学习模型。

        本文将对卷积过程中的特征图进行可视化,研究图片经过每层卷积特征提取后,会得到哪些特征,对比观察这些特征的变化情况,能够更加熟练掌握特征图可视化操作。

        特征图可视化,这种方法是最简单,输入一张照片,然后把网络中间某层的输出的特征图按通道作为图片进行可视化展示即可。本文使用一张狗的图片进行特征图可视化。为了加快训练速度,本文仅选取一张图片进行特征图可视化,如下图1。

1、ResNet50特征图可视化

1.1 使用IntermediateLayerGetter类
# 返回输出结果
import random
import cv2
import torchvision
import torch
from matplotlib import pyplot as plt
import numpy as np
from torchvision import transforms
from torchvision import models
# 定义函数,随机从0-end的一个序列中抽取size个不同的数
def random_num(size, end):
    range_ls = [i for i in range(end)]
    num_ls = []
    for i in range(size):
        num = random.choice(range_ls)
        range_ls.remove(num)
        num_ls.append(num)
    return num_ls

path = "./input/dog.png"
transformss = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Resize((224, 224)),
     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
# 注意如果有中文路径需要先解码,最好不要用中文
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 转换维度
img = transformss(img).unsqueeze(0)
model = models.resnet50(pretrained=True)
new_model = torchvision.models._utils.IntermediateLayerGetter(model, {'layer1': '1', 'layer2': '2', "layer3": "3"})
out = new_model(img)
tensor_ls = [(k, v) for k, v in out.items()]
# 这里选取layer2的输出画特征图
v = tensor_ls[1][1]
# 选择目标卷积层
target_layer = model.layer2[0]
"""
如果要选layer3的输出特征图只需把第一个索引值改为2,即:
v=tensor_ls[2][1]
只需把第一个索引更换为需要输出的特征层对应的位置索引即可
"""
# 取消Tensor的梯度并转成三维tensor,否则无法绘图
v = v.data.squeeze(0)
print(v.shape)  # torch.Size([512, 28, 28])
# 随机选取25个通道的特征图
channel_num = random_num(25, v.shape[0])
plt.figure(figsize=(10, 10))
for index, channel in enumerate(channel_num):
    ax = plt.subplot(5, 5, index + 1, )
    plt.imshow(v[channel, :, :])
plt.savefig("./output/feature.jpg", dpi=600)

for index, channel in enumerate(channel_num):
    ax = plt.subplot(5, 5, index + 1, )
    plt.imshow(v[channel, :, :])
plt.savefig("./output/feature.jpg", dpi=600,cmap="gray") #加上cmap参数就可以显示灰度图

IntermediateLayerGetter有一个不足就是它不能获取二级层的输出,比如ResNet的layer2,他不能获取layer2里面的卷积的输出。

模型地址:C:\Users\Administrator\.cache\torch\hub\checkpoints

1.2 使用hook机制(推荐)
# 返回输出结果
import random

import cv2
import torchvision
import torch
from matplotlib import pyplot as plt
import numpy as np
from torchvision import transforms
from torchvision import models

# 定义函数,随机从0-end的一个序列中抽取size个不同的数
def random_num(size, end):
    range_ls = [i for i in range(end)]
    num_ls = []
    for i in range(size):
        num = random.choice(range_ls)
        range_ls.remove(num)
        num_ls.append(num)
    return num_ls


path = "./input/dog.png"
transformss = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Resize((224, 224)),
     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])

# 注意如果有中文路径需要先解码,最好不要用中文
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 转换维度
img = transformss(img).unsqueeze(0)

model = models.resnet50(pretrained=True)

# 选择目标层
target_layer = model.layer2[2]
# 注册钩子函数,用于获取目标卷积层的输出
outputs = []
def hook(module, input, output):
    outputs.append(output)

hook_handle = target_layer.register_forward_hook(hook)

_ = model(img)

v = outputs[-1]

"""
如果要选layer3的输出特征图只需把第一个索引值改为2,即:
v=tensor_ls[2][1]
只需把第一个索引更换为需要输出的特征层对应的位置索引即可
"""
# 取消Tensor的梯度并转成三维tensor,否则无法绘图
v = v.data.squeeze(0)

print(v.shape)  # torch.Size([512, 28, 28])

# 随机选取25个通道的特征图
channel_num = random_num(25, v.shape[0])
plt.figure(figsize=(10, 10))
for index, channel in enumerate(channel_num):
    ax = plt.subplot(5, 5, index + 1, )
    plt.imshow(v[channel, :, :])
plt.savefig("./output/feature2.jpg", dpi=600)

for index, channel in enumerate(channel_num):
    ax = plt.subplot(5, 5, index + 1, )
    plt.imshow(v[channel, :, :],cmap="gray")
plt.savefig("./output/feature2.jpg", dpi=600)

2、AlexNet特征图可视化

上面的ResNet用的是预训练模型,这里我们自己构建AlexNet

from torch import nn

class AlexNet(nn.Module):
    def __init__(self):
        super(AlexNet, self).__init__()

        self.conv1 = nn.Sequential(nn.Conv2d(3, 96, 11, 4, 2),
                                   nn.ReLU(),
                                   nn.MaxPool2d(3, 2),
                                   )

        self.conv2 = nn.Sequential(nn.Conv2d(96, 256, 5, 1, 2),
                                   nn.ReLU(),
                                   nn.MaxPool2d(3, 2),
                                   )

        self.conv3 = nn.Sequential(nn.Conv2d(256, 384, 3, 1, 1),
                                   nn.ReLU(),
                                   nn.Conv2d(384, 384, 3, 1, 1),
                                   nn.ReLU(),
                                   nn.Conv2d(384, 256, 3, 1, 1),
                                   nn.ReLU(),
                                   nn.MaxPool2d(3, 2))


        self.fc=nn.Sequential(nn.Linear(256*6*6, 4096),
                                nn.ReLU(),
                                nn.Dropout(0.5),
                                nn.Linear(4096, 4096),
                                nn.ReLU(),
                                nn.Dropout(0.5),
                                nn.Linear(4096, 100),
                                )

    def forward(self, x):
        x=self.conv1(x)
        x=self.conv2(x)
        x=self.conv3(x)
        output=self.fc(x.view(-1, 256*6*6))
        return output

model=AlexNet()
for name in model.named_children():
    print(name[0])
#同理先看网络结构
#输出
path = "./input/dog.png"
transformss = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Resize((224, 224)),
     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])

#注意如果有中文路径需要先解码,最好不要用中文
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#转换维度
img = transformss(img).unsqueeze(0)

model = AlexNet()

## 修改这里传入的字典即可

new_model = torchvision.models._utils.IntermediateLayerGetter(model, {"conv1":1,"conv2":2,"conv3":3})
out = new_model(img)

tensor_ls=[(k,v) for  k,v in out.items()]

#选取conv2的输出
v=tensor_ls[1][1]

#取消Tensor的梯度并转成三维tensor,否则无法绘图
v=v.data.squeeze(0)

print(v.shape)  # torch.Size([512, 28, 28])

#随机选取25个通道的特征图
channel_num = random_num(25,v.shape[0])
plt.figure(figsize=(10, 10))
for index, channel in enumerate(channel_num):
    ax = plt.subplot(5, 5, index+1,)
    plt.imshow(v[channel, :, :])  # 灰度图参数cmap="gray"
plt.savefig("./output/feature.jpg",dpi=300)

也就是说AlexNet这里分为了4部分,三个卷积和一个全连接(其实就是我们自己定义的foward前向传播),我们想要哪层的输出改个字典就好了

new_model = torchvision.models._utils.IntermediateLayerGetter(model, {“conv1”:1,“conv2”:2,“conv3”:3})

plt.imshow(v[channel, :, :],cmap=“gray”) 加上cmap参数就可以显示灰度图

for index, channel in enumerate(channel_num):
    ax = plt.subplot(5, 5, index+1,)
    plt.imshow(v[channel, :, :],cmap="gray")  # 灰度图参数cmap="gray"
plt.savefig("./output/feature.jpg",dpi=300)

3、简易网络特征图可视化

from torch import nn
import torch
from torch.nn import functional as F
import cv2
from matplotlib import pyplot as plt

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool1 = nn.MaxPool2d(4, 4)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.pool2 = nn.MaxPool2d(4, 4)

    def forward(self, x):
        output = []  # 保存特征层的列表,在最后的时候返回
        x = self.conv1(x)
        output.append(x)  # 加入output中
        x = F.relu(x)
        output.append(x)
        x = self.pool1(x)
        output.append(x)
        x = self.conv2(x)
        output.append(x)
        x = F.relu(x)
        output.append(x)
        x = self.pool2(x)
        return x, output

net = Net()

path = "./input/dog.png"
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = torch.tensor(img, dtype=torch.float32) / 255.0  # Normalize to [0, 1]
img = img.unsqueeze(0)  # 添加批次维度
img = img.permute(0, 3, 1, 2)  # 更改尺寸顺序
print(img.shape)

_, output = net(img)

# 打印并可视化图层
for layer in output:
    fig = plt.figure(figsize=(15, 5))  # 定义图形大小
    for i in range(layer.shape[1]):  # 迭代通道
        ax = fig.add_subplot(1, layer.shape[1], i + 1, xticks=[], yticks=[])  # 1 行,通道列数
        plt.imshow(layer[0, i].detach().numpy(), cmap="gray")  # 将通道显示为灰度图像
    plt.show()

4、Yolo网络特征图可视化

import matplotlib.pyplot as plt
import torch
import torch.nn as nn
from torch.nn import functional as F
from torchvision import transforms
from PIL import Image
from net.yolov4 import YoloBody  # Assuming YoloBody is defined in yolov4.py
import cv2

# Define the hook function to get activations
activation = {}  # Save the obtained output

def get_activation(name):
    def hook(model, input, output):
        activation[name] = output.detach()
    return hook

def main():
    anchors_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2]]
    # Call the model
    model = YoloBody(3, 20)  # Assuming 3 anchors and 20 classes
    model.eval()
    # 输出网络
    for name, param in model.named_parameters():
        print(name, param.shape)

    # 在特定层上前向钩子
    model.backbone.conv1.conv.register_forward_hook(get_activation('conv'))

    # 虚拟输入图像
    x = torch.randn(1, 3, 416, 416)

    # 获取模型预测结果(可能需要根据模型结构进行修改)
    _, _, _ = model(x)

    # 从挂钩中读取激活信息
    bn = activation['conv']
    print(bn.shape)

    # 显示特征图
    plt.figure(figsize=(12, 12))
    for i in range(bn.shape[1]):
        plt.subplot(8, 8, i + 1)
        plt.imshow(bn[0, i, :, :].cpu().numpy(), cmap='gray')
        plt.axis('off')
    plt.show()
    return 0

if __name__ == '__main__':
    transform = transforms.Compose([
        transforms.Resize([416, 416]),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])

    # 加载并预处理图像
    img_path = './input/dog.png'
    img = Image.open(img_path)
    input_img = transform(img).unsqueeze(0)

    print(input_img.shape)
    main()

报错net的问题解决方案:zhanggong0564/YOLOV3 at d94c249d8d9ec532d2f6cff1a2be183a987c2c7f (github.com)
解决文件在YOLOV3/nets,将nets文件copy放在项目根目录下面,重命名为net即可解决。

from pathlib import Path
from pooch.utils import LOGGER
import torch
import math
import matplotlib.pyplot as plt
import numpy as np

def feature_visualization(x, module_type, stage, n=2, save_dir=Path('./output')):
    """
    x:              Features to be visualized
    module_type:    Module type
    stage:          Module stage within the model
    n:              Maximum number of feature maps to plot
    save_dir:       Directory to save results
    """
    print(f"save_dir: {save_dir}")
    if 'Detect' not in module_type:
        batch, channels, height, width = x.shape  # batch, channels, height, width
        print(f"x.shape: {x.shape}")
        if height > 1 and width > 1:
            save_dir.mkdir(parents=True, exist_ok=True)  # Ensure the directory exists

            f = save_dir / f"stage{stage}_{module_type.split('.')[-1]}_features.png"  # filename
            print(f"f: {f}")

            blocks = torch.chunk(x[0].cpu(), channels, dim=0)  # select batch index 0, block by channels
            n = min(n, channels)  # number of plots
            fig, ax = plt.subplots(math.ceil(n / 2), 2, tight_layout=True)  # 8 rows x n/8 cols
            ax = ax.ravel()
            plt.subplots_adjust(wspace=0.05, hspace=0.05)
            for i in range(n):
                ax[i].imshow(blocks[i].squeeze(), cmap='gray')  # Add cmap='gray'
                ax[i].axis('off')

            LOGGER.info(f'Saving {f}... ({n}/{channels})')
            plt.savefig(f, dpi=300, bbox_inches='tight')
            plt.close()
            np.save(str(f.with_suffix('.npy')), x[0].cpu().numpy())  # npy save

5、VGGNet特征图可视化

VGG19本是用来进行分类的,进行可视化和用作VGG loss 自然也就是用到全连接层之前的内容,先要了解VGG19全连接层之前的结构

from torchvision.models import vgg19,vgg16
import torch
import torch.nn.functional as F
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

#对于torch 的models就已经包含了vgg19
#在这里pretrained=False,在下面我自己进行了模型预加载,选择Ture,则电脑联网时
#自动会完成下载
vgg_model = vgg19(pretrained=False).features[:].to(device)
print(vgg_model)
加载vgg model
import torch
from torchvision import models

# 定义 VGG19 模型
vgg_model = models.vgg19(pretrained=True)

# 将权重保存到文件中
torch.save(vgg_model.state_dict(), 'vgg19-dcbb9e9d.pth')

# 以 strict=False 加载预训练的权重
vgg_model.load_state_dict(torch.load('vgg19-dcbb9e9d.pth'), strict=False)
vgg_model.eval()

# 将所有参数的 requires_grad 设置为 False
for param in vgg_model.parameters():
    param.requires_grad = False

模型地址 C:\Users\Administrator/.cache\torch\hub\checkpoints\vgg19-dcbb9e9d.pth

可视化
import numpy as np
import matplotlib.pyplot as plt
def get_row_col(num_maps):
    # 根据特征地图的数量计算子地图行数和列数的函数
    rows = int(np.sqrt(num_maps))
    cols = int(np.ceil(num_maps / rows))
    return rows, cols
#输入的应该时feature_maps.shape = (H,W,Channels)
#下图对relu1_2 进行了可视化,有64channels,拼了个了8*8的图
def visualize_feature_map(feature_maps):
    #创建特征子图,创建叠加后的特征图
    #param feature_batch: 一个卷积层所有特征图
    # np.squeeze(feature_maps, axis=0)
    print("visualize_feature_map shape:{},dtype:{}".format(feature_maps.shape,feature_maps.dtype))
    num_maps = feature_maps.shape[2]
    feature_map_combination = []
    plt.figure(figsize=(8, 7))
    # 取出 featurn map 的数量,因为特征图数量很多,这里直接手动指定了。
    #num_pic = feature_map.shape[2]
    row, col = get_row_col(num_maps)
    # 将 每一层卷积的特征图,拼接层 5 × 5
    for i in range(0, num_maps):
        feature_map_split = feature_maps[:, :, i]
        feature_map_combination.append(feature_map_split)
        plt.subplot(row, col, i+1)
        plt.imshow(feature_map_split)
        plt.axis('off')

    plt.savefig('./output/relu1_2_feature_map.png') # 保存图像到本地
    plt.show()
feature_maps = np.random.rand(8, 8, 64)
visualize_feature_map(feature_maps)

参考文献:

基于pytorch使用特征图输出进行特征图可视化-CSDN博客

【Pytorch】 特征图的可视化_pytorch 特征图可视化-CSDN博客

深度学习——pytorch卷积神经网络中间特征层可视化_pytorch获取卷积神经网络中间层-CSDN博客

Pytorch 深度学习特征图可视化——(Yolo网络、rcnn)_basicconv-CSDN博客

zhanggong0564/YOLOV3 at d94c249d8d9ec532d2f6cff1a2be183a987c2c7f (github.com) 

计算机视觉特征图可视化与注意力图可视化(持续更新)-CSDN博客

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

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

相关文章

【现代密码学】笔记 补充7-- CCA安全与认证加密《introduction to modern cryphtography》

【现代密码学】笔记7-- CCA安全与认证加密《introduction to modern cryphtography》 写在最前面7 CCA安全与认证加密 写在最前面 主要在 哈工大密码学课程 张宇老师课件 的基础上学习记录笔记。 内容补充:骆婷老师的PPT 《introduction to modern cryphtography》…

【GitHub项目推荐--一行命令下载全网视频】【转载】

项目地址:https://github.com/soimort/you-get 首先声明,请不要使用该项目从事违法活动哦~仅供学习使用! 解决痛点 如果你上网的时候看了一些东西不错,想下载下来,或者在线观看喜欢的视频,但是没有找到网…

坚持刷题|翻转二叉树

坚持刷题,老年痴呆追不上我,今天先刷个简单的:翻转二叉树 题目 226.翻转二叉树 考察点 翻转二叉树又称为镜像二叉树,使用Java实现翻转二叉树通常是为了考察对二叉树的基本操作和递归的理解能力 递归的理解: 能够理解…

【JaveWeb教程】(26) Mybatis基础操作(新增、修改、查询、删除) 详细代码示例讲解(最全面)

目录 1. Mybatis基础操作1.1 需求1.2 准备1.3 删除1.3.1 功能实现1.3.2 日志输入1.3.3 预编译SQL1.3.3.1 介绍1.3.3.2 SQL注入1.3.3.3 参数占位符 1.4 新增1.4.1 基本新增1.4.2 主键返回 1.5 更新1.6 查询1.6.1 根据ID查询1.6.2 数据封装1.6.3 条件查询1.6.4 参数名说明 1. Myb…

大语言模型面试问题【持续更新中】

自己在看面经中遇到的一些面试题,结合自己和理解进行了一下整理。 transformer中求和与归一化中“求和”是什么意思? 求和的意思就是残差层求和,原本的等式为y H(x)转化为y x H(x),这样做的目的是防止网络层数的加深而造成的梯…

Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?直接在yml中配置线程池

在 Spring 中,Async 注解用于将方法标记为异步执行的方法。当使用 Async 注解时,该方法将在单独的线程中执行,而不会阻塞当前线程。这使得方法可以在后台执行,而不会影响主线程的执行。 在您提供的代码示例中,a1() 和…

【conda】pip安装报错,网络延时问题解决记录(亲测有效)

【conda】pip安装报错,网络延时问题解决记录 1. pip install 报错如下所示2. 解决方案: 1. pip install 报错如下所示 pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(hostfiles.pythonhosted.org, port443): Read timed out.…

Spring Boot 中批量执行 SQL 脚本的实践

在Spring Boot应用中,有时候我们需要批量执行存储在数据库中的 SQL 脚本。本文将介绍一个实际的案例,演示如何通过 Spring Boot、MyBatis 和数据库来实现这一目标。 0、数据库层 CREATE TABLE batchUpdate (id INT AUTO_INCREMENT PRIMARY KEY,update_…

现阶段Python和Java哪个更吃香?

现阶段Python和Java哪个更吃香? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「Java的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!&…

基于pyqt5+scapy 根据ip 具体端口 进行扫描 的程序

先给出代码 import sysfrom PyQt5 import uic from PyQt5.QtWidgets import *from scapy.all import * import argparse import logging from scapy.layers.inet import IP, TCP from scapy.sendrecv import sr1class MyWindow(QWidget):def __init__(self):super().__init__(…

2024.1.14周报

目录 摘要 一、文献阅读 1、题目 2、摘要 3、模型架构 4、文献解读 一、Introduction 二、实验 三、结论 二、PINN 一、PINN简介 二、PINN比传统数值方法有哪些优势 三、PINN方法 四、正问题与反问题 总结 摘要 本周我阅读了一篇题目为Deep Residual Learning …

还有人不知道开源知识库吗?低成本搭建就靠它了

在德拉克洛瓦笔下的乔治华盛顿看着蔽日的凯特,可能也没想到他的一句“知识就是力量”会穿越几个世纪,直到互联网时代。在这个信息爆炸的年代,知识管理成为了企业发展的重要支柱,而开源知识库,则成为了低成本搭建公司知…

Git核心知识总结

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 工具教程 ✨特色专栏: MyS…

centos7配置时间同步网络时间

centos7配置时间同步网络时间 1、安装 NTP 工具。 sudo yum install -y ntp2启动 NTP 服务。 sudo systemctl start ntpd3、将 NTP 服务设置为开机自启动。 sudo systemctl enable ntpd4、验证 date

液晶偏振光栅

1、偏振 光是横波.在垂直于光的传播方向的平面内光波振动(即E矢量振动) 各方向振幅都相等的光为自然光; 只在某一方向有光振动的光称为线偏振光;各方向光振动都有,但振幅不同的光叫部分偏振光.螺旋着振动的光称圆偏振光,分旋和右旋 2、庞加莱球表示法 庞加莱球是用…

Java开发或调用WebService的几种方式

Java开发或调用WebService的几种方式 一.JDK自带的 JAX-WS 方式开发WebService服务 1.服务端开发与发布 编写接口 WebService public interface JaxWsDemo {String helloJaxWS(String userName); }编写接口的实现类 WebService public class JaxWsDemoImpl implements Jax…

微服务架构设计核心理论:掌握微服务设计精髓

文章目录 一、微服务与服务治理1、概述2、Two Pizza原则和微服务团队3、主链路规划4、服务治理和微服务生命周期5、微服务架构的网络层搭建6、微服务架构的部署结构7、面试题 二、配置中心1、为什么要配置中心2、配置中心高可用思考 三、服务监控1、业务埋点的技术选型2、用户行…

数据结构学习 leetcode31 下一个排列

关键词:下一个排列 字典序 排列 这是我在做jz38字符串的排序的时候,一种解题方法是字典序,用到的就是这种方法。这种方法支持不重复地输出全排列。 题目:下一个排列 思路: 我看了官方题解和这位大哥的题解&#xff…

聚合收益协议 InsFi :打开铭文赛道全新叙事的旋转门

​“InsFi 协议构建了一套以铭文资产为基础的聚合收益体系,该体系正在为铭文资产捕获流动性、释放价值提供基础,该生态也正在成为铭文赛道掘金的新热土。” 在 2023 年年初,Ordinals 协议在比特币链上被推出后,为比特币链上带来了…

RFID服装物流零售管理系统设计解决方案

一、方案概述 本方案是广东航连科技根据服装企业客户的需求量身定制的解决方案,该方案综合了RFID技术、网络技术、计算机技术、数据库技术和无线通信技术,结合服装企业的实际需求以及航连科技的丰富经验和独特技术,提出了以下基于RFID的物流…