【深度学习-第6篇】使用python快速实现CNN多变量回归预测(使用pytorch框架)

news2024/11/23 3:15:28

上一篇我们讲了使用CNN进行分类的python代码:

Mr.看海:【深度学习-第5篇】使用Python快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例(使用pytorch框架)

这一篇我们讲CNN的多变量回归预测。

是的,同样是傻瓜式的快速实现。

本篇是之前MATLAB快速实现CNN多变量回归预测的姊妹篇。

一、环境搭建

本篇使用的是Win10系统搭建VSCode+Anaconda+Pytorch+CUDA环境,当然如果你是用的是其他编辑器,没有使用anaconda,或者没有独立显卡,本文的程序也都是可以实现的(不过也需要正确配置好了相关环境)。

如果你还没有配置环境,或者配置的环境运行后边的代码有错误,那么推荐大家按照我之前的这篇文章操作来重新进行配置:

Mr.看海:【深度学习-番外1】Win10系统搭建VSCode+Anaconda+Pytorch+CUDA深度学习环境和框架全过程

环境搭建中遇到的问题,大家可以集中在上边这篇文章中留言反映。

二、什么是多变量回归预测

多变量回归预测则是指同时考虑多个输入特征进行回归预测。举几个例子:

  1. 房价预测:给定一组房产的特征,如面积、卧室数量、浴室数量、地理位置等,预测房产的销售价格。
  2. 股票价格预测:使用历史股票价格、交易量、财务指标等信息,预测未来某个时间点的股票价格。
  3. 销售预测:基于历史销售数据、季节性、促销活动等信息,预测未来某个时间段的销售额。
  4. 能源需求预测:考虑天气条件、时间(如一天中的时间、一周中的哪一天、一年中的哪个月份等)、历史能源需求等因素,预测未来的能源需求。
  5. 疾病风险预测:根据患者的年龄、性别、生活习惯、基因信息等,预测患者罹患某种疾病的风险。

在许多实际问题中,我们通常需要考虑多个输入特征。虽然 CNN 最初是为图像分类问题设计的,但它也可以应用于回归预测问题。在这种情况下,CNN 的目标不再是预测输入图像的类别,而是预测一个连续的目标值。为此,我们可以将 CNN 的最后一层全连接层修改为输出一个单一的连续值,然后使用一个回归损失函数(如均方误差)来训练网络。

CNN 由于其强大的特征提取能力,特别适合处理这种多变量的回归预测问题。

这篇文章我们就以房价预测为例吧

三、一个简单的案例——波士顿房价预测

下面我们将演示如何使用pytorch实现一个卷积神经网络(CNN)来进行波士顿房价的多变量回归预测。我们将使用波士顿房价数据集来训练我们的模型,该数据集包含波士顿城郊区域的房屋的多个特性(如犯罪率、房间数量、教师学生比例等)和房价。如下图每组房价数据由13个相关属性(即13个指标变量),1个目标变量(房价)组成,总共有506组数据,即为506*14的数组。

房价数据

下边代码我将详细讲解逐行写到注释当中,为了增加可读性,正文文字仅做流程讲解。

0. 安装必要的库并导入

如果大家使用上述环境搭建方法,使用了conda的环境,则不需要再额外安装库。如果不是的话,你可能会需要安装numpy,torch和sklearn等。

安装好之后,代码中导入必要的库:

import numpy as np
# 导入NumPy库,用于数组操作和数值计算

import torch
# 导入PyTorch库,用于构建和训练神经网络模型

import torch.nn as nn
# 导入torch.nn模块,其中包含了各种神经网络层和损失函数

import torch.optim as optim
# 导入torch.optim模块,其中包含了各种优化算法

from torch.utils.data import DataLoader, TensorDataset
# 从torch.utils.data模块中导入DataLoader和TensorDataset类
# DataLoader用于创建数据加载器,实现批量读取和数据打乱等功能
# TensorDataset用于将数据封装成数据集对象,便于传递给DataLoader

