【课程总结】Day11(中):手势图像识别实战(Vgg16和ResNet)

前言

在上一章《【课程总结】Day11(上):手势图像识别实战(LeNet模型)》课程中,我们通过使用LeNet模型实现了手势识别。在本章内容中,我们将搭建Vgg模型和ResNet模型,并应用到手势识别中。

Vgg模型

Vgg简介

VGG是一种深度卷积神经网络模型,由牛津大学的研究团队提出。它在2014年的ImageNet图像分类比赛中获得了第二名的好成绩,被广泛应用于计算机视觉领域。

论文地址:https://arxiv.org/abs/1409.1556

Vgg网络结构图

查看Vgg的论文可以看到Vgg的网络构成如下:

Vgg网络有不同的版本,本次我们使用Vgg16,即为图中D列对应的网络结构。该网络结构换另外一种展示方式如下图所示:

输入层

输入层是一张224×224的RGB图像,通道数为3,通道数代表RGB三个通道的像素值。

第一次卷积

经过2层的64×3×3卷积核,输出输出层为64×224×224

  • 卷积核大小为3×3,步长为1,填充为1
  • 激活函数为ReLU
  • 卷积次数为2
第一次MaxPooling

经过最大池化层,图像尺寸减半,输出尺寸为64×112×112

  • 池化核大小为2×2,步长为2
第二次卷积

经过2层的128×3×3卷积核,输出尺寸为128×112×112

  • 卷积核大小为3×3,步长为1,填充为1
  • 激活函数为ReLU
  • 卷积次数为2
第二次MaxPooling

经过最大池化层,图像尺寸减半,输出尺寸为128×56×56

  • 池化核大小为2×2,步长为2
第三次卷积

经过3层256×3×3卷积核,输出尺寸为256×56×56

  • 卷积核大小为3×3,步长为1,填充为1
  • 激活函数为ReLU
  • 卷积次数为3
第三次MaxPooling

经过最大池化层,图像尺寸减半,输出尺寸为256×28×28

  • 池化核大小为2×2,步长为2
第四次卷积

经过3层512×3×3卷积核,输出尺寸为512×28×28

  • 卷积核大小为3×3,步长为1,填充为1
  • 激活函数为ReLU
  • 卷积次数为3
第四次MaxPooling

经过最大池化层,图像尺寸减半,输出尺寸为512×14×14

  • 池化核大小为2×2,步长为2
第五次卷积

经过3层512×3×3卷积核,输出尺寸为512×14×14

  • 卷积核大小为3×3,步长为1,填充为1
  • 激活函数为ReLU
  • 卷积次数为3
第五次MaxPooling

经过最大池化层,图像尺寸减半,输出尺寸为512×7×7

  • 池化核大小为2×2,步长为2
全连接层

将feature map展平,输出一维尺寸为512×7×7=25088

全链接4096

经过2层的1×1×4096的全连接层,输出尺寸为4096

  • 激活函数为ReLU
  • 全链接次数为2
全链接1000

经过1×1×1000的全连接层,输出尺寸为1000,最后通过softmax函数进行分类,输出1000个预测结果。

1000由最终分类数量决定,当年比赛需要分1000类

Vgg网络特点

  • 小卷积核组:作者通过堆叠多个33的卷积核(少数使用11)来替代大的卷积核,以减少所需参数;
  • 小池化核:相比较于AlexNet使用的33的池化核,VGG全部为22的池化核;
  • 网络更深特征图更宽:卷积核专注于扩大通道数,池化专注于缩小高和宽,使得模型更深更宽的同时,计算量的增加不断放缓;

总结来说,Vgg这种设计可以增加网络的深度,提高特征提取的效果,同时减少了参数数量,降低了过拟合的风险。

Vgg网络搭建

import torch
from torch import nn


class ConvBlock(nn.Module):
    """
        一层卷积:
            - 卷积层
            - 批规范化层
            - 激活层
    """
    def __init__(self, in_channels, out_channels, 
                 kernel_size=3, stride=1, padding=1):
        super().__init__()
        self.conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels,
                             kernel_size=kernel_size, stride=stride,padding=padding)
        self.bn = nn.BatchNorm2d(num_features=out_channels)
        self.relu = nn.ReLU()
    
    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

