- 博客(53)
- 收藏
- 关注
原创 python打卡day53
这里我们用了torch中的容器这个概念,sequential是一个按顺序存放神经网络的容器,这样写神经网路的属性的时候,把这些内容都写在一个容器中,然后作为属性,后面定义前向传播的时候会方便很多,不用像之前那样。之前的激活函数都是用的标准ReLU:f(x) = max(0, x),但当输入为负时,输出全部置为零,此时梯度为零更新不了参数,这就是神经元死亡问题。结果反而更差了,这个数据集健康样本138,病人样本165,不平衡问题不显著,GAN相当于过采样了,而且还生成的是病人样本,过度处理不平衡更不合理了。
2025-06-13 23:40:56
796
原创 python打卡day52
知识点回顾:随机种子内参的初始化神经网络调参指南参数的分类调参的顺序各部分参数的调整心得还是要过一下一些基础概念torch中很多场景都会存在随机数:权重、偏置的随机初始化;数据加载(shuffling打乱)与批次加载(随机批次加载)的随机化;数据增强的随机化(随机旋转、缩放、平移、裁剪等);随机正则化dropout;优化器中的随机性等如果想保证之后再运行结果一模一样,就需要设置随机种子,一般默认值为42。
2025-06-12 23:39:09
1085
原创 python打卡day51
在模型修改这一部分,原先构想的是在每一个残差块后面都加入CBAM模块,但是 MobileNetV3 有十五个残差块啊,当时没有想到这样操作铁定会造成过拟合,训练集准确旅奇高但测试集准确率简直一坨。也不算太高,但至少比之前用自定义CNN网络训练来的效果好(突然想到之前效果不好可能也是网络构造复杂过拟合了,当时没有可视化细看,遗憾)讲实话整个结构改进下来,CBAM和通道数匹配才是最恼火的,最先是直接设定CBAM输入通道,一直报错都快放弃了,最后无脑遍历😈。和之前一样,用Grad-CAM可视化,改了点细节。
2025-06-11 23:41:03
668
原创 python打卡day50
如果是resnet18+cbam模块,那么大多数地方的代码都是可以复用的,模型定义部分需要重写,对于训练策略,还是延续之前第一次使用resnet的预训练策略:先冻结预训练层,然后训练其他层。之前的其它层是全连接层(分类头),现在其它层还包含了每一个残差块中的cbam注意力层。如果想在预训练模型中加入注意力机制,预训练模型的结构和权重是固定的,如果修改其中的模型结构,是否会大幅影响其性能;,没有破坏特征的结构或空间关系,虽然对预训练层的输出信号强度减半了,但所有信息还是保留下来了,不会剧烈扰动预训练权重。
2025-06-10 22:51:52
1136
原创 python打卡day49
所有的模块本质上只是对特征进一步提取,之前学习了SE通道注意力,今天进一步了解一下CBAM注意力,它的核心目标是通过学习的方式,自动获取特征图在通道和空间维度上的重要性,进而对特征图进行自适应调整,增强重要特征,抑制不重要特征。所以很明显,CBAM有两个主要部分,通道注意力模块和空间注意力模块,输入特征图 → 通道注意力模块 → 空间注意力模块 → 输出增强后的特征图。然后直接在训练函数里面修改就行,图方便只查看训练过程的损失、准确率(主要是改完代码忘了还有测试集的事儿,训练一次太费时间了不搞了)
2025-06-09 23:22:51
494
原创 python打卡day48
还有其他张量随机函数,生成数据分布不同,比如 torch.rand():生成在 [0, 1) 范围内均匀分布的随机数;在 PyTorch 中,torch.randn()是一个常用的随机张量生成函数,它可以创建一个由标准正态分布(均值为 0,标准差为 1)随机数填充的张量。自动对形状不同的张量进行维度扩展,无需手动调整张量维度,但也要符合规则:从张量的最后一个维度(最右侧)开始向左逐维比较。卷积和池化的输入输出维度关系都满足下式,本质就是核窗口在输入特征图上移动的有效范围带来的,搞懂卷积层的具体原理就懂了。
2025-06-08 23:26:45
644
原创 python打卡day47
特征图本质就是不同的卷积核的输出,浅层指的是离输入图近的卷积层,浅层卷积层的特征图通常较大,而深层特征图会经过多次下采样,尺寸显著缩小,尺寸差异过大时,小尺寸特征图在视觉上会显得模糊或丢失细节。:展示输入图像中不同空间位置的权重分布,例如,在目标检测或图像分类任务中,模型可能会对目标物体所在的区域分配更高的注意力权重。:展示不同通道的权重分布,例如,在图像分类任务中,模型可能会对包含目标物体的通道赋予更高的注意力权重。关于全局平均池化 torch.mean。5. 可视化特征图:对每张图像。
2025-06-07 23:10:23
1054
原创 python打卡day46
过去我们都是在同一个数据集上对比不同的模型的差异,或者同一个模型不同参数下的差异,这种实验叫做对比实验,用于评估模型的整体竞争力;transformer中的叫做自注意力机制,他是一种自己学习自己的机制,我们现在说的很多模块,比如通道注意力、空间注意力、通道注意力等等,都是基于自注意力机制的。想要把通道注意力插入到模型中,需要定义注意力模块,再重写之前的模型定义部分,确定好模块插入的位置。什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。通道注意力:模型的定义和插入的位置。
2025-06-06 23:55:47
1047
原创 python打卡day45
如果现在有一个交互工具可以很简单的通过按钮完成这些辅助功能那就好了,所以现在介绍下tensorboard这个可视化工具,它可以很方便地完成很多可视化的功能,尤其是可以在运行过程中实时渲染,方便我们根据图来动态调整训练策略,而不是训练完了才知道好不好。TensorBoard 的核心原理就是在训练过程中,把训练过程中的数据(比如损失、准确率、图片等)先记录到日志文件里,再通过工具把这些日志文件可视化成图表,这样就不用自己手动打印数据或者用其他工具画图。(批损失、批准确率、学习率、参数直方图)
2025-06-05 21:36:42
627
原创 python打卡day44
训练就是不断更新参数,那么如果参数初始值比较好,不仅可以减少未来训练次数,也可以避免未来训练陷入局部最优解的可能,这就引入了预训练模型——即指在和当前目标数据集类似的大规模数据集上训练好的模型。这种思想叫做迁移学习,预训练的过程叫做上游任务,在目标训练集微调参数的过程叫做下游任务。对于当前数据集的预处理和数据加载不赘述了,以ResNet18作为预训练模型,先修改创建(使用creat_resnet() 函数对原始ResNet18进行修改以适配当前任务)图像预训练模型的发展史。常见的分类预训练模型。
2025-06-04 22:56:46
441
原创 python打卡day43
1、如果是比较规整的图像分类数据集,自己划分了train和test目录,就可以直接用pytorch内置的ImageFolder类,不用自己再辛辛苦苦定义数据集类了,但很遗憾这个数据集不规整,图片在列别下面,标签用一个csv文件存储,所以不经要自己定义数据类,训练测试的时候还要自己划分数据集。2、之前的数据集创建dataset和dataloader的时候都很轻松,到了这个数据集就成了比较困难的一个点了,首先是文件路径的问题,其次就是在数据集类的定义里对图像和标签的处理。进阶:并拆分成多个文件。
2025-06-03 23:41:15
465
原创 python打卡day42
在深度学习中,我们经常需要查看或修改模型中间层的输出或梯度,但标准的前向传播和反向传播过程通常是一个黑盒,很难直接访问中间层的信息。PyTorch 提供了一种强大的工具——hook 函数,它允许我们在不修改模型结构的情况下,获取或修改中间层的信息。这种机制允许代码在运行时动态指定需要执行的逻辑,其中回调函数作为参数传入,所以在定义的时候一般用callback来命名。在hook中常常用到lambda函数,它是一种匿名函数(没有正式名称的函数),最大特点是用完即弃,无需提前命名和定义。Grad-CAM的示例。
2025-06-01 23:38:26
1436
原创 python打卡day41
ReduceLROnPlateau调度器适用于当监测的指标(如验证损失)停滞时降低学习率,是大多数任务的首选调度器,尤其适合验证集波动较大的情况。该策略通常不改变单次训练的样本总数,而是通过对现有图像进行多样化变换,使每次训练输入的样本呈现更丰富的形态差异,从而有效扩展模型训练的样本空间多样性。可以把全连接层前面的不理解为神经网络的一部分,单纯理解为特征提取器,他们的存在就是帮助模型进行特征提取的,展平加上全连接就是后续任务的具体实现。卷积的本质:通过卷积核在输入通道上的滑动乘积,提取跨通道的空间特征。
2025-06-01 21:39:44
869
原创 python打卡day40
不同的是 Flatten() 会自动展平,但 view/reshape() 必须显示保留 batch_size ,比如 x = x.view(batch_size, -1),这里-1是一个特殊值,表示让PyTorch自动计算该维度的大小。- Iteration(迭代):一个Iteration是指一个批次的样本通过神经网络一次(前向传播+反向传播)的过程。:仔细学习下测试和训练代码的逻辑,这是基础,这个代码框架后续会一直沿用,后续的重点慢慢就是转向模型定义阶段了。再加上测试,一个完整的过程如下。
2025-05-30 23:23:28
574
原创 python打卡day39
所以实际应用中,输入图像还存在batch_size这一维度,但在PyTorch中,模型定义和输入尺寸的指定不依赖于batch_size,无论设置多大的batch_size,模型结构和输入尺寸的写法都是不变的,batch_size是在数据加载阶段定义的(之前提过这是DataLoader的参数)对于batch_size的设置,大规模数据时,通常从16开始测试,然后逐渐增加,确保代码运行正常且不报错,直到出现内存不足(OOM)报错或训练效果下降,此时选择略小于该值的 batch_size。---注意顺序关系,
2025-05-29 23:46:31
633
原创 python打卡day38
此外,还存在Dataset类,该类可以定义数据集的读取方式和预处理方式,均继承自torch.utils.data。因为每个数据的维度比较小,所以既可以视为结构化数据,用机器学习、MLP训练,也可以视为图像数据,用卷积神经网络训练。torchvision 的 datasets 模块已经预定义了许多常见的数据集,实例化一个数据类就是创建dataset对象了。__getitem__和__len__ 是类的特殊方法(也叫魔术方法 ),它们不是像普通函数那样直接使用,而是。minist手写数据集的了解。
2025-05-27 23:02:17
819
原创 python打卡day37
刚才也说了,过拟合是测试集的曲线会在某一时刻开始上升,那当曲线不再变好,此时提前终止训练,避免模型对训练集过度拟合,这就是早停法。深度学习中模型的保存与加载主要涉及参数(权重)和整个模型结构的存储,同时需兼顾训练状态(如优化器参数、轮次等)以支持断点续训。是否过拟合,可以通过同步打印训练集和测试集的loss曲线来判断(要点就是训练一定epoch后,就开始推理,然后接着训练)阈值patience的设置就很重要了。(训练Loss远低于测试Loss)训练Loss和测试Loss。训练Loss和测试Loss。
2025-05-26 23:20:12
449
原创 python打卡day36
2、构造神经网络的时候,输入层的输入维度没注意太多,因为处理前数据有16个特征,所以设置的16,一直报错,然后想起来独热编码之后导致了特征膨胀,变成了31个特征。这里的处理是将输入层的维度就设置成了31,但如果是大型数据集,特征更多了之后这样显然不太合适,还没想到处理办法。1、终于搞懂数据转换成张量的时候要不要加上to_numpy()了,先看看数据类型,DataFrame或者Series就转换不过去,先搞成数组或者列表(很幽默啊,划分数据集后特征和标签的数据类型居然不一样)探索性作业(随意完成)
2025-05-25 23:28:04
1123
原创 python打卡day35
的,它不会预先计算各层的形状,只有当你输入真实数据时,才会逐层推导形状,就比如 self.fc1 = nn.Linear(4, 10) 虽然定义了输入维度为4,但模型并不知道输入的完整形状(如批量大小、其他维度),如果输入是一个批量大小为32的数据(形状为。而`model.named_parameters()`不仅返回参数,还返回每个参数的名称,这对调试或需要按名称操作参数的情况很有用)例如,如果发现权重标准差过大导致训练不稳定,可以尝试调整学习率,使权重更新更平稳;脑子在颤抖了,记不住。
2025-05-24 23:14:08
705
原创 python打卡day34
举个例子,之前训练时要选定损失函数,nn.CrossEntropyLoss() 是一个类,criterion 是它的实例,criterion(output, y_train) 实际上是 criterion.__call__(output, y_train),这个__call__方法内部会计算交叉熵损失,并返回结果。方法,它的实例可以通过 实例名() 的方式调用,就像调用函数一样,这种特性使得对象可以表现得像函数,同时保留对象的内部状态。所以综上所述,GPU适合大型数据集,大型模型,复杂繁琐的并行计算操作。
2025-05-24 20:45:31
1542
1
原创 python打卡day33
PyTorch这个专门用于深度学习的包,就跟之前的库一样的安装就好,至于cuda,英伟达的gpu可以装这个,不是的话装个cpu版的PyTorch就行了,要用gpu上云服务器就好。1. 分类任务中,若标签是整数(如 0/1/2 类别),需转为long类型(对应 PyTorch 的torch.long),否则交叉熵损失函数会报错。显卡信息和cuda的检查就不说了,反正今天也没用上,直接用鸢尾花数据集通过一个全连接的神经网络训练走一下流程。看得出来loss到后面已经稳定了,说明实现了收敛,可以画图看看。
2025-05-22 23:26:26
556
原创 python打卡day32
现在面对一个全新的官方库,看看是否可以借助官方文档的写法了解其如何使用,以pdpbox这个机器学习解释性库来学习如何使用官方文档(之前的学习用的shape库来进行可解释性分析,其实还有很多库可以实现)先进入官方文档,通常会有一个“API Reference”或“Documentation”部分,列出所有可用的函数、类和方法,以绘制 TargetPlot 为例,蓝色框内是实例化这个需要的的参数,Attribute 显示了这个类所具备的属性和方法。参考pdpbox官方文档中的其他类,绘制相应的图,任选即可。
2025-05-21 23:22:13
811
原创 python打卡day31
规范的py文件,首行会有:# -*- coding: utf-8 -*-,主要目的是显式声明文件的编码格式,确保 Python 解释器能正确读取和解析文件中的非 ASCII 字符(如中文、日文、特殊符号等)。if __name__ == "__main__"这个写法在项目拆分时很常见,如果直接运行某个文件,则__name__等于__main__,若这个文件被其他模块导入,则__name__不等于__main__Python 的类型注解是一种为变量、函数参数和返回值和类属性添加类型提示的语法,
2025-05-20 22:47:53
914
原创 python打卡day30
------------------------------------------------ 相关概念辨析一下 ------------------------------------------------------导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致)场景:要导入的模块位于完全不同的目录层级(如父目录、兄弟目录等)└── utils.py # 要导入的模块。方法:直接使用上面提到的三种导入库的方式。场景:要导入的模块位于当前脚本的子目录中。
2025-05-19 23:31:51
1260
原创 python打卡day29
回顾一下,函数的装饰器是 :接收一个函数,返回一个修改后的函数。类也有修饰器,类装饰器本质上确实是一个函数,他的逻辑类似,接收一个类,返回一个修改后的类或者新类。学了这么多天,感觉python就是万物皆可类,类又有属性和方法,跟原先的C语言学习比起来,从数据结构、从函数或者类的复用、封装、动态修改等方面更进一步有了不同。第二种用 wrapper() 封装返回的方法就不谈了,之前函数装饰器接触过。装饰器思想的进一步理解:外部修改、动态。举个具体例子来看看,这是直接修改类。类方法的定义:内部定义和外部定义。
2025-05-18 23:20:10
582
原创 python打卡day28
普通方法和init方法的差别在于,init方法是类的构造方法,只要你创建这个类对象了,这个init函数就会自动执行。普通方法是只有你显式调用类的这个方法的时候,函数才会执行。在面向对象编程中,继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码复用和功能扩展。注意一下子类定义时传入参数是父类名称,用 super() 函数调用父类的方法,不管是构造方法还是普通方法都行。Python 通过缩进来定义代码块的结构,当规划好准备写一个函数、或者一个类,关键词定义后,会。(比如让对象执行某个操作)
2025-05-17 23:26:33
787
原创 python打卡day27
装饰器本质上是一个 Python 函数,可以在不修改原函数代码的情况下,给函数添加额外功能。今天终于把昨天讲的 *args 和 **kwargs 这种什么时候解包(加上*)什么时候不解包(不加*)搞清楚了,只在需要将元组或字典拆分为独立参数时才使用*args或**kwargs,其他情况直接使用元组或字典即可。如果原函数需要传入参数并且还要有返回值(比如传入参数maxnum,计算2-maxnum的质数的个数),那么。所以装饰器本身就是函数中调用其他函数,实现先拆分函数,再合并函数的功能。
2025-05-16 23:18:21
789
原创 python打卡day26
他可以传位置参数的值,也可以传默认参数的值,也可以传可变参数的值,也可以传关键字参数的值。Python 先处理所有位置参数(包括普通参数和*args),把能匹配普通参数名的关键字参数用掉,剩下的所有 参数名=值 都塞进 **kwargs 这个字典里。Python 先用传的参数按顺序填满普通参数,如果还有剩下的位置参数,全部塞进 *args 这个元组里,如果没多余参数,*args 就是个空元组 ()注意点:带默认值的参数必须放在没有默认值的参数之后。函数的参数类型:位置参数、默认参数、不定参数。
2025-05-15 23:40:58
895
原创 python打卡day25
程序首先尝试执行 try 块中的代码,如果 try 块中的代码没有发生异常,则 except 块会被跳过,程序继续执行 try-except 结构之后的代码。如果找到匹配的,则执行该 except 块中的代码,然后继续执行整个 try-except 结构之后的代码(除非 except 块中又引发了新异常或执行了 return/break/continue 等)。执行 try 块中的代码,如果 try 块中发生异常,则会查找并执行匹配的 except 块,else 块不会被执行。debug过程中的各类报错。
2025-05-14 22:45:42
1075
原创 python打卡day24
举个例子,假如当前工作目录是`my_project`,`os.walk` 会首先访问起始目录 (`my_project`),然后它会选择第一个子目录 (`data`) 并深入进去,访问 `data` 目录本身,然后继续深入它的子目录 (`processed` -> `raw`)。这里提一下元组,主要是昨天pipeline()的定义中,接受的类是包含多个小元组的列表,元组用于将每个步骤的名称和处理对象捆绑在一起,列表定义执行步骤的先后,之后可以对列表进行修改,再强调一下。生成器 (Generators)
2025-05-13 23:17:20
711
原创 python打卡day23
估计器是实现机器学习算法的对象或类,用于拟合(fit)数据并进行预测(predict),从数据中学习模式、进行预测和进行模型评估。转换器是一个用于对数据进行预处理和特征提取的 estimator,用于对数据进行预处理和特征提取。很显然缺失值补全、离散变量编码这些操作都是手动处理完成,如果测试集训练集分开的情况还要重复相同操作(比如之前的泰坦尼克号幸存预测),加入pipeline就不一样了。这也意味着,很多个不同的数据集,只要处理成管道的输入形式,后续的代码就可以复用。转化器和估计器的概念。
2025-05-12 23:37:28
798
原创 python打卡day22
可以看看每个特征与最后标签的相关性来确定是否需要去除,这里只看了几个特征,最后直接根据特征的含义评判了,数据探索还可以再多一点数据可视化一下更明确,这里的处理其实蛮粗糙的,比如名字还可以看出头衔阶层啥的对吧,和幸存率可能还是有关系的(就是很简单很草率地走了一遍机器学习的经典流程,其实数据还可以提取新特征,但懒得搞了,特征也少不需要降维。就是这个项目本身就分了训练集和测试集,需要注意一下数据预处理跟之前不太一样。保存csv文件,调参谦和调参后都提交了一下做对比,还是贝叶斯优化后准确率高点。
2025-05-12 15:36:28
648
原创 python打卡day21
所以PCA是一种线性降维,对于数据结构高度非线性(例如“瑞士卷”、“S型曲线”),PCA会将其投影到一个线性子空间,这可能会丢失关键的非线性关系,在这种情况下,非线性降维技术(如 t-SNE, UMAP, LLE, Isomap, 核PCA, 自编码器)会是更好的选择。PCA这种无监督降维方法的目标是保留数据的最大方差(即主成分),将数据投影到由这些最重要的主成分构成的新的、维度更低子空间上,这些方差大的方向不一定是对分类最有用的方向。同时PCA同样适合聚类前的可视化,但PCA更适合一般数据预处理。
2025-05-10 23:41:52
800
原创 python打卡day20
应用:结构化数据中,将原来的m个特征降维成k个新的特征,新特征是原始特征的线性组合,捕捉了数据的主要方差信息,降维后的数据可以直接用于机器学习模型(如分类、回归),通常能提高计算效率并减少过拟合风险。,对于分解后的矩阵,可以选取保留前K个奇异值及其对应的奇异向量,重构原始矩阵,可以通过计算Frobenius 范数相对误差来衡量原始矩阵和重构矩阵的差异。ps:在进行 SVD 之前,通常需要对数据进行标准化(均值为 0,方差为 1),以避免某些特征的量纲差异对降维结果的影响。降噪:通常噪声对应较小的奇异值。
2025-05-09 23:29:59
943
原创 python打卡day19
答:第一次创建 rf_selector 是专门用于特征重要性评估,传入的是原始的 x_train,第二次创建 rf_model_rf 是用筛选后的特征训练最终预测模型,传入的是筛选后的 x_train_rf,让特征选择和最终模型实现了隔离,避免数据泄露。Lasso本质是线性回归模型,要求目标变量是连续值,但分类问题的目标变量是离散类别,强行用回归方法处理分类问题会带来理论缺陷,把类别标签0/1当作连续数值处理,拟合的是"用特征预测0到1之间的数值"的回归问题,虽然确实能计算。今天这节先说一下特征筛选,
2025-05-08 23:24:35
1436
原创 python打卡day18
如你想聚类消费者购买习惯,那么他过去的消费记录、购买记录、购买金额等等,这些特征都与消费者购买习惯有关,你可以使用这些特征来确定簇含义,一些其他的特征,如消费者年龄,工作行业则不考虑。------适用于你本身就有构造某些明确含义的特征的情况。2. 最开始用全部特征来聚类,把其余特征作为 x,
2025-05-07 22:38:35
989
原创 python打卡day17
知识点聚类的指标聚类常见算法:kmeans聚类、dbscan聚类、层次聚类三种算法对应的流程实际在论文中聚类的策略不一定是针对所有特征,可以针对其中几个可以解释的特征进行聚类,得到聚类后的类别,这样后续进行解释也更加符合逻辑。聚类的流程标准化数据------聚类前的一般操作选择合适的算法,根据评估指标调参( )将聚类后的特征添加到原数据中原则t-sne或者pca进行2D或3D可视化KMeans 和层次聚类的参数是K值,选完k指标就确定。
2025-05-06 23:25:22
720
原创 python打卡day16
因为前天说了shap,这里涉及到数据形状尺寸问题,所以需要在这一节说清楚,后续的神经网络我们将要和他天天打交道。知识点:numpy数组的创建:简单创建、随机创建、遍历、运算numpy数组的索引:一维、二维、三维SHAP值的深入理解作业:今日知识点比较多,好好记忆下NumPy 数组的维度或称为轴 (Axis)的概念,与我们日常理解的维度非常相似。直观判断:数组的维度层数通常可以通过打印输出时中括号 `[]` 的嵌套层数来初步确定:一层 `[]`:一维数组。两层 `[]`:二维数组。
2025-05-05 22:20:43
1988
原创 python打卡day15
尝试找到一个kaggle或者其他地方的结构化数据集,用之前的内容完成一个全新的项目,这样你也是独立完成了一个专属于自己的项目。对于数据的认识,很重要的一点是,很多数据并非是为了某个确定的问题收集的,这也意味着一份数据你可以完成很多不同的研究,同一个问题,特征加工上,是否对数据进一步加工得出了新的结论-----你的加工被证明是有意义的。研究问题的选择上,同一个数据你找到了有意思的点,比如更换了因变量,做出了和别人不同的研究问题。数据的质量上,是否有好的研究主题但是你这个数据很难获取,所以你这个研究有价值。
2025-05-04 23:56:02
744
原创 python打卡day14
SHAP图介绍今日作业偏思考类型,有一定难度参考上述文档补全剩余的几个图尝试确定一下shap各个绘图函数对于每一个参数的尺寸要求,如shap.force_plot力图中的数据需要满足什么形状?确定分类问题和回归问题的数据如何才能满足尺寸,分类采取信贷数据集,回归采取单车数据集。
2025-05-03 23:44:14
1340
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