import matplotlib.pyplot as plt
# 导入Matplotlib的pyplot模块,用于绘制图形和可视化结果

from sklearn.preprocessing import MinMaxScaler
# 从scikit-learn库的preprocessing模块中导入MinMaxScaler类
# MinMaxScaler用于对数据进行最小-最大归一化,将数据缩放到[0, 1]的范围内

1. 数据预处理

首先,我们从 'housing.txt' 中读取数据。

# 读取数据
data = np.loadtxt('housing.txt')
# 使用NumPy的loadtxt函数从文件'housing.txt'中读取数据
# 假设数据文件的格式为每行代表一个样本,不同的特征值和目标值之间用空格或制表符分隔
# 读取的数据将被存储在NumPy数组data中

X = data[:, :13]
# 数据集中前13列是输入特征,每一行代表一个样本,每一列代表一个特征
# data[:, :13]表示选取数组的所有行和前13列

y = data[:, 13]
# 通过数组切片操作,将数据的第14列提取出来,赋值给变量y
# 这里假设数据集中第14列是目标值,即我们要预测的房价

然后将输入和输出数据进行归一化处理。数据归一化的目的是将不同特征的值缩放到相似的范围,以提高模型的收敛速度和性能。这在处理具有不同量纲或范围的特征时尤为重要。

# 数据归一化处理
scaler_x = MinMaxScaler()
# 创建一个MinMaxScaler对象scaler_x,用于对输入特征X进行归一化处理
# MinMaxScaler会将数据缩放到[0, 1]的范围内

X = scaler_x.fit_transform(X)
# 使用scaler_x对输入特征X进行拟合和转换
# fit_transform方法会计算数据的最小值和最大值,并将数据缩放到[0, 1]的范围内
# 转换后的数据将覆盖原始的X

scaler_y = MinMaxScaler()
# 创建另一个MinMaxScaler对象scaler_y,用于对目标值y进行归一化处理

y = scaler_y.fit_transform(y.reshape(-1, 1)).flatten()
# 使用scaler_y对目标值y进行拟合和转换
# 由于MinMaxScaler期望输入是二维数组,因此需要使用reshape(-1, 1)将y转换为二维数组
# reshape(-1, 1)表示将y转换为一个列向量,行数自动推断
# fit_transform方法会计算数据的最小值和最大值,并将数据缩放到[0, 1]的范围内
# 最后使用flatten()将转换后的二维数组重新转换为一维数组,覆盖原始的y

将数据转换为PyTorch张量是在PyTorch中进行模型训练和推理的必要步骤。PyTorch模型接受张量作为输入,并对张量进行操作和计算。

# 将数据转换为PyTorch张量
X = torch.tensor(X, dtype=torch.float32)
# 使用torch.tensor函数将NumPy数组X转换为PyTorch张量
# dtype=torch.float32指定张量的数据类型为32位浮点数
# 转换后的张量X将用于模型的输入

y = torch.tensor(y, dtype=torch.float32)
# 转换后的张量y将用于模型的训练和评估

2.数据集划分

下边将数据集划分为训练集、验证集和测试集,可以全面评估模型的性能。训练集用于训练模型,验证集用于调整模型的超参数和进行模型选择,测试集用于评估模型在未见过的数据上的泛化能力。

# 数据集划分
train_ratio = 0.7
val_ratio = 0.1
# 定义训练集和验证集的比例
# train_ratio表示训练集占总数据的比例,这里设置为0.7,即70%的数据用于训练
# val_ratio表示验证集占总数据的比例,这里设置为0.1,即10%的数据用于验证
# 剩下的20%用于测试

num_samples = len(X)
# 获取数据集的样本数,即X的长度

num_train = int(num_samples * train_ratio)
num_val = int(num_samples * val_ratio)
# 计算训练集和验证集的样本数
# num_train表示训练集的样本数,通过总样本数乘以训练集比例并取整得到
# num_val表示验证集的样本数,通过总样本数乘以验证集比例并取整得到