class Vgg16(nn.Module):
    def __init__(self, n_classes=1000):
        super().__init__()
        # 1, 特征抽取部分
        self.feature_extractor = nn.Sequential(
            
            # stage1
            
            # 卷积1
            ConvBlock(in_channels=3, 
                      out_channels=64, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积2
            ConvBlock(in_channels=64, 
                      out_channels=64, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 池化
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
            
            # stage2
            
            # 卷积1
            ConvBlock(in_channels=64, 
                      out_channels=128, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积2
            ConvBlock(in_channels=128, 
                      out_channels=128, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 池化
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
            
            # stage3
            
            # 卷积1
            ConvBlock(in_channels=128, 
                      out_channels=256, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积2
            ConvBlock(in_channels=256, 
                      out_channels=256, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积3
            ConvBlock(in_channels=256, 
                      out_channels=256, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 池化
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
            
            # stage4
            
            # 卷积1
            ConvBlock(in_channels=256, 
                      out_channels=512, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积2
            ConvBlock(in_channels=512, 
                      out_channels=512, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积3
            ConvBlock(in_channels=512, 
                      out_channels=512, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 池化
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
            
            
            # stage5
            
            # 卷积1
            ConvBlock(in_channels=512, 
                      out_channels=512, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积2
            ConvBlock(in_channels=512, 
                      out_channels=512, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 卷积3
            ConvBlock(in_channels=512, 
                      out_channels=512, 
                      kernel_size=3,
                      stride=1,
                      padding=1),
            # 池化
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
        )
        
        # 2, 分类
        self.classifier = nn.Sequential(
            nn.Flatten(),
            nn.Linear(in_features=7 * 7 * 512, out_features=4096),
            nn.ReLU(),
            nn.Linear(in_features=4096, out_features=4096),
            nn.ReLU(),
            nn.Linear(in_features=4096, out_features=n_classes)
        )
        
    def forward(self, x):
        # 1, 提取特征
        x = self.feature_extractor(x)
        # 2, 分类输出
        x = self.classifier(x)
        return x

手势识别Vgg的应用

在【课程总结】Day11(上):手势图像识别实战(LeNet模型)中,我们已经实现了整体的流程如下:

  1. 数据预处理
    1.1 数据读取
    1.2 数据切分
    1.3 数据规范化
  2. 批量化打包数据
  3. 模型搭建
  4. 筹备训练
  5. 训练模型
    5.1 定义监控指标和方法
    5.2 实现训练过程
    5.3 开始训练

相比LeNet模型的使用过程,我们只需要对模型搭建训练模型模型预测部分进行适当修改即可。

模型搭建

将上述Vgg16模型代码封装到models.py中,然后在训练代码中如下引用即可:

from models import Vgg16
model = Vgg16(n_classes=10)
模型训练

在train()的方法中,修改训练后的模型名称

        # ....(以上代码省略)
        # 保存模型
        if cur_test_acc < test_acc:
            cur_test_acc = test_acc
            # 保存最好模型
            torch.save(obj=model.state_dict(), f="vgg16_best.pt")
        # 保存最后模型
        torch.save(obj=model.state_dict(), f="vgg16_last.pt") 
        

运行结果:

模型预测

在streamlit的前端页面中,修改模型加载部分的代码:


    # 2, 加载模型
    m1 = Vgg16()
    m1.to(device=device)
    # 加载权重
    m1.load_state_dict(state_dict=torch.load(f="vgg16_best.pt", map_location=device),
                    strict=False)
    if not isinstance(m1, Vgg16):
        raise ValueError("模型加载失败")

运行结果:

ResNet模型

ResNet简介

ResNet 网络是在 2015年 由微软实验室中的何凯明等几位大神提出,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名。该网络结构中残差思想,解决了梯度消失和梯度爆炸问题,使得神经网络更多层卷积成为可能。

ResNet引入背景

在ResNet提出之前,所有的神经网络都是通过卷积层和池化层的叠加组成的。
人们认为卷积层和池化层的层数越多,获取到的图片特征信息越全,学习效果也就越好。但是在实际的试验中发现,随着网络层数的增加,梯度在反向传播过程中逐渐变得非常小,导致深层网络难以训练的现象。

备注:关于梯度消失的详细论述不是本章重点,如须了解更详细内容,可以查看
CSDN:ResNet50超详细解析!!!

残差思想

为了避免梯度消失问题,ResNet的关键创新是引入了residual结构(残差结构),将输入信号直接跳过一到多层,与后续层的输出相加,而不是简单地经过一层层的变换。这种设计使得网络可以更轻松地学习残差映射,有助于减轻梯度消失问题。

所谓的残差结构是在正常网络的结构中,增加一个分支结构,这样网络的输出便不再是F\left ( x \right ),而是F\left ( x \right )+x

实线残差结构 VS 虚线残差结构

ResNet由实线残差结构和虚线残差结构两种:

以深层(50/101/152)为例,实线和虚线残差结构如下图所示:

残差结构代码实现

虚线残差结构
import torch
from torch import nn


class ConvBlock(nn.Module):
    """
        虚线块,每一个大的重复逻辑块前面,第一个短接块就是这个
        实现逻辑:
            y = F(x) + Conv(x)
    """
    def __init__(self, in_channels, out_channels, stride):
        # 调用父类初始化方法
        super().__init__()
                
        # 1,核心处理逻辑
        self.stage = nn.Sequential(
            # 1  1 * 1
            nn.Conv2d(in_channels=in_channels,
                     out_channels=out_channels[0],
                     kernel_size=1,
                     stride=stride,
                     padding=0,
                     bias=False),
            nn.BatchNorm2d(num_features=out_channels[0]),
            nn.ReLU(),
            # 2  3 * 3
            nn.Conv2d(in_channels=out_channels[0],
                     out_channels=out_channels[1],
                     kernel_size=3,
                     padding=1,
                     stride=1,
                     bias=False),
            nn.BatchNorm2d(num_features=out_channels[1]),
            nn.ReLU(),
            # 3  1 * 1
            nn.Conv2d(in_channels=out_channels[1],
                     out_channels=out_channels[2],
                     kernel_size=1,
                     stride=1,
                     padding=0,
                     bias=False),
            nn.BatchNorm2d(num_features=out_channels[2]))
        
        # 2,短路层
        self.shortcut = nn.Sequential(
            nn.Conv2d(in_channels=in_channels,
                                   out_channels=out_channels[2],
                                   kernel_size=1,
                                   stride=stride,
                                   padding=0,
                                   bias=False),
            nn.BatchNorm2d(num_features=out_channels[2])
        )
        
        # 3,最后的激活
        self.relu = nn.ReLU()
    
    def forward(self, x):
        # 1,短接处理
        s = self.shortcut(x)
        
        # 2,核心处理
        h = self.stage(x)
        
        # 3,两部分相加 add
        h = h + s
        
        # 4,输出 激活
        o = self.relu(h)
        
        return o
    
实线残差结构
    
class IdentityBlock(nn.Module):
    """
        实线块
            y = F(x) + x
    """
    def __init__(self, in_channels, out_channels):
        super().__init__()
        
        self.stage = nn.Sequential(
            # 1:1 x 1
            nn.Conv2d(in_channels=in_channels,
                     out_channels=out_channels[0],
                     kernel_size=1,
                     padding=0,
                     stride=1,
                     bias=False),
            nn.BatchNorm2d(num_features=out_channels[0]),
            nn.ReLU(),
            
            # 2:3 x 3
            nn.Conv2d(in_channels=out_channels[0],
                     out_channels=out_channels[1],
                     kernel_size=3,
                     padding=1,
                     stride=1,
                     bias=False),
            nn.BatchNorm2d(num_features=out_channels[1]),
            nn.ReLU(),
            
            # 3:1 x 1
            nn.Conv2d(in_channels=out_channels[1],
                     out_channels=out_channels[2],
                     kernel_size=1,
                     padding=0,
                     stride=1,
                     bias=False),
            nn.BatchNorm2d(num_features=out_channels[2])
        )
        
        self.relu = nn.ReLU()
    
    def forward(self, x):
        h = x + self.stage(x)
        o = self.relu(h)  
        return o

对比实线残差结构和虚线残差结构,会发现其主要的不同点在于:
虚线残差结构:

    def forward(self, x):
        # 1,短接处理
        s = self.shortcut(x)
        # 2,核心处理
        h = self.stage(x)
        # 3,两部分相加 add
        h = h + s
        # 4,输出 激活
        o = self.relu(h)
        return o

实线残差结构:

    def forward(self, x):
        h = x + self.stage(x)
        o = self.relu(h)  
        return o

虚线残差结构和实线残差结构都是有效的残差连接方式,有助于解决梯度消失问题,提高深度神经网络的训练效果。

ResNet50

基于引入残差结构的思想,ResNet50模型结构如下图所示:

代码实现
class ResNet50(nn.Module):
    """
        自定义 ResNet50
    """
    def __init__(self, n_classes=1000):
        super(ResNet50, self).__init__()
        self.stage1 = nn.Sequential(
            nn.Conv2d(in_channels=3, 
                     out_channels=64,
                     kernel_size=7,
                     padding=3,
                     stride=2,
                     bias=False),
            nn.BatchNorm2d(num_features=64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3,
                        stride=2,
                        padding=1)
        )
        self.stage2 = nn.Sequential(
            ConvBlock(in_channels=64,
                     out_channels=(64, 64, 256),
                     stride=1),
            IdentityBlock(in_channels=256,
                         out_channels=(64, 64, 256)),
            IdentityBlock(in_channels=256,
                         out_channels=(64, 64, 256)),
        )
        
        self.stage3 = nn.Sequential(
            ConvBlock(in_channels=256,
                      out_channels=(128, 128, 512),
                      stride=2),
            IdentityBlock(in_channels=512,
                         out_channels=(128, 128, 512)),
            IdentityBlock(in_channels=512,
                         out_channels=(128, 128, 512)),
            IdentityBlock(in_channels=512,
                         out_channels=(128, 128, 512))
        )
        
        self.stage4 = nn.Sequential(
            ConvBlock(in_channels=512,
                      out_channels=(256, 256, 1024),
                      stride=2),
            IdentityBlock(in_channels=1024,
                         out_channels=(256, 256, 1024)),
            IdentityBlock(in_channels=1024,
                         out_channels=(256, 256, 1024)),
            IdentityBlock(in_channels=1024,
                         out_channels=(256, 256, 1024)),
            IdentityBlock(in_channels=1024,
                         out_channels=(256, 256, 1024)),
            IdentityBlock(in_channels=1024,
                         out_channels=(256, 256, 1024))
        )
        self.stage5 = nn.Sequential(
            ConvBlock(in_channels=1024,
                      out_channels=(512, 512, 2048),
                      stride=2),
            IdentityBlock(in_channels=2048,
                         out_channels=(512, 512, 2048)),
            IdentityBlock(in_channels=2048,
                         out_channels=(512, 512, 2048))
        )
        self.pool = nn.AdaptiveAvgPool2d(output_size=(1, 1))
        
        self.fc = nn.Linear(in_features=2048,
                           out_features=n_classes)
    def forward(self, x):
        h = self.stage1(x)
        h = self.stage2(h)
        h = self.stage3(h)
        h = self.stage4(h)
        h = self.stage5(h)
        h = self.pool(h)
        h = h.view(h.size(0), -1)
        o = self.fc(h)
        return o

手势识别ResNet50的应用

类比Vgg16的手势识别的代码实现,我们修改以下相关内容

模型搭建

将上述Vgg16模型代码封装到models.py中,然后在训练代码中如下引用即可:

from models import ResNet50
model = ResNet50(n_classes=10)
模型训练

在train()的方法中,修改训练后的模型名称

        # ....(以上代码省略)
        # 保存模型
        if cur_test_acc < test_acc:
            cur_test_acc = test_acc
            # 保存最好模型
            torch.save(obj=model.state_dict(), f="resnet50_best.pt")
        # 保存最后模型
        torch.save(obj=model.state_dict(), f="resnet50_last.pt") 
        

运行结果:

对比LeNet、Vgg16、ResNet50对比:

  • Vgg16模型文件最大,LeNet模型文件最小,ResNet50模型文件适中
  • Vgg16训练提升速度最快,在第4轮就已经达到90%的准确率

内容小结

  • VGG是一种深度卷积神经网络模型,由牛津大学的研究团队提出。
  • VGG的主要特点是更多层的卷积,同时采用了3x3卷积核,来替代大的卷积核,以减少所需参数。
  • ResNet50是一种深度残差网络模型,由Microsoft Research团队提出。
  • ResNet50中最核心的思想是引入残差结构,通过残差结构解决了梯度消失问题,从而提高了深度神经网络的训练效果。

参考资料

CSDN:VGG网络讲解——小白也能懂

CSDN:VGG 经典神经网络学习笔记 (附代码)

CSDN:ResNet50超详细解析!!!

知乎:ResNet(深度残差网络)原理及代码实现(基于Pytorch)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

egg代码生成器

今天给大家分享一下egg的代码生成器&#xff0c;这个其实原理很简单&#xff0c;说白了就是用到了nodejs的一个文件io的操作&#xff0c;通过一系列配置参数解析然后生成一个很长的字符串&#xff0c;写入到文件中&#xff0c;最后导出到我们指定的文件夹。 前提概要 为什么我…

网工内推 | 国企信息工程师,信息系统项目管理师优先,最高14薪

01 上海浦东软件园股份有限公司 &#x1f537;招聘岗位&#xff1a;信息化管理工程师 &#x1f537;岗位职责&#xff1a; 1. 根据公司战略、数字化总体架构规划和IT 技术趋势&#xff0c;制定信息化系统的规划与设计&#xff0c;并制定实施计划。 2. 统筹公司信息化系统管理…

【Linux详解】进程的状态 | 运行 阻塞 挂起 | 僵尸和孤儿状态

目录 操作系统中 运行状态 阻塞状态 进程状态转换 Linux系统中 查看进程状态 深度睡眠状态 T 暂停状态 Z 僵尸状态 孤儿状态 文章手稿 xmind: 引言 介绍系统中的进程状态及其管理方式。将通过结合操作系统原理和实际代码示例&#xff0c;详细说明进程的各种状态、转换…

Java Stream API揭秘:掌握List流操作,打造高效数据处理流程

序言 Java Stream API是Java 8中引入的一个非常重要的功能组成部分&#xff0c;它提供了一种声明式的处理数据集合的方法。它主要特点是基于函数式编程的理念&#xff0c;允许我们以更加简洁、高效的方式进行集合的处理、转换和过滤。通过Stream API&#xff0c;我们可以灵活地…

暗黑4PTR怎么参与测试 暗黑4第五赛季怎么参加PTR测试教程

暗黑破坏神4作为暗黑破坏神系列的最新作品&#xff0c;自从2023年上线就受到了一众好评。游戏是动作冒险类角色扮演游戏&#xff0c;游戏的背景设定在一个腐化的圣休瑞亚大陆上&#xff0c;玩家们可以五种职业中选择自己喜爱的游戏进行游戏。 暗黑破坏神4第五赛季现在已经开启P…

机器学习数学原理专题——线性分类模型:损失函数推导新视角——交叉熵

目录 二、从回归到线性分类模型&#xff1a;分类 3.分类模型损失函数推导——极大似然估计法 &#xff08;1&#xff09;二分类损失函数——极大似然估计 &#xff08;2&#xff09;多分类损失函数——极大似然估计 4.模型损失函数推导新视角——交叉熵 &#xff08;1&#x…

SpringCloud_GateWay服务网关

网关作用 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由和负载均衡&#xff1a;一切请求都必须先经过gateway&#xff0c;但网关不处理业务&#xff0c;而是根据某种规则&#xff0c;把请求转发到某个微服务&a…

Python数据分析-糖尿病数据集数据分析

一、研究背景介绍 糖尿病是美国最普遍的慢性病之一&#xff0c;每年影响数百万美国人&#xff0c;并对经济造成重大的经济负担。糖尿病是一种严重的慢性疾病&#xff0c;其中个体失去有效调节血液中葡萄糖水平的能力&#xff0c;并可能导致生活质量和预期寿命下降。。。。糖尿…

如何借助物联网实现土壤监测与保护

如何借助物联网实现土壤监测与保护 高标准农田信息化是指利用现代信息技术&#xff0c;如物联网、大数据、云计算等&#xff0c;对农田进行数字化、智能化的管理&#xff0c;以提高农田的生产效率和可持续发展能力。其中&#xff0c;土壤监测与保护是农田信息化的重要内容之一…

解决SD卡被写保护问题

存储卡在使用过程中&#xff0c;有时会遇到写保护问题&#xff0c;导致无法写入或删除数据。这可能会对用户的正常使用造成困扰。MK米客方德将为您介绍几种常见的解决方法&#xff0c;帮助用户解除存储卡的写保护。 一、检查物理写保护开关 许多存储卡&#xff0c;如SD卡&…

JavaScript的学习之dom的查询(一)

一、获得元素 通过document对象调用&#xff1a; getElementById()&#xff1a;通过id属性获取一个元素节点对象getElementsByTagName()&#xff1a;通过标签名获取一组元素节点对象getElementsByName()&#xff1a;通过name属性来获取一组元素节点对象 核心学习代码 <scrip…

【UE5.3】笔记3-静态网格体,BSP

静态网格体组件 主要有两个属性 一个是静态网格体&#xff1a;对应的也就是模型&#xff0c;比如fbx&#xff0c;maya&#xff0c;obj等格式 一个是材质&#xff1a;由各种贴图、渲染设置等&#xff0c;比如unity里的shader BSP画刷&#xff1a; 打开放置Actor选项卡&#…

QT中子工程的创建,以及如何在含有库的子工程项目中引用主项目中的qt资源

1、背景 在qt中创建多项目类型,如下: CustomDll表示其中的一个动态库子项目; CustomLib表示其中的一个静态库子项目; MyWidget表示主项目窗口(main函数所在项目); 2、qrc资源的共享 如何在CustomDll和CustomLib等子项目中也同样使用 MyWidget项目中的qrc资源呢??? 直…

MySQL 7种Join的定义图解示范结果(所有join类型)

文章目录 MySQL 7种Join的定义&图解&示范&结果&#xff08;所有join类型&#xff09;基本知识笛卡尔积 建表&填充数据1-Join不带条件account筛选 1-Inner Join 内连接不带条件account相同where筛选玩点特殊的 2-Left Join 左连接不带条件account筛选 3-Right J…

神经网络学习8-反向传播

back propagation 拿到前面传回来的L对z的偏导&#xff0c;再分别算损失值对x和w的偏导 反向传播 前馈过程求局部梯度 反向传播 这里的loss&#xff08;wxb-y)^2,第一个关于b的偏导为2(wxb-y),第二个关于w的为2w(wxb-y)

业绩尚可但股价不振,浙商银行陆建强闯“3元大关”

&#xff08;题图&#xff09; 文&#xff5c;新熔财经 作者&#xff5c;宏一 本来做着钱生钱的“美梦”&#xff0c;现在倒好&#xff0c;本金都不一定拿得回来。 因为不想把“鸡蛋都放在一个笼子里”&#xff0c;所以前几年在理财的时候一部分放在银行定存&#xff0c;一…

Sum of Single Effects Linear Regression (susieR):多个因果变异位点的鉴定

使用susieR鉴定多个因果变异位点只需要两个输入文件&#xff0c;一个输入文件是包含Zscore值的SNP位点&#xff08;zscore.txt&#xff09;&#xff0c;另一个文件是LD matrix&#xff08;LD.matrix.ld&#xff09;。 zscore.txt 文件如下所示&#xff1a; LD.matrix.ld 文件…

Vue DevTools

介绍 什么是 Vue DevTools&#xff1f; Vue DevTools 是一款旨在增强 Vue 开发者体验的工具&#xff0c;它是一款功能强大且用途广泛的工具&#xff0c;可以在使用 Vue 应用程序时显着提高您的生产力和调试能力。它的实时编辑、时间旅行调试和全面检查功能使其成为任何Vue.js开…

程序员如何用ChatGPT解决常见编程问题:实例解析

引言 在现代编程的世界中&#xff0c;技术进步日新月异&#xff0c;程序员们面临着各种各样的挑战和问题。解决这些问题的过程中&#xff0c;找到合适的工具至关重要。ChatGPT作为一种先进的人工智能语言模型&#xff0c;能够帮助程序员迅速、高效地解决常见的编程问题。本文将…

基于SpringBoot的学生综合测评系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架 工具&#xff1a;MyEclipse、Tomcat 系统展示 首页 系统首页&#xff0c;提供综合…