1.9学习日记

2025-1.9 实习学习日记 弱网测试 在网络通信中,抓包地址通常是指捕获网络数据包的源地址、目的地址或经过的中间节点(如网关)的IP地址。当软件与服务器或其他设备进行通信时,数据会在网络中传输,这些数据包含了源IP地址(发送数据的设备的地址)和目的IP地址(接收数据的设备的地址)。抓包工具就是用来捕获这些数据包,并显示其中的详细信息,包括这些地址信息。- 例如,在一个简单的网页浏览场景中,你的电脑(客户端)通过浏览器访问一个网站服务器。电脑的IP地址就是源IP地址,网站服务器的IP地址就是目的IP地址。 阅读详情

今天继续学习食物分类

图片分类的模型最重要的就是设计维度变化

优化器

        Adam和AdamW——SGD

        1.梯度的改变

        SGD只看当前点的梯度

        Adam = \Theta * old + (1- \Theta )*new

        2.学习率的改变

        Adam会自动调整学习率,是动态调整的过程,相对与SGD较难出现模型坍塌、梯度爆炸的问题。Adam的鲁棒性和稳定性通常优于SGD。

        AdamW,W就是weight decay,权重衰减

optimzer = torch.optim.AdamW(model.parameters(), lr=lr, weight_decay=1e-4)      #优化器

训练函数

#训练函数
def train_val(model, train_loader, val_loader, device, epochs, optimizer, loss, save_path):
    model = model.to(device)

    plt_train_loss = [] #记录所有轮次的loss
    plt_val_loss = []

    plt_train_acc = []  #记录准确率
    plt_val_acc = []

    max_acc = 0.0   #保存准确率最高的模型

    for epoch in range(epochs):   #冲锋的号角
        train_loss = 0.0
        val_loss = 0.0
        train_acc = 0.0
        val_acc = 0.0
        start_time = time.time()

        model.train()     #模型调为训练模式
        for batch_x, batch_y in train_loader:
            x, target = batch_x.to(device), batch_y.to(device)
            pred = model(x)
            train_bat_loss = loss(pred, target)
            train_bat_loss.backward()
            optimizer.step() #更新模型的作用
            optimizer.zero_grad()
            train_loss += train_bat_loss.cpu().item()
            train_acc += np.sum(np.argmax(pred.detach().cpu().numpy(), axis=1) == target.cpu().numpy())

        plt_train_loss.append(train_loss / train_loader.__len__())
        plt_train_acc.append(train_acc / train_loader.dataset.__len__())    #记录准确率

        model.eval()
        with torch.no_grad():
            for batch_x, batch_y in val_loader:
                x, target = batch_x.to(device), batch_y.to(device)
                pred = model(x)
                val_bat_loss = loss(pred, target)
                val_loss += val_bat_loss.cpu().item()
                val_acc += np.sum(np.argmax(pred.detach().cpu().numpy(), axis=1) == target.cpu().numpy())
        plt_val_loss.append(val_loss/ val_loader.__len__())
        plt_val_acc.append(val_acc / val_loader.dataset.__len__())
        if val_acc > max_acc:
            torch.save(model, save_path)
            max_acc = val_loss

        print("[%03d/%03d] %2.2f sec(s) Trainloss: %.6f |Valloss: %.6f Trainacc: %.6f |Valacc: %.6f" % \
              (epoch, epochs, time.time()-start_time, plt_train_loss[-1], plt_val_loss[-1], plt_train_acc[-1], plt_val_acc[-1]))


    plt.plot(plt_train_loss)
    plt.plot(plt_val_loss)
    plt.title("loss")
    plt.legend(["train", "val"])
    plt.show()

    plt.plot(plt_train_acc)
    plt.plot(plt_val_acc)
    plt.title("acc")
    plt.legend(["train", "val"])
    plt.show()

train_acc += np.sum(np.argmax(pred.detach().cpu().numpy(), axis=1) == target.cpu().numpy())

        argmax():取最大值的下标,axis=1:沿纵向求

        sum之中的函数就是判断pred预测值与target的值是否相等,返回true/false的矩阵

        np.sum()再对得出的true=1/false=0纵向求和

        train_acc就是看每轮预测对的数量

迁移学习

        数据量少时的最佳选择。

        迁移学习(Transfer Learning)是一种强大的机器学习方法,其核心思想是将在一个任务(源任务)上学到的知识或模型迁移到另一个相关任务(目标任务)上,以提高新任务的性能。这种方法充分利用了已有的数据和模型资源,减少了目标任务对大量新数据的依赖,加快了模型训练速度,并提高了模型的泛化能力。