train_data = X[:num_train]
train_labels = y[:num_train]
# 使用切片操作提取训练集数据和标签
# train_data表示训练集的输入特征,取X的前num_train个样本
# train_labels表示训练集的目标值,取y的前num_train个样本

val_data = X[num_train:num_train+num_val]
val_labels = y[num_train:num_train+num_val]
# 使用切片操作提取验证集数据和标签
# val_data表示验证集的输入特征,取X从num_train到num_train+num_val的样本
# val_labels表示验证集的目标值,取y从num_train到num_train+num_val的样本

test_data = X[num_train+num_val:]
test_labels = y[num_train+num_val:]
# 使用切片操作提取测试集数据和标签
# test_data表示测试集的输入特征,取X从num_train+num_val到最后的样本
# test_labels表示测试集的目标值,取y从num_train+num_val到最后的样本

3.创建数据加载器

下面我们来创建用于训练、验证和测试的数据加载器。使用PyTorch的TensorDataset类将数据和标签打包成数据集对象。然后通过DataLoader类创建数据加载器,指定批次大小和数据打乱选项。

# 创建数据加载器
train_dataset = TensorDataset(train_data, train_labels)
val_dataset = TensorDataset(val_data, val_labels)
test_dataset = TensorDataset(test_data, test_labels)
# 使用TensorDataset将训练集、验证集和测试集的数据和标签打包成数据集对象
# TensorDataset接受多个张量作为参数,将它们组合成一个数据集
# train_dataset表示训练集的数据集对象,包含训练数据和标签
# val_dataset表示验证集的数据集对象,包含验证数据和标签
# test_dataset表示测试集的数据集对象,包含测试数据和标签

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=64)
test_loader = DataLoader(test_dataset, batch_size=64)
# 使用DataLoader创建数据加载器,用于批次读取数据
# train_loader表示训练集的数据加载器,batch_size=64表示每个批次包含64个样本,shuffle=True表示在每个epoch开始时打乱数据顺序
# val_loader表示验证集的数据加载器,batch_size=64表示每个批次包含64个样本
# test_loader表示测试集的数据加载器,batch_size=64表示每个批次包含64个样本

4.定义CNN模型

下边这段代码定义了一个卷积神经网络(CNN)模型。

模型结构包括一个卷积层(conv1)和一个全连接层(fc1)。卷积层使用32个大小为(3, 1)的卷积核,并在输入周围进行零填充。卷积层的输出经过ReLU激活函数进行非线性变换。

这里只是演示了一种最简单的CNN网络结构,在实际应用中,大家可以根据实际做更复杂的修改。如果你还不太懂CNN的网络结构,可以看我之前的这篇图解文章:关于CNN网络结构的图解入门。

# 定义CNN模型
class CNN(nn.Module):
    def __init__(self, input_dim):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=(3, 1), padding=(2, 2))
        # 定义一个二维卷积层,输入通道为1,输出通道为32,卷积核大小为(3, 1),padding为(2, 2)
        self.relu1 = nn.ReLU()
        # 定义一个ReLU激活函数
        
        # 计算卷积层输出的维度
        conv_output_dim = self.conv1(torch.zeros(1, 1, input_dim, 1)).view(-1).shape[0]
        # 通过将全零张量传递给卷积层并展平输出,计算卷积层输出的维度
        self.fc1 = nn.Linear(conv_output_dim, 1)
        # 定义一个全连接层,输入维度为卷积层输出的维度,输出维度为1

    def forward(self, x):
        x = x.unsqueeze(1).unsqueeze(3)  # 增加通道维度和高度维度
        # 在输入张量x上增加通道维度和高度维度,以满足卷积层的输入要求
        x = self.conv1(x)
        # 将输入张量x传递给卷积层
        x = self.relu1(x)
        # 对卷积层的输出应用ReLU激活函数
        x = x.view(x.size(0), -1)
        # 将卷积层的输出展平为二维张量,第一维为批次大小,第二维为特征维度
        x = self.fc1(x)
        # 将展平后的张量传递给全连接层,得到最终的输出
        return x

