pytorch深度学习基础(八)——线性回归

educoder机器学习 --- 线性回归 第1关:简单线性回归与多元线性回归 1、BC 2、ABC 3、A 第2关:线性回归的正规方程解 #encoding=utf8 import numpy as np def mse_score(y_predict,y_test): ''' input:y_predict(ndarray):预测值 y_test(ndarray):真实值 ouput:mse(float):mse损失函数值 ''' #********* Begin ********* 阅读详情


引言

我们生活中可能会遇到形如

y = w 1 x 1 + w 2 x 2 + w 3 x 3 + b y=w_1x_1+w_2x_2+w_3x_3+b y=w1​x1​+w2​x2​+w3​x3​+b

的问题,其中有y为输出,x为输入,w为权值,b为偏置

假设我们有一个房价预测的问题,我们有很多条数据,每一个数据项有很多特征,这些特征就是x,而房价就是y,线性回归要解决的就是得出一批合适的w和b来实现x向y的映射,使得我们得到x时就可以预测出y。

损失函数

为了求得权值和偏置的最优值,我们需要定义损失函数,通过降低损失函数的损失进行权值和偏置的优化,我们常用的有如下三种损失值
均方误差
l ( w , b ) = 1 2 ( x w + b − y ) 2 l(w, b)=\frac{1}{2}(xw+b-y)^2 l(w,b)=21​(xw+b−y)2
这里的1/2并没有什么含义,只是为了求导后计算方便
在多个样本上可以表述为
L ( W , b ) = 1 2 n ∑ i = 1 n ( X ( i ) W + b − Y ( i ) ) 2 L(W, b)= \frac{1}{2n}\sum_{i=1}^n(X^{(i)}W+b-Y^{(i)})^2 L(W,b)=2n1​i=1∑n​(X(i)W+b−Y(i))2
同时为了方便处理,通常我们会在数据后加一列1,这样偏置也会并入到权值当中,即

[ x 1 ( 1 ) x 2 ( 1 ) 1 x 1 ( 2 ) x 2 ( 2 ) 1 x 1 ( 3 ) x 2 ( 3 ) 1 ] ⋅ [ w 1 w 2 b ] = [ y ( 1 ) y ( 2 ) y ( 3 ) ] \begin{bmatrix} x_1^{(1)}&x_2^{(1)}&1\\ x_1^{(2)}&x_2^{(2)}&1\\ x_1^{(3)}&x_2^{(3)}&1\\ \end{bmatrix} \cdot \begin{bmatrix} w_1 \\ w_2 \\ b \end{bmatrix}= \begin{bmatrix} y^{(1)} \\ y^{(2)} \\ y^{(3)} \end{bmatrix} ​x1(1)​x1(2)​x1(3)​​x2(1)​x2(2)​x2(3)​​111​ ​⋅ ​w1​w2​b​ ​= ​y(1)y(2)y(3)​ ​
我们令
注:为了方便表示,这里用三个数据,每个数据有两个数据项的数据表示

我们令
W = [ w 1 w 2 b ] W=\begin{bmatrix} w_1 \\ w_2 \\ b \end{bmatrix} W= ​w1​w2​b​ ​
那么我们的均方误差就变成了
L ( W , b ) = 1 2 n ∑ i = 1 n ( X ( i ) W − Y ( i ) ) 2 L(W, b)= \frac{1}{2n}\sum_{i=1}^n(X^{(i)}W-Y^{(i)})^2 L(W,b)=2n1​i=1∑n​(X(i)W−Y(i))2

解析解

线性回归问题存在解析解

公式