结束!

import random
import torch
import torch.nn as nn
import numpy as np
import os
from PIL import Image #读取文件数据
from torch.utils.data import Dataset, DataLoader
from tqdm import tqdm  #查看读取进度
from torchvision import transforms
import time
import matplotlib.pyplot as plt
from model_utils.model import initialize_model

def seed_everything(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.benchmark = False
    torch.backends.cudnn.deterministic = True
    random.seed(seed)
    np.random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
#################################################################
seed_everything(0)
###############################################


HW = 224 #深度学习领域一般让图片大小为224,而文件中的图片是512*512
#读文件
def read_file(path):
    for i in tqdm(range(11)):
        file_dir = path + "/%02d"%i
        file_list = os.listdir(file_dir)   #列出文件夹下所有文件名字

        xi = np.zeros((len(file_list),HW,HW,3), dtype=np.uint8) #读为整型
        yi = np.zeros(len(file_list), dtype=np.uint8)

        for j, img_name in enumerate(file_list):   #enumerate()既可以读到下标,也可以读到内容
            img_path = os.path.join(file_dir, img_name)
            img = Image.open(img_path)
            img = img.resize((HW,HW))
            xi[j, ...] = img   #...表示后面的维度表示一致,把图片放到第j个
            yi[j] = i  #标签

        # 把所有的xi,yi在0维合并
        if i == 0:
            X = xi
            Y = yi
        else:
            X = np.concatenate((X, xi), axis=0)
            Y = np.concatenate((Y, yi), axis=0)

    print("读到了%d个数据"%len(Y))
    return X,Y


#数据变换   训练集和验证集的数据变换不同,验证和测试的时候要用原图,训练的时候才需要不同的数据变换进行训练
train_transform = transforms.Compose(
    [
        transforms.ToPILImage(),    #图片为224*224*3,模型需要3*224*224
        transforms.RandomResizedCrop(224),  #对图片随机放大裁切
        transforms.RandomRotation(50),  #对图片50°以内随机旋转
        transforms.ToTensor()   #变为张量进行模型运行
    ]
)

val_transform = transforms.Compose(
    [
        transforms.ToPILImage(),    #图片为224*224*3,模型需要3*224*224
        transforms.ToTensor()   #变为张量进行模型运行
    ]
)



#定义数据集
class food_Dataset(Dataset):
    def __init__(self, path, mode="train"):    #初始化,传入地址,得到数据集x和标签y
        self.X, self.Y = read_file(path)
        self.Y = torch.LongTensor(self.Y)  #标签转为长整型
        if mode == "train":
            self.transform = train_transform   #数据增广
        else:
            self.transform = val_transform

    def __getitem__(self, item):
        return self.transform(self.X[item]), self.Y[item]

    def __len__(self):
        return len(self.Y)




#模型
class myModel(nn.Module):
    def __init__(self, num_class):  #搭建模型框架
        super(myModel, self).__init__()
        #图片输入为3*224*224,要变为512*7*7,然后拉直、全连接、分类
        self.conv1 = nn.Conv2d(3, 64, 3, 1, 1)   #64*224*224
        self.bn1 = nn.BatchNorm2d(64)   #归一化
        self.relu = nn.ReLU()
        self.pool1 = nn.MaxPool2d(2)    #64*112*112

        self.layer1 = nn.Sequential(    #这样合并更方便,且美观
            nn.Conv2d(64, 128, 3, 1, 1),   #128*112*112
            nn.BatchNorm2d(128),   #归一化
            nn.ReLU(),
            nn.MaxPool2d(2)    #127*56*56
        )

        self.layer2 = nn.Sequential(
            nn.Conv2d(128, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.MaxPool2d(2)    #256*28*28
        )

        self.layer3 = nn.Sequential(
            nn.Conv2d(256, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.MaxPool2d(2)  #512*14*14
        )

        self.pool2 = nn.MaxPool2d(2)    #512*7*7
        self.fc1 = nn.Linear(25088, 1000)   #卷积 25088->1000
        self.relu2 = nn.ReLU()
        self.fc2 = nn.Linear(1000, num_class)   #1000->num_class(11)


    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.pool1(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.pool2(x)
        x = x.view(x.size()[0], -1)     #拉直
        x = self.fc1(x)
        x = self.relu2(x)
        x = self.fc2(x)
        return x


#训练函数
def train_val(model, train_loader, val_loader, device, epochs, optimizer, loss, save_path):
    model = model.to(device)

    plt_train_loss = [] #记录所有轮次的loss
    plt_val_loss = []

    plt_train_acc = []  #记录准确率
    plt_val_acc = []

    max_acc = 0.0   #保存准确率最高的模型

    for epoch in range(epochs):   #冲锋的号角
        train_loss = 0.0
        val_loss = 0.0
        train_acc = 0.0
        val_acc = 0.0
        start_time = time.time()

        model.train()     #模型调为训练模式
        for batch_x, batch_y in train_loader:
            x, target = batch_x.to(device), batch_y.to(device)
            pred = model(x)
            train_bat_loss = loss(pred, target)
            train_bat_loss.backward()
            optimizer.step() #更新模型的作用
            optimizer.zero_grad()
            train_loss += train_bat_loss.cpu().item()
            train_acc += np.sum(np.argmax(pred.detach().cpu().numpy(), axis=1) == target.cpu().numpy())

        plt_train_loss.append(train_loss / train_loader.__len__())
        plt_train_acc.append(train_acc / train_loader.dataset.__len__())    #记录准确率

        model.eval()
        with torch.no_grad():
            for batch_x, batch_y in val_loader:
                x, target = batch_x.to(device), batch_y.to(device)
                pred = model(x)
                val_bat_loss = loss(pred, target)
                val_loss += val_bat_loss.cpu().item()
                val_acc += np.sum(np.argmax(pred.detach().cpu().numpy(), axis=1) == target.cpu().numpy())
        plt_val_loss.append(val_loss/ val_loader.__len__())
        plt_val_acc.append(val_acc / val_loader.dataset.__len__())
        if val_acc > max_acc:
            torch.save(model, save_path)
            max_acc = val_loss

        print("[%03d/%03d] %2.2f sec(s) Trainloss: %.6f |Valloss: %.6f Trainacc: %.6f |Valacc: %.6f" % \
              (epoch, epochs, time.time()-start_time, plt_train_loss[-1], plt_val_loss[-1], plt_train_acc[-1], plt_val_acc[-1]))


    plt.plot(plt_train_loss)
    plt.plot(plt_val_loss)
    plt.title("loss")
    plt.legend(["train", "val"])
    plt.show()

    plt.plot(plt_train_acc)
    plt.plot(plt_val_acc)
    plt.title("acc")
    plt.legend(["train", "val"])
    plt.show()


# path = r"D:\大学\学习\深度学习\课程代码\第四五节_分类代码\food_classification\food-11\training\labeled"   #训练数据的路径,r能去除转义字符的作用
# train_path = r"D:\大学\学习\深度学习\课程代码\第四五节_分类代码\food_classification\food-11\training\labeled"
# val_path = r"D:\大学\学习\深度学习\课程代码\第四五节_分类代码\food_classification\food-11\validation"
train_path = r"D:\大学\学习\深度学习\课程代码\第四五节_分类代码\food_classification\food-11_sample\training\labeled"
val_path = r"D:\大学\学习\深度学习\课程代码\第四五节_分类代码\food_classification\food-11_sample\validation"

#读数据集
train_set = food_Dataset(train_path, "train")
val_set = food_Dataset(val_path, "val")

train_loader = DataLoader(train_set, batch_size=16, shuffle=True)    #train_loader把train_set变为一批数据
val_loader = DataLoader(val_set, batch_size=16, shuffle=True)


# model = myModel(11)

#用大佬们的模型
# from torchvision.models import resnet18
# model = resnet18(pretrained=True)   #pretrained=True用架构和参数,=False时则从0开始训练
# in_features = model.fc.in_features      #替换分类头
# model.fc = nn.Linear(in_features, 11)   #把模型的分类头改为自己的输入维度11

#引用模型
model = initialize_model("resnet18", 11, use_pretrained=True)

lr = 0.001  #学习率
loss = nn.CrossEntropyLoss()   #损失用交叉熵损失
optimizer = torch.optim.AdamW(model.parameters(), lr=lr, weight_decay=1e-4)      #优化器
device = "cuda" if torch.cuda.is_available() else "cpu" #设备
save_path = "model_save/best_model_zhou.pth"   #保存最好的模型
epochs = 15     #训练轮次

train_val(model, train_loader, val_loader, device, epochs, optimizer, loss, save_path)

22、狭义相对论与曲线坐标空间相关知识解析 本文深入解析了狭义相对论与曲线坐标空间的核心概念,涵盖能量-动量张量的定义与守恒、曲线坐标系下的度量张量与基向量性质、协变与逆变张量的变换规则,并介绍了克里斯托费尔符号与协变导数的计算方法。进一步探讨了在弯曲空间中进行微积分运算的基础理论及其在广义相对论中的关键应用,如爱因斯坦场方程如何描述物质-能量对时空曲率的影响,为理解黑洞等引力现象提供了理论框架。 阅读详情

相关推荐

Circos在Windows下的安装教程

这里写自定义目录标题Circos简介安装Perl 的安装Circos安装安装及解压安装Modules测试用例官方文档 Circos简介 (来源官网:http://circos.ca/software/readme/ O.INTRODUCTION部分) Circos is a program for the generation of publication-quality, circularly composited renditions of genomic data and related annot

qq_42318911的博客 1661

2024年大二上学习日记9.1-9.2

加过渡属性最好不要加在标签上(如h1),变换的时候不知道为什么会怪异地从‘天’飞下来,走了偏离的路线,用xxx-enter-active和xxx-leave-active就正常了。如:Category.vue通过slot给App.vue传递需要用到的数据,传递的数据类型是对象(因为传递的数据可能有多个)在public文件夹下新建一个text.txt文件,修改axios.get中的地址,可以成功请求text.txt中的数据。元素进入的起点就是离开的终点,元素离开的起点就是进入的终点,实现一个轮回的效果。

2401_84827689的博客 938

智能车竞赛轮腿穿越组:GPS+IMU导航绕桩实战技巧(附避坑指南)

本文详细介绍了智能车竞赛轮腿穿越组中GPS+IMU导航绕桩的实战技巧,包括硬件选型、传感器标定、路径规划及多传感器数据融合策略。通过实际案例和避坑指南,帮助参赛队伍提升导航精度和稳定性,避免常见错误。特别强调IMU安装位置和标定对导航系统的重要性。

gin88的博客 584

学习日记1/9我直接被锤

kmp的模板(只有模板没有讲解)

jdjdhdha的博客 81

用Python玩转Milvus:从安装SDK到完成第一个向量搜索Demo

本文为Python开发者提供了一份详细的Milvus向量数据库实战指南。文章重点讲解了如何规避版本兼容性陷阱,正确部署Milvus服务端并安装匹配的Python SDK。通过一个电影推荐系统的完整案例,演示了从数据建模、集合创建、向量插入、索引构建到执行混合搜索的全流程,帮助开发者快速上手并完成第一个向量搜索Demo。

weixin_29239279的博客 192

C# 异步编程详解(Task,async/await)

同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。异步的好处在于非阻塞(调用线程不会暂停执行去等待子线程完成),因此我们把一些不需要立即使用结果、较耗时的任务设为异步执行,可以提高程序的运行效率。

luxingyu329的博客 4154

学习日记(1.9)

学习日记(kmp)

qq_74455082的博客 115

用户行为路径可视化_桑葚图(Sankey)

桑基图对用户行为路径可视化的blog学习笔记。

徐思孟的博客 3855

机器学习日记2017.1.9

(《机器学习系统设计》第一章) 一、学习简单的Numpy、Scipy用法 Numpy:数组维数转换reshape()、对数组操作能传递到每一个元素、索引np.array()、修剪函数clip()、清洗~np.isnan() Scipy工具包: 二、练习第一个(极小的)的机器学习应用   1.读取数据(一个月的web请求统计信息) import scipy as sp da

qq_27396789的博客 348

c语言版数据结构课程设计 学生成绩管理系统

此学生成绩管理系统完成15项功能,是我经过很多次的修改得到的。花费时间不短,功能齐全,主要完成了:输入,输出,插入,修改,删除,查询,读取文件,写入文件,复制文件,建立索引,显示各种情况下的信息,追加学生信息等等功能。一共15项。   代码如下: // shujujiegou.cpp : 定义控制台应用程序的入口点。///**本程序采用数组链表形式,原因:数组查询速度快,数组也能实现动态存储

Java 1万+

三菱FX5U系列PLC与汇川IT6000系列触摸屏进行MODBUS TCP通信的具体方法

三菱FX5U系列PLC与汇川IT6000系列触摸屏进行MODBUS TCP通信的具体方法

Robot_PLC_HMI_Automation 6515

python基础学习日记---1.9

学习到了while循环嵌套的使用和random伪随机数库的学习。random伪随机数库的值可以重现。

m0_63078568的博客 238

华为ensp、思科eve、华为ensp pro中通过cloud桥接本地网络和联通互联网的方法

华为ensp、思科eve中通过cloud桥接本地网络和联通互联网的方法

suofen9703的博客 417

学习日记-spring-day47-9.1

知识点核心内容重点事务传播机制种类介绍事务传播属性的七种类型,重点前两种:required和requires newrequired vs requires new的区别required传播属性如果当前有事务运行,则在当前事务内执行;否则启动新事务嵌套事务是否回滚取决于外层事务requires new传播属性无论当前是否有事务,都启动新事务,并挂起现有事务(若存在)嵌套事务独立提交/回滚,互不影响事务传播示例(required)

qq_59714927的博客 1208

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

2023.9.19日记:JDBC的学习1

学习转载:JDBC基础知识_jdbc协议_随逸星的博客-优快云博客

m0_55856577的博客 88

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

OpenCV 学习日记-写在前面(1) 2014.9.20

2014.8.31 我对于计算机视觉有一定的兴趣,打算学习一下opencv,并在此记录一下自己的学习过程。我打算把自己的学习总结和自己写的历程都记录下来,再变成pdf放到网上供大家学习之用。我打算在学习一下android再将android和opencv结合起来,运用android环境来运行opencv实现智能手机的计算机视觉。           最好能便一本书《当opencv遇上android》

31号楼的某个房间 683

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Linux学习日记 Day 9 - FTP(1)

1、挂载光盘 2、修改光盘挂载路径 3、进入仓库路径并编写仓库 4、安装FTP的软件包 5、关闭防火墙 6、关闭selinux 7、修改主配置文件 8、重启服务 9、验证

m0_66650174的博客 498

FPGA学习日记(9-1) 分频器——偶分频

module divider_six ( input wire sys_clk, input wire sys_rst_n, output reg clk_out ); reg [1:0] cnt; always@(posedge sys_clk or negedge sys_rst_n)//使用异步复位 if(sys_rst_n == 1'b0) cnt <= 2'd0; else if(cnt == 2'd2) ...

jsomin的博客 295

2023.9.14日记:学习前端基础相关知识1

学习转载:CSS3新增样式 - 知乎

m0_55856577的博客 69

2023.9.7日记:学习MySQL相关知识1

学习链接,转载:小白 mysql5.7 安装版本配置教程+百度云资源分享_程序东的博客-优快云博客史上最详细、最良心的MySQL 5.7 + Navicat 下载安装教程(附安装包)_navicat下载包_P D C9527的博客-优快云博客

m0_55856577的博客 87

《算法笔记》学习日记——9.1 树与二叉树&9.2 二叉树的遍历

目录9.1 树与二叉树9.2 二叉树的遍历问题 A: 复原二叉树问题 B: 二叉树问题 C: 二叉树遍历问题 D: 二叉树遍历小结 9.1 树与二叉树 Codeup Contest ID:100000610 PS:本节是二叉树概念的讲述,没有相关习题。 9.2 二叉树的遍历 Codeup Contest ID:100000611 问题 A: 复原二叉树 题目描述 小明在做数据结构的作业,其中一题是...

一只奋斗中的本科生 504

黑马程序员-学习日记9(集合框架 1 )

-------android培训、java培训、期待与您交流! ----------         TreeSet:  Set:无序,不可以重复元素。  |--HashSet: 数据结构是哈希表,线程是非同步的。     保证元素唯一性的原理:判断元素的hashCode值是否相同。     如果相同,还会继

449

Python学习日记-9-homework-1-购物车

price = [7500,8000,32,80,1500] name = [&quot;iphone x&quot;,&quot;mac book&quot;,&quot;coffee&quot;,&quot;book&quot;,&quot;bike&quot;] thing = [0,0,0,0,0] msg_1 = ''' --------------------- 1.iphone x 7500 2.mac bo

wuli_xiaoran的博客 191

从零开始的数据结构学习日记(九)——1.9KMP算法

1.1KMP算法 先给出KMP算法伪代码: 1.在目标串T和模式串P中分别设置比较的起始下标i和j 2.当(i<n&&j<m)时,重复以下操作,直到目标串T或者模式串P的字符都比较完毕 ——2.1如果T[i]等于p[i],则继续比较T和P的下一对字符 ——2.2否则将模式串P的下标j回溯到P中的next[j]位置,即j=next[j] ——2.3如果j=-1,则将下标i...

sakaili的博客 589

【1个月速成Java】基于Android平台开发个人记账app学习日记——第9天,明细页面初步设计

GitHub - Messimeimei/PersonalExpenseTracker: 通过Java开发个人记账Android的app实现一个月速成Java语言通过Java开发个人记账Android的app实现一个月速成Java语言. Contribute to Messimeimei/PersonalExpenseTracker development by creating an account on GitHub.

榕城候佳人的博客 1035

前端学习(HTML)日记 day.9(2023.1.21-2023.1.22)

HTML5学习笔记

m0_74149002的博客 174
上一篇: 1.8学习日记
下一篇: 1.12学习日记
紫薯粥zzz
博客等级 码龄5年 32粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值