model = CNN(input_dim=X.shape[1])
# 创建CNN模型的实例,输入维度为X的特征数

模型使用均方误差(MSE)作为损失函数,并使用Adam优化器对模型参数进行优化,学习率设置为0.01。

# 设置损失函数和优化器
criterion = nn.MSELoss()
# 定义均方误差损失函数
optimizer = optim.Adam(model.parameters(), lr=0.01)
# 定义Adam优化器,学习率为0.01,优化对象为模型的参数

5.训练模型

下边这段代码实现了卷积神经网络(CNN)模型的训练过程。

训练过程分为多个epoch,,每个epoch中模型在训练集上进行训练,并在验证集上进行评估。

在每个epoch结束时,打印当前的epoch数、平均训练损失和平均验证损失,以监控模型的训练进度和性能。这个训练过程重复进行指定的epoch数,以优化模型参数并提高模型的性能。

# 训练模型
num_epochs = 20
# 设置训练的轮数为20
train_losses = []
val_losses = []
# 定义用于存储训练损失和验证损失的列表

for epoch in range(num_epochs):
    model.train()
    # 将模型设置为训练模式
    train_loss = 0.0
    # 初始化训练损失为0.0
    for data, labels in train_loader:
        # 遍历训练数据加载器,获取每个批次的数据和标签
        optimizer.zero_grad()
        # 将优化器的梯度置零
        outputs = model(data)
        # 将数据输入模型,得到预测输出
        loss = criterion(outputs, labels.unsqueeze(1))
        # 计算预测输出和真实标签之间的损失,需要将标签增加一个维度以匹配输出的形状
        loss.backward()
        # 反向传播计算梯度
        optimizer.step()
        # 更新模型参数
        train_loss += loss.item() * data.size(0)
        # 累加训练损失,乘以批次大小以得到总损失
    train_loss /= len(train_loader.dataset)
    # 计算平均训练损失,除以训练集的样本数
    train_losses.append(train_loss)
    # 将平均训练损失添加到训练损失列表中

    model.eval()
    # 将模型设置为评估模式
    val_loss = 0.0
    # 初始化验证损失为0.0
    with torch.no_grad():
        # 禁用梯度计算,以减少内存占用和加速计算
        for data, labels in val_loader:
            # 遍历验证数据加载器,获取每个批次的数据和标签
            outputs = model(data)
            # 将数据输入模型,得到预测输出
            loss = criterion(outputs, labels.unsqueeze(1))
            # 计算预测输出和真实标签之间的损失,需要将标签增加一个维度以匹配输出的形状
            val_loss += loss.item() * data.size(0)
            # 累加验证损失,乘以批次大小以得到总损失
    val_loss /= len(val_loader.dataset)
    # 计算平均验证损失,除以验证集的样本数
    val_losses.append(val_loss)
    # 将平均验证损失添加到验证损失列表中

    print(f"Epoch [{epoch+1}/{num_epochs}], Train Loss: {train_loss:.4f}, Val Loss: {val_loss:.4f}")
    # 打印当前轮数、训练损失和验证损失

程序执行到此处,将会得到训练过程中训练集和验证集的Loss值。

6.在测试集上评估模型

最后我们将训练好的模型应用在测试集当中,记得要应用之前归一化的影射规则,将预测数据反归一化处理。

# 在测试集上评估模型
model.eval()
# 将模型设置为评估模式
test_preds = []
# 定义用于存储测试集预测值的列表
with torch.no_grad():
    # 禁用梯度计算,以减少内存占用和加速计算
    for data, _ in test_loader:
        # 遍历测试数据加载器,获取每个批次的数据
        outputs = model(data)
        # 将数据输入模型,得到预测输出
        test_preds.extend(outputs.numpy())
        # 将预测输出转换为NumPy数组并添加到测试集预测值列表中