首先我们在L上对W求导
∇ w L = 1 n ∑ i = 1 n ( X ( i ) W − Y ( i ) ) T X ( i ) \nabla _wL= \frac{1}{n} \sum_{i=1}^n(X^{(i)}W-Y^{(i)})^{T}X^{(i)} ∇w​L=n1​i=1∑n​(X(i)W−Y(i))TX(i)
最优的解即为L=0的解,即
W ( ∗ ) T X ( i ) T X ( i ) − Y ( i ) T X ( i ) = 0 ⇒ W ( ∗ ) T = Y ( i ) T X ( i ) ( X ( i ) T X ( i ) ) − 1 ⇒ W ( ∗ ) = ( X ( i ) T X ( i ) ) − 1 X ( i ) T Y ( i ) W^{(*)T}X^{(i)T}X^{(i)}-Y^{(i)T}X^{(i)}=0 \\ \Rightarrow W^{(*)T}=Y^{(i)T}X^{(i)}(X^{(i)T}X^{(i)})^{-1} \\ \Rightarrow W^{(*)} = (X^{(i)T}X^{(i)})^{-1} X^{(i)T}Y^{(i)} W(∗)TX(i)TX(i)−Y(i)TX(i)=0⇒W(∗)T=Y(i)TX(i)(X(i)TX(i))−1⇒W(∗)=(X(i)TX(i))−1X(i)TY(i)

代码

如果使用numpy,假设我们有X和y这个过程可以表述为

# 第一步是增加一列1,这样可以使得w和b合并
X_b = np.c_[np.ones((X.shape[0], 1)), X]
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)  

其中np.linalg.inv是求矩阵的逆

实例

import torch
from torch.utils import data
import numpy as np
import random

首先我们定义一个生成数据的函数

def synthetic_data(w, b, num_examples):
    X = torch.normal(0, 1, (num_examples, w.shape[0]))  # 生成均值为0,方差为1的数据
    y = torch.matmul(X, w) + b  # 生成标签
    y += torch.normal(0, 0.01, y.shape)  # 均值为0,方差为0.01的正态分布
    return X, y.reshape((-1, 1))

我们假设w为[2, -3.4],b为4.2,我们生成线性数据

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)

我们将w和b合并

X = np.array(features)
X_b = np.c_[np.ones((X.shape[0], 1)), X]
y = np.array(labels)

获得解析解

theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
theta_best

在这里插入图片描述
可以看到权值和偏置的解析解基本与真实值相同

梯度下降

理论

但是不是所有的问题都可以得到解析解,所以我们一般使用梯度下降的方式进行优化,优化方式是:各个参数沿着梯度的反方向更新,梯度方向就是方向导数最大的方向,用公式表示
( w , b ) ← ( w , b ) − ∇ ( w , b ) L (w, b) \leftarrow (w, b)-\nabla _{(w, b)}L (w,b)←(w,b)−∇(w,b)​L

随机梯度下降的手动实现代码

数据迭代器
首先为了读出数据,我们先创建一个函数作为数据迭代器,其本质是生成器,安装小梯度的梯度大小生成数据

def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        batch_indices = torch.tensor(indices[i:min(i+batch_size, num_examples)])
        yield features[batch_indices], labels[batch_indices]

权值和偏置初始化

w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)

定义线性模型

def linreg(X, w, b):
    return torch.matmul(X, w) + b

定义损失函数

def squared_loss(y_hat, y):
    return (y_hat - y) ** 2 / 2

定义随机梯度下降优化器

def sgd(params, lr, batch_size):
    with torch.no_grad():
        for param in params:
            param -= lr * param.grad / batch_size
            param.grad.zero_()

参数设置

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss

训练模型

for epoch in range(num_epochs):
    for X, y in data_iter(batch_size, features,labels):
        l = loss(net(X, w, b), y)  # 小批量损失
        l.sum().backward()  # 总损失进行反向传递
        sgd([w, b], lr, batch_size)
        
    with torch.no_grad():
        train_1 = loss(net(features, w, b), labels)
        print(f'epoch {epoch+1}, loss:{float(train_1.mean()):f}')

结果如下:

epoch 1, loss:0.033043
epoch 2, loss:0.000118
epoch 3, loss:0.000050

求损失

print(f'w损失:{true_w - w.reshape(true_w.shape)}')
print(f'b损失:{true_b - b}')

结果如下:

w损失:tensor([ 0.0007, -0.0011], grad_fn=<SubBackward0>)
b损失:tensor([0.0002], grad_fn=<RsubBackward1>)

torch中的随机梯度下降

数据加载器
使用torch.utils中的data来构建数据加载器
使用data.TensorDataset从tensor格式的数据中构建数据集,传入的参数应该是数据和标签组成的元组
使用data.DataLoader,传入数据集和批量大小,以及是否打乱顺序,使用这个函数按照批量大小加载数据

def load_array(data_arrays, batch_size, is_train=True):
    dataset = data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset, batch_size, shuffle=is_train)

设置参数

batch_size = 10
data_iter = load_array((features, labels), batch_size)
next(iter(data_iter))

结果如下:
在这里插入图片描述

构建模型
在torch中,Linear为全连接层,通过Sequential构建线性模型

from torch import nn
​
net = nn.Sequential(nn.Linear(2, 1))
help(nn.Linear)

在其中可以看到Attributes里边有weight和bias,通过这个函数我们可以获取权值和偏置
在这里插入图片描述

net[0].weight

结果如下:

Parameter containing:
tensor([[0.6657, 0.1449]], requires_grad=True)

net[0].bias

结果如下:

Parameter containing:
tensor([-0.6534], requires_grad=True)

help(net[0].weight)

这里我们可以看到使用data可以查看weight的数据
在这里插入图片描述

net[0].weight.data

tensor([[0.6657, 0.1449]])

初始化权值和偏置
我们使用均值为0,方差为0.01的正态分布的数据初始化weight,将偏置设置为0

net[0].weight.data.normal_(0, 0.01)

tensor([[-0.0092, 0.0053]])

net[0].weight.data

tensor([[-0.0092, 0.0053]])

net[0].bias.data.fill_(0)

tensor([0.])

net[0].bias.data

tensor([0.])

损失函数和优化器

选用均方误差作为损失函数,随机梯度下降优化参数

loss = nn.MSELoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.03)

训练

num_epochs= 3
for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X), y)
        trainer.zero_grad()
        l.backward()
        trainer.step()
        
    l = loss(net(features), labels)
    print(f'epoch:{epoch+1}, loss:{l:f}')

epoch:1, loss:0.000201
epoch:2, loss:0.000100
epoch:3, loss:0.000100

net[0].weight.data

tensor([[ 1.9992, -3.3989]])

net[0].bias.data

tensor([4.2002])

print(f'w损失:{net[0].weight.data - true_w}')
print(f'b损失:{net[0].bias.data - true_b}')

w损失:tensor([[-0.0008, 0.0011]])
b损失:tensor([0.0002])

线性回归(使用pytorch实现) 阅读详情

相关推荐

educoder 数据挖掘算法原理与实践:线性回归(房价预测)

第1关:线性回归算法思想 1 BC 第2关:动手实现线性回归 #encoding=utf8 import numpy as np #mse def mse_score(y_predict,y_test): #********* Begin *********# m = len(y_predict) a = y_test - y_predict mse = np.dot(a,a)/m #********* End *********# return mse

木右加木 就是木木 3695

头歌-PyTorch之线性回归

线性回归模型# 调用Module的初始化# 输入和输出分别为一维# module调用forward,将按forward进行前向传播,并构建网络return out# 实例化一个新建的模型变量model# 输出该模型 model 的'.parameters'属性。

qq_54195994的博客 3833

Pytorch实现线性回归模型

我们接下来使用Pytorch的API来手动构建一个线性回归的假设函数损失函数及优化方法,熟悉一下训练模型的流程。🧨我们将这批数据每次分成16份训练,并且这样重复训练epochs次,可以更深入地学习数据中的特征和模式,有助于防止模型快速陷入局部最优解,从而提高模型的泛化能力,而且。由于每个批次的数据都是随机抽取的。方法被调用时,PyTorch 会自动计算该张量相对于所有需要梯度的参数的梯度,并将这些梯度累加到对应参数的。是简单函数还是复杂的损失函数,都能利用相同的方法来进行梯度的反向传播。