test_preds = scaler_y.inverse_transform(np.array(test_preds).reshape(-1, 1)).flatten()
# 对测试集预测值进行反归一化,将其转换为原始尺度
test_labels = scaler_y.inverse_transform(test_labels.numpy().reshape(-1, 1)).flatten()
# 对测试集真实标签进行反归一化,将其转换为原始尺度

然后对预测结果进行可视化处理:

# 绘制测试集的真实值和预测值
plt.figure(figsize=(8, 6))
# 创建一个大小为(8, 6)的图形
plt.plot(test_labels, label='True Values (Testing Set)')
# 绘制测试集的真实标签,并添加标签
plt.plot(test_preds, label='Predicted Values (Testing Set)')
# 绘制测试集的预测值,并添加标签
plt.xlabel('Sample')
# 设置x轴标签为"Sample"
plt.ylabel('House Price')
# 设置y轴标签为"House Price"
plt.title('True vs. Predicted Values (Testing Set)')
# 设置图形标题为"True vs. Predicted Values (Testing Set)"
plt.legend()
# 添加图例
plt.tight_layout()
# 调整子图参数,使之填充整个图像区域
plt.show()
# 显示图形

测试集预测结果,由于训练具有一定随机性,所以每次运行结果会有一定差别

三、“一行代码”实现CNN回归预测任务(pytorch框架)

上边章节演示了使用MATLAB实现CNN回归预测的基础代码演示,不过我们在实际研究中可能会面临更为复杂的困境:

  • 导入自己的数据后,网络结构一改就频频报错
  • 代码被改得乱七八糟,看的头大
  • 不知道该画哪些图、怎么画图
  • 想要学习更规范的代码编程
  • ……

按照本专栏的惯例,笔者封装了快速实现CNN回归预测的函数,在设定好相关参数后,只需要一行代码,就可以实现数据集训练集/验证集/测试集快速划分、快速绘制训练集/测试集预测结果对比图、绘制预测误差图,导出训练过程数据、计算MAE/MSE/MAPE/RMSE/R等指标等等常用功能,这个函数的介绍如下:

def FunRegCNNs(dataX, dataY, divideR, cLayer, poolingLayer, fcLayer, options, setting):
    """
    使用CNN进行回归预测的快速实现函数
    
    参数:
    - dataX: 输入数据,形状为(num_samples, num_channels, height, width)的numpy数组
    - dataY: 输出结果,考虑可以为多维的numpy数组
    - divideR: 数据集划分比例,形如[train_ratio, val_ratio, test_ratio]的列表
    - cLayer: 卷积层结构,形状为(num_conv_layers, 5)的numpy数组,每一行代表一个卷积层的参数[filter_height, filter_width, num_filters, stride, padding]
    - poolingLayer: 池化层结构,形状为(num_conv_layers, 5)的列表,每一行代表一个池化层的参数['pool_type', pool_height, pool_width, stride, padding],其中pool_type可以是'maxPooling2dLayer'或'averagePooling2dLayer'或'none'
    - fcLayer: 全连接层结构,形状为(num_fc_layers,)的列表,每一个元素代表一个全连接层的输出维度,如果为空列表则只有一个输出维度等于1的全连接层
    - options: 网络训练相关的选项,字典类型,包含以下键值对:
      - 'solverName': 优化器类型,可以是'sgdm'或'rmsprop'或'adam',默认为'adam'
      - 'MaxEpochs': 最大迭代次数,默认为30
      - 'MiniBatchSize': 批量大小,默认为128
      - 'InitialLearnRate': 初始学习率,默认为0.005
      - 'ValidationFrequency': 验证频率,即每多少次迭代进行一次验证,默认为50
      - 'LearnRateSchedule': 学习率调度方式,可以是'piecewise'或'none',默认为'none'
      - 'LearnRateDropPeriod': 学习率下降周期,默认为10
      - 'LearnRateDropFactor': 学习率下降因子,默认为0.95
    - setting: 其他选项,字典类型,包含以下键值对:
      - figflag: 是否绘制图像,'on'为绘制,'off'为不绘制
      - deviceSel: 训练设备选择,可以是'cpu'或'gpu',默认为'gpu',当设置为'gpu'时,如果gpu硬件不可用,则会自动切换到cpu
      - seed: 随机种子,整数,设置为0时不启用,设置为其他整数时启用,不同的整数为不同的种子值,变换种子值会影响结果,相同种子的计算结果是一致的,缺省时为不设置随机种子
      - minmax: 是否进行归一化,布尔值,默认为True
      
    返回值:
    - foreData: 测试集的回归预测结果
    - foreDataTrain: 训练集的回归预测结果
    - model: 训练好的PyTorch模型
    - info: 包含训练过程中的损失和准确率信息的字典

看注释写的蛮多的似乎有点唬人,其实使用起来比较简单。

例如上边波士顿房价预测的案例,整个第二章节代码可以用下述几行轻松实现:

import numpy as np
from khCNNreg import FunRegCNNs

# 1.读取 housing.txt 文件
data = np.loadtxt('housing.txt')

# 2.提取输入变量和输出变量
X = data[:, :13]  # 通过数组切片操作,将数据的前13列提取出来,赋值给变量X
y = data[:, 13]   # 通过数组切片操作,将数据的第14列提取出来,赋值给变量y
X = X.reshape(X.shape[0], 1, 1, X.shape[1])  # 对输入数据进行转置
divideR = [0.7, 0.1, 0.2]  # 设置数据集划分比例 训练集:验证集:测试集

# 3.设置网络结构
cLayer = np.array([[3, 1, 32, 1, 2]]) # 卷积层结构
poolingLayer = [['none', 0, 0, 2, 0]] # 设置池化层结构
fcLayer = []  # 设置全连接层结构

# 4.设置网络训练选项
options = {
'MaxEpochs': 100,          # 最大训练轮数为100
'MiniBatchSize': 64,       # 小批量数据大小为64
'InitialLearnRate': 0.01,  # 初始学习率为0.01
'ValidationFrequency': 5,  # 每5个epoch进行一次验证
'LearnRateDropPeriod': 10, # 每10个epoch学习率下降一次
'LearnRateDropFactor': 0.9 # 学习率下降因子为0.9
}

# 5.设置其他选项
setting = {
    'figflag': 'on',    # 显示图形
    'deviceSel': 'gpu', # 使用GPU作为设备
    'seed': 42,         # 随机种子设置为42
    'minmax': True      # 进行最小最大值归一化
}

# 6.调用 FunRegCNNs 函数进行测试
foreData, foreDataTrain, model, info = FunRegCNNs(X, y, divideR, cLayer, poolingLayer, fcLayer, options, setting)

上述代码中留下需要设置的,都是必要的参数,这也是为了在保证代码易用性的同时充分保证灵活性。

运行上述代码可以得到一系列图片和指标,这些在写论文过程中都是很有用的

具体包括:

在命令行窗口还会打印出以下内容:

四、总结

使用封装函数对复杂的CNN训练和评估流程进行了高度封装,大家只需要提供数据和指定参数,就可以轻松进行模型的训练和评估,大大减轻了同学们负担;另外函数接收多个参数作为输入,包括网络结构和训练选项等,使得用户可以根据自己的需求灵活地定制和配置模型,适应各种不同的应用场景;此函数不仅实现了CNN模型的训练,还对模型的性能进行了全面评估,并返回了训练过程中的详细信息,助力用户快速理解模型的性能,并进行后续的优化调整。

需要上述案例的代码和封装函数的代码,同学们可以在公众号 khscience(看海的城堡)中回复“CNN回归预测”获取。

扩展阅读

3.1 Mr.看海:神经网络15分钟入门!足够通俗易懂了吧

3.2 Mr.看海:神经网络15分钟入门!——反向传播到底是怎么传播的?

3.3 Mr.看海:神经网络15分钟入门!使用python从零开始写一个两层神经网络

3.4 Mr.看海:用深度学习做了下中国股市预测,结果是...

3.5 Mr.看海:使用MATLAB快速搭建神经网络实现分类任务(模式识别)

3.6 Mr.看海:【深度学习-第1篇】深度学习是什么、能干什么、要怎样学?

3.7 Mr.看海:【深度学习-第2篇】CNN卷积神经网络30分钟入门!足够通俗易懂了吧(图解)

3.8 Mr.看海:【深度学习-第3篇】使用MATLAB快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例

3.9 Mr.看海:【深度学习-第4篇】使用MATLAB快速实现CNN多变量回归预测

3.10 Mr.看海:【深度学习-番外1】Win10系统搭建VSCode+Anaconda+Pytorch+CUDA深度学习环境和框架全过程

3.11 Mr.看海:【深度学习-第5篇】使用Python快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例(使用pytorch框架)

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

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

相关文章

【Linux】磁盘文件和软硬链接

上篇博客我们说了内存级文件,就是文件加载到内存中它的一些操作。那么不可能所有文件文件都要加载到内存中,大部分文件都要存在与一种可以永久性存储数据的硬件中,就是我们要说的磁盘。现在的笔记本电脑用的都是硬盘,你可以理解为…

C语言 io-文件拷贝

#include <stdio.h> int main(int argc, const char *argv[]) {//1文件拷贝到2文件FILE* fileAfopen(argv[1],"r");FILE* fileBfopen(argv[2],"w");if(NULLfileA){perror("fopen");return -1;}if(NULLfileB){perror("fopen");re…

【Vue】scoped解决样式冲突

默认情况下写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。 全局样式: 默认组件中的样式会作用到全局&#xff0c;任何一个组件中都会受到此样式的影响 局部样式: 可以给组件加上scoped 属性,可以让样式只作用于当前组件 一、代码示例 BaseOne…

MYSQL ORDER BY

在MySQL中&#xff0c;默认情况下&#xff0c;升序排序会将NULL值放在前面&#xff0c;因为在排序过程中&#xff0c;NULL会被视为最小值。然而&#xff0c;有时会要求在升序排序中需要将NULL值放在最后。 例如根据日期升序时就会出现这种问题 方案一&#xff1a; SELECT sor…

Docker成功启动Rabbitmq却访问不了管理页面问题解决

目录 启动步骤&#xff1a; 无法访问问题总结&#xff1a; 启动步骤&#xff1a; 拉取镜像&#xff1a; docker pull rabbitmq 运行&#xff1a; docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq进入容器&#xff1a; docker exec -it 容器id /bin/…

2024.6.9周报

目录 摘要 ABSTRACT 一、文献阅读 1、相关信息 2、摘要 3、文献解读 1、Introduction 2、文章主要贡献 3、模型架构 4、实验 4、结论 二、代码实现 总结 摘要 本周我阅读了一篇题目为《Unlocking the Potential of Transformers in Time Series Forecasting with …

流水线建构apk、abb实战(二)

gradlew 命令生成apk、aab包 其实构建应用程序包就几个命令&#xff1a; ### 生成AAB&#xff1a; gradlew bundleRelease #输出到[project]/build/outputs/bundle/release/下 gradlew bundleDebug### 生成APK&#xff1a; gradlew assembleRelease gradlew assembleDebug###…

Linux系统之fc命令的基本使用

Linux系统之fc命令的基本使用 一、fc命令介绍1.1 fc命令简介1.2 fc命令用途 二、fc命令的帮助信息2.1 fc的man帮助2.2 fc命令的使用帮助2.3 fc命令与history命令区别 三、fc命令的基本使用3.1 显示最近执行的命令3.2 指定序号查询历史命令3.3 使用vim编辑第n条历史命令3.4 替换…

openh264 自适应量化功能源码分析

openh264 OpenH264是一个开源的H.264/AVC视频编解码器&#xff0c;由Cisco公司发起并贡献了最初的代码基础。它提供了一个用于视频编码和解码的库&#xff0c;支持H.264视频压缩标准&#xff0c;广泛应用于视频会议、流媒体和视频存储等领域。OpenH264是实现H.264编解码功能的…

关于vue2 antd 碰到的问题总结下

1.关于vue2 antd 视图更新问题 1.一种强制更新 Vue2是通过用Object…defineProperty来设置数据的getter和setter实现对数据和以及视图改变的监听的。对于数组和对象这种引用类型来说&#xff0c;getter和setter无法检测到它们内部的变化。用这种 this.$set(this.form, "…

T-Rex2: Towards Generic Object Detection via Text-Visual Prompt Synergy论文解读

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、引言二、文献综述1. Text-prompted Object Detection2. Visual-prompted Object Detection3. Interactive Object Detection 三、模型方法1. Visual-Text P…

在vscode 中使用npm的问题

当我装了 npm和nodejs后 跑项目在 文件中cmd的话可以直接运行但是在 vscode 中运行的时候就会报一下错误 解决方法就是在 vscode 中吧 power shell换成cmd 来运行就行了

JVM相关:Java内存区域

Java 虚拟机&#xff08;JVM)在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。 Java运行时数据区域是指Java虚拟机&#xff08;JVM&#xff09;在执行Java程序时&#xff0c;为了管理内存而划分的几个不同作用域。这些区域各自承担特定的任务&#xff0c…

知攻善防应急

知攻善防应急靶场一 小李在值守的过程中&#xff0c;发现有 CPU 占用飙升&#xff0c;出于胆子小&#xff0c;就立刻将服务器关机&#xff0c;并找你帮他分析&#xff0c;这是他的服务器系统&#xff0c;请你找出以下内容&#xff0c;并作为通关条件&#xff1a; 1.攻击者的 …

今日增长工具精选| 8个SaaS出海必备运营工具

一、SurveyMonkey 是一个灵活、方便、经济实惠的在线调查工具&#xff0c;可以通过自行设计定制化问卷&#xff0c;开展消费者调研&#xff0c;收集第一手数据&#xff0c;获取用户反馈。 客户涵盖财富100强公司以及其他不同规模和类型的组织&#xff0c;如公司、学术研究机构…

第二十六章CSS3续~

3.CSS3渐变属性 CSS3渐变(gradients)可以在两个或多个指定的颜色之间显示平稳的过渡。 以前&#xff0c;我们必须使用图像来实现这些效果。但是&#xff0c;通过使用CSS3渐变(gradients)&#xff0c;可以减少下载的事件和宽带的使用。由于渐变(gradient)是由浏览器生成的&…

首个文字生成手语模型来了!SignLLM通过文字描述来生成手语视频,目前已经支持八国手语!

SignLLM 是目前第一个通过文字描述生成手语视频的多语言手语模型。 该项目引入了首个多语言手语数据集 Prompt2Sign&#xff0c;它使用工具自动采集和处理网络上的手语视频&#xff0c;能够不断更新&#xff0c;且具有轻量化特点。 该模型当前支持 8 种手语类型。包括美国手语…

软件管理、rpm安装、yum安装、源码编译安装

目录 一、Windows安装/卸载 二、软件的卸载&#xff1a; 三、Linux的软件安装和卸载 3.1rpm安装 第一步&#xff1a;挂在光盘 第二步&#xff1a;查看/mnt 第三步&#xff1a;切换到/mnt/Packages 第四步&#xff1a;安装 3.2yum安装&#xff08;使用关盘作为yum源&…

29 - 买下所有产品的客户(高频 SQL 50 题基础版)

29 - 买下所有产品的客户 selectc.customer_id fromCustomer c group byc.customer_id havingcount(c.product_key)(select count(distinct product_key) from Product);

java版知识付费saas租户平台:剖析现代知识付费平台的功能架构与运营逻辑

在数字化学习的时代背景下&#xff0c;知识付费平台已经成为教育行业的一颗璀璨明星&#xff0c;以其用户需求为中心&#xff0c;提供便捷高效的学习途径。这些平台汇聚了众多专业知识&#xff0c;覆盖职业技能、生活兴趣和人文社科等多个领域&#xff0c;满足不同用户的学习需…