小森的博客 2742

动手学深度学习pytorch版练习解答—3.1线性回归

第一问和第三问最后一小题都是开放性题目,有很多角度去思考和回答。希望我的这份参考能为您的学习带来帮助,您的指正对我而言也是大有裨益。 假设我们有⼀些数据x1, . . . , xn ∈ R。我们的⽬标是找到⼀个常数b,使得最小化∑i(xi−b)2\sum_{i}(x_i-b)^2∑i​(xi​−b)2 (1)找到最优值b的解析解。 (2)这个问题及其解与正态分布有什么关系? 2. 推导出使⽤平⽅误差的线性回归优化问题的解析解。为了简化问题,可以忽略偏置b(我们可以通过向X添加所有值为1的⼀列来做到这⼀点)

qq_43853021的博客 2618

从代码学习深度学习-线性回归Pytorch版

线性回归是机器学习的基础,也是深度学习的入门模型。它通过建立输入特征与输出标签之间的线性关系,帮助我们预测未知数据的结果。比如,给定房屋面积和房间数量,能否预测房价?这就是线性回归的典型应用。在深度学习框架中,PyTorch 以其灵活性和动态计算图受到广泛欢迎。本文将通过一个完整的 PyTorch 代码示例,带你从零实现线性回归,理解数据生成、模型训练和结果评估的全过程。博客将分为数据准备、模型定义、训练和结果分析几个部分,希望你能通过代码逐步掌握深度学习的基本思路!

weixin_43887510的博客 1440

【AI】《动手学-深度学习-PyTorch版》笔记(八):线性回归

了解线性回归、高斯分布、极大似然估计

郭老二 709

【深度学习】:《PyTorch入门到项目实战》基础篇1-2:从零实现线性回归(附Pytorch代码)

==线性回归==是机器学习中非常常用的模型之一,特别在研究定量数据的问题中,它能分析变量之间的关系,并给出很好的解释。此外,它还是新方法的一个良好起点:许多有趣的统计学习方法可以被视为线性回归的推广或扩展。例如`Lasso回归`,`岭回归`,`logistic regression`,`softmax回归`。本文通过Pytorch实现线性回归

阿里云专家博主、数据科学领域优质创作者、统计er在读 1万+

PyTorch深度学习实战 | 预测工资——线性回归

通过员工工作年限与工资的对应关系表,找出二者之间的关系,并预测在指定的年限时,工资会有多少。

不断学习,不断进步,提高自己 2505

PyTorch深度学习实践

根据学习情况随时更新。 2020.08.14更新完成。 参考课程-刘二大人《PyTorch深度学习实践》 文章目录(一)课程概述(二)线性模型(三)梯度下降算法(四)反向传播(五)用PyTorch实现线性回归(六)Logistic回归(七)多维特征输入的分类问题(八)加载数据集(九)多分类问题(十)卷积神经网络(十一)循环神经网络 (一)课程概述 本章知识部分涉及到计算图的正向传播(表达式计算)和反向传播(表达式求导),无需赘述。 (二)线性模型 机器学习的过程 训练时如果y值已知的学习是监督学习。 数

我的精神家园 7199

告别Keil/IAR:在VSCode中用CMake+Clangd打造丝滑的STM32开发环境(附完整配置)

本文详细介绍了如何在VSCode中使用CMake和Clangd搭建高效的STM32开发环境,替代传统的Keil/IAR工具。通过完整的配置指南和快速开发技巧,帮助开发者实现轻量级、高度可定制的现代化开发流程,显著提升STM32项目的开发效率。

weixin_26843605的博客 166

PPT高清导出秘籍:如何轻松设置600dpi图片分辨率

本文详细解析了PPT导出图片模糊的根本原因,并提供了通过修改Windows注册表将导出分辨率从默认的96dpi提升至600dpi的完整教程。该方法能显著提升图片清晰度,满足学术出版与高质量印刷需求,文中还包含效果对比、进阶设置及常见问题解答。

a0b1c2d3的专栏 1316

Pytorch与深度学习基础

Pytorch与深度学习基础前言Pytorch介绍导入Pytorch第一章:数据操作第一节:什么是张量?第二节:创建第一个张量第三节:张量的创建方法通过列表来创建自定义张量通过Numpy创建张量通过randn方法创建随机张量通过逻辑运算符构建二元张量一些特殊的张量创建高维张量的创建第四节:张量的属性张量的维度访问张量的属性第五节:改变张量的形状第六节:张量的运算张量之间的运算广播机制一个张量的元素求和一个张量的元素求平均值两个一维张量(向量)的内积(点积)二维张量(矩阵)的运算矩阵的转置矩阵的乘法矩阵的范数

weixin_45414514的博客 1723

LangChain实战:Plan and Execute代理在智能预算规划中的应用

本文详细介绍了如何利用LangChain框架中的Plan and Execute代理实现智能预算规划。通过拆解复杂财务问题、调用多工具链协作,该代理能自动完成从个人月度预算到家庭年度综合预算的智能规划,并具备消费习惯学习和多目标优化等进阶功能,帮助用户实现精准财务管理和决策优化。

weixin_42530732的博客 382

05—《动手学深度学习——Pytorch版》—线性回归

回归(regression)是能为一个或多个自变量与因变量之间关系建模的一类方法。在自然科学和社会科学领域,回归经常用来表示输入和输出之间的关系。在机器学习领域中的大多数任务通常都与预测(prediction)有关。当我们想预测一个数值时,就会涉及到回归问题。常见的例子包括:预测价格(房屋、股票等)、预测住院时间(针对住院病人等)、 预测需求(零售销量等)。但不是所有的预测都是回归问题。接下来,我们必须定义模型,将模型的输入和参数同模型的输出关联起来。

qq_46670313的博客 1384

哨兵1号(Sentinel-1)雷达SAR数据预处理全流程:从下载到精确配准

本文详细介绍了哨兵1号(Sentinel-1)雷达SAR数据从下载到精确配准的全流程预处理方法。内容涵盖SLC与GRD数据选择、ASF平台下载技巧,并重点解析了使用SNAP软件进行几何校正、辐射定标及高精度配准的核心步骤,为InSAR形变监测等应用提供可靠的数据基础。

weixin_29208327的博客 478

JavaFX - 动画

JavaFX 动画

思你日度难眠 1603

从入门到精通:DL on Flink PyTorch Estimator高效开发指南

DL on Flink是一个将Flink与深度学习框架(如PyTorch、TensorFlow等)集成的强大工具,旨在实现在Flink集群上进行分布式深度学习训练和推理。本指南将带你全面掌握PyTorch Estimator的开发流程,从环境搭建到模型部署,让你快速上手并高效开发分布式深度学习应用。 ## 一、DL on Flink核心架构解析 🧠 DL on Flink采用分层架构设计,完

gitblog_00286的博客 1074

鸿蒙应用发布实战:应用热更新的实现

在移动应用开发领域,应用更新是持续交付价值的关键环节。传统的应用更新方式需要用户手动下载完整安装包,不仅用户体验差,而且更新率往往不理想。热更新技术(也称为OTA更新)允许应用在不重新安装的情况下动态更新部分功能,极大提升了用户体验和迭代效率。本文专注于鸿蒙操作系统下的应用热更新实现方案,涵盖从原理到实践的完整知识体系。鸿蒙热更新的技术架构差分更新算法实现动态部署机制实际项目中的最佳实践安全与性能优化策略首先介绍鸿蒙热更新的背景和核心概念深入分析技术原理和算法实现。

操作系统内核探秘的博客 965

深度学习 Pytorch 线性回归建模实验

这是一篇有关深度学习pytorch笔记

“只要有信念,就一定会成功” 1684

【Bug已解决】Claude Team Plan 购买席位报错 Payment failed 解决方案

方案适用场景推荐指数检查账单历史状态排查的第一步⭐⭐⭐⭐⭐更换支付方式类型快速尝试是否能绕开问题⭐⭐⭐联系官方支持团队最终解决问题的正规渠道⭐⭐⭐⭐⭐临时过渡方案紧急用人需求的应急处理⭐⭐⭐关注官方修复进度确认属于系统性缺陷的场景⭐⭐⭐⭐Claude Team Plan 增购席位报的问题,社区反馈和实际排查表明很大概率属于平台计费系统在处理按比例分摊费用这类复杂计算链路时的系统性缺陷,而不是用户自身的支付信息填写有误。先排除自身账单历史是否存在异常。

一键难忘的博客 4183

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【深度学习基础】线性神经网络03:线性回归的简洁实现

本文讲解深度学习中线性回归的简介实现。我们可以使用PyTorch的高级API更简洁地实现模型。在PyTorch中,data模块提供了数据处理工具,nn模块定义了大量的神经网络层和常见损失函数。我们可以通过_结尾的方法将参数替换,从而初始化参数。

Morse_Chen的博客 1284

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

深度学习基础:自动梯度、线性回归与逻辑回归的 PyTorch 实践

本文介绍了深度学习中的自动梯度、线性回归和逻辑回归的原理与 PyTorch 实现。自动梯度为深度学习模型的训练提供了高效的计算方法,线性回归和逻辑回归分别适用于数值预测和分类问题。通过掌握这些基础知识,可以为深入学习更复杂的深度学习模型和算法奠定坚实的基础。在实际应用中,可以根据具体问题的需求,灵活运用这些方法,并进一步优化模型,以实现更好的性能。

weixin_52603404的博客 1213

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【DL】使用pytorch的线性回归简洁实现

从零实现线性回归此内容主要依据李沐老师的《动手学深度学习》课程,同时结合了网络上其它资料和自己的理解。对于标准深度学习模型,我们可以使用框架的预定义好的层。我们首先定义一个模型变量net,它是一个Sequential类的实例。Sequential类将多个层串联在一起,类似于按序列存放各种层的容器。当给定输入数据时,Sequential实例将数据传入到第一层, 然后将第一层的输出作为第二层的输入,以此类推。由于线性回归相当于单层神经网络,实际上不需要Sequential。

qq_43557907的博客 648

【AI深度学习基础】PyTorch初探

通过本阶段的学习,我们了解了PyTorch的基本概念和核心特性,掌握了张量的基本操作和神经网络的构建方法,并通过一个简单的线性回归示例进行了实践。PyTorch的灵活性和强大功能为我们后续深入学习深度学习奠定了基础。PyTorch是一个非常强大且易于使用的深度学习框架,适合初学者入门和开发者进行各种深度学习项目。希望本篇学习指南能够帮助你迈出PyTorch学习的第一步,期待你在后续的学习和实践中不断探索,利用PyTorch构建出更加优秀的模型。

Arbboter的专栏 2358

PyTorch深度学习基础/Logistic回归

线性回归是一种简单且广泛应用的机器学习算法,主要用于预测和分析两个变量之间的关系。线性回归模型的基本思想是建立一个线性方程来描述自变量(X)和因变量(Y)之间的关系。这个方程通常表示为 (Y = wx + b),其中 (w) 是斜率,表示自变量对因变量的影响程度,而 (b) 是截距,表示当自变量为零时因变量的值。线性回归的目标是找到最佳的 (w) 和 (b) 值,使得模型预测的 (Y) 值与实际数据中的 (Y) 值之间的差异最小。

2301_77976072的博客 1544
上一篇: opencv案例实战——银行卡模式匹配识别
下一篇: pytorch深度学习基础(九)——深入浅析卷积核
艾醒(AiXing-w)
艾醒(AiXing-w) 2021年度博客之星AI领域top5 2021年度博客之星AI领域top5
博客等级 码龄7年 1万+粉丝 320原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

艾醒(AiXing-w)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值