用Pytorch搭建一个房价预测模型

news2024/11/25 16:25:54

本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052

目录

一、项目介绍

二、准备工作

三、实验过程

3.1数据预处理

3.2拆分数据集

3.3构建PyTorch模型

3.3.1.数据转换

3.3.2定义模型架构

3.3.3定义损失准则和优化器

3.3.4创建数据加载器

3.3.5训练模型

四、原理讲解

五、补充


一、项目介绍

        在此项目中,目的是预测爱荷华州Ames的房价,给定81个特征,描述了房子、面积、土地、基础设施、公共设施等。埃姆斯数据集具有分类和连续特征的良好组合,大小适中,也许最重要的是,它不像其他类似的数据集(如波士顿住房)那样存在潜在的红线或数据输入问题。在这里我将主要讨论PyTorch建模的相关方面,作为一点额外的内容,我还将演示PyTorch中开发的模型的神经元重要性。你可以在PyTorch中尝试不同的网络架构或模型类型。本项目中的重点是方法论,而不是详尽地寻找最佳解决方案。

二、准备工作

为了准备这个项目,我们首先需要下载数据,并通过以下步骤进行一些预处理。

from sklearn.datasets import fetch_openml
data = fetch_openml(data_id=42165, as_frame=True)

关于该数据集的完整描述,你可以去该网址查看:https://www.openml.org/d/42165。

查看数据特征

import pandas as pd
data_ames = pd.DataFrame(data.data, columns=data.feature_names)
data_ames['SalePrice'] = data.target
data_ames.info()

下面是DataFrame的信息

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1460 entries, 0 to 1459
Data columns (total 81 columns):
Id               1460 non-null float64
MSSubClass       1460 non-null float64
MSZoning         1460 non-null object
LotFrontage      1201 non-null float64
LotArea          1460 non-null float64
Street           1460 non-null object
Alley            91 non-null object
LotShape         1460 non-null object
LandContour      1460 non-null object
Utilities        1460 non-null object
LotConfig        1460 non-null object
LandSlope        1460 non-null object
Neighborhood     1460 non-null object
Condition1       1460 non-null object
Condition2       1460 non-null object
BldgType         1460 non-null object
HouseStyle       1460 non-null object
OverallQual      1460 non-null float64
OverallCond      1460 non-null float64
YearBuilt        1460 non-null float64
YearRemodAdd     1460 non-null float64
RoofStyle        1460 non-null object
RoofMatl         1460 non-null object
Exterior1st      1460 non-null object
Exterior2nd      1460 non-null object
MasVnrType       1452 non-null object
MasVnrArea       1452 non-null float64
ExterQual        1460 non-null object
ExterCond        1460 non-null object
Foundation       1460 non-null object
BsmtQual         1423 non-null object
BsmtCond         1423 non-null object
BsmtExposure     1422 non-null object
BsmtFinType1     1423 non-null object
BsmtFinSF1       1460 non-null float64
BsmtFinType2     1422 non-null object
BsmtFinSF2       1460 non-null float64
BsmtUnfSF        1460 non-null float64
TotalBsmtSF      1460 non-null float64
Heating          1460 non-null object
HeatingQC        1460 non-null object
CentralAir       1460 non-null object
Electrical       1459 non-null object
1stFlrSF         1460 non-null float64
2ndFlrSF         1460 non-null float64
LowQualFinSF     1460 non-null float64
GrLivArea        1460 non-null float64
BsmtFullBath     1460 non-null float64
BsmtHalfBath     1460 non-null float64
FullBath         1460 non-null float64
HalfBath         1460 non-null float64
BedroomAbvGr     1460 non-null float64
KitchenAbvGr     1460 non-null float64
KitchenQual      1460 non-null object
TotRmsAbvGrd     1460 non-null float64
Functional       1460 non-null object
Fireplaces       1460 non-null float64
FireplaceQu      770 non-null object
GarageType       1379 non-null object
GarageYrBlt      1379 non-null float64
GarageFinish     1379 non-null object
GarageCars       1460 non-null float64
GarageArea       1460 non-null float64
GarageQual       1379 non-null object
GarageCond       1379 non-null object
PavedDrive       1460 non-null object
WoodDeckSF       1460 non-null float64
OpenPorchSF      1460 non-null float64
EnclosedPorch    1460 non-null float64
3SsnPorch        1460 non-null float64
ScreenPorch      1460 non-null float64
PoolArea         1460 non-null float64
PoolQC           7 non-null object
Fence            281 non-null object
MiscFeature      54 non-null object
MiscVal          1460 non-null float64
MoSold           1460 non-null float64
YrSold           1460 non-null float64
SaleType         1460 non-null object
SaleCondition    1460 non-null object
SalePrice        1460 non-null float64
dtypes: float64(38), object(43)
memory usage: 924.0+ KB

接下来,我们还将使用一个库,即 captum,它可以检查 PyTorch 模型的特征和神经元重要性。

pip install captum

 在做完这些准备工作后,我们来看看如何预测房价。

三、实验过程

3.1数据预处理

        在这里,首先要进行数据缩放处理,因为所有的变量都有不同的尺度。分类变量需要转换为数值类型,以便将它们输入到我们的模型中。我们可以选择一热编码,即我们为每个分类因子创建哑变量,或者是序数编码,即我们对所有因子进行编号,并用这些数字替换字符串。我们可以像其他浮动变量一样将虚拟变量送入,而序数编码则需要使用嵌入,即线性神经网络投影,在多维空间中对类别进行重新排序。我们在这里采取嵌入的方式。

import numpy as np
from category_encoders.ordinal import OrdinalEncoder
from sklearn.preprocessing import StandardScaler

num_cols = list(data_ames.select_dtypes(include='float'))
cat_cols = list(data_ames.select_dtypes(include='object'))

ordinal_encoder = OrdinalEncoder().fit(
    data_ames[cat_cols]
)
standard_scaler = StandardScaler().fit(
    data_ames[num_cols]
)

X = pd.DataFrame(
    data=np.column_stack([
        ordinal_encoder.transform(data_ames[cat_cols]),
        standard_scaler.transform(data_ames[num_cols])
    ]),
    columns=cat_cols + num_cols
)

3.2拆分数据集

       在构建模型之前,我们需要将数据拆分为训练集和测试集。在这里,我们添加了一个数值变量的分层。这可以确保不同的部分(其中五个)在训练集和测试集中都以同等的数量包含。

np.random.seed(12)  
from sklearn.model_selection import train_test_split

bins = 5
sale_price_bins = pd.qcut(
    X['SalePrice'], q=bins, labels=list(range(bins))
)
X_train, X_test, y_train, y_test = train_test_split(
    X.drop(columns='SalePrice'),
    X['SalePrice'],
    random_state=12,
    stratify=sale_price_bins
)

3.3构建PyTorch模型

        接下来开始建立我们的PyTorch模型。我们将使用PyTorch实现一个具有批量输入的神经网络回归,具体将涉及以下步骤。

  • 1. 将数据转换为Torch tensors
  • 2. 定义模型结构
  • 3. 定义损失标准和优化器。
  • 4. 创建一个批次的数据加载器
  • 5. 跑步训练

3.3.1.数据转换

首先将数据转换为torch tensors

from torch.autograd import Variable 

num_features = list(
    set(num_cols) - set(['SalePrice', 'Id'])
)
X_train_num_pt = Variable(
    torch.cuda.FloatTensor(
        X_train[num_features].values
    )
)
X_train_cat_pt = Variable(
    torch.cuda.LongTensor(
        X_train[cat_cols].values
    )
)
y_train_pt = Variable(
    torch.cuda.FloatTensor(y_train.values)
).view(-1, 1)
X_test_num_pt = Variable(
    torch.cuda.FloatTensor(
        X_test[num_features].values
    )
)
X_test_cat_pt = Variable(
   torch.cuda.LongTensor(
        X_test[cat_cols].values
    ).long()
)
y_test_pt = Variable(
    torch.cuda.FloatTensor(y_test.values)
).view(-1, 1)

        这可以确保我们将数字和分类数据加载到单独的变量中,类似于NumPy。如果你把数据类型混合在一个变量(数组/矩阵)中,它们就会变成对象。我们希望把数值变量弄成浮点数,把分类变量弄成长(或int),索引我们的类别。我们还将训练集和测试集分开。显然,一个ID变量在模型中不应该是重要的。在最坏的情况下,如果ID与目标有任何相关性,它可能会引入目标泄漏。我们已经把它从这一步的处理中删除了。

3.3.2定义模型架构

class RegressionModel(torch.nn.Module): 
  
    def __init__(self, X, num_cols, cat_cols, device=torch.device('cuda'), embed_dim=2, hidden_layer_dim=2, p=0.5): 
        super(RegressionModel, self).__init__() 
        self.num_cols = num_cols
        self.cat_cols = cat_cols
        self.embed_dim = embed_dim
        self.hidden_layer_dim = hidden_layer_dim
        
        self.embeddings = [
            torch.nn.Embedding(
                num_embeddings=len(X[col].unique()),
                embedding_dim=embed_dim
            ).to(device)
            for col in cat_cols
        ]
        hidden_dim = len(num_cols) + len(cat_cols) * embed_dim,
        
        # hidden layer
        self.hidden = torch.nn.Linear(torch.IntTensor(hidden_dim), hidden_layer_dim).to(device)
        self.dropout_layer = torch.nn.Dropout(p=p).to(device)
        self.hidden_act = torch.nn.ReLU().to(device)
        
        # output layer
        self.output = torch.nn.Linear(hidden_layer_dim, 1).to(device)
    
    def forward(self, num_inputs, cat_inputs):
        '''Forward method with two input variables -
        numeric and categorical.
        '''
        cat_x = [
            torch.squeeze(embed(cat_inputs[:, i] - 1))
            for i, embed in enumerate(self.embeddings)
        ]
        x = torch.cat(cat_x + [num_inputs], dim=1)
        x = self.hidden(x)
        x = self.dropout_layer(x)
        x = self.hidden_act(x)
        y_pred = self.output(x)
        return y_pred

house_model = RegressionModel(
    data_ames, num_features, cat_cols
)

        我们在两个线性层(上的激活函数是整流线性单元激活(ReLU)函数。这里需要注意的是,我们不可能将相同的架构(很容易)封装成一个顺序模型,因为分类和数值类型上发生的操作不同。

3.3.3定义损失准则和优化器

        接下来,定义损失准则和优化器。我们将均方误差(MSE)作为损失,随机梯度下降作为我们的优化算法。

criterion = torch.nn.MSELoss().to(device)
optimizer = torch.optim.SGD(house_model.parameters(), lr=0.001)

3.3.4创建数据加载器

现在,创建一个数据加载器,每次输入一批数据。

data_batch = torch.utils.data.TensorDataset(
    X_train_num_pt, X_train_cat_pt, y_train_pt
)
dataloader = torch.utils.data.DataLoader(
    data_batch, batch_size=10, shuffle=True
)

我们设置了10个批次的大小,接下来我们可以进行训练了。

3.3.5.训练模型

       基本上,我们要在epoch上循环,在每个epoch内推理出性能,计算出误差,优化器根据误差进行调整。这是在没有训练的内循环的情况下,在epochs上的循环。

from tqdm.notebook import trange

train_losses, test_losses = [], []
n_epochs = 30
for epoch in trange(n_epochs):
    train_loss, test_loss = 0, 0
  
    # print the errors in training and test:
    if epoch % 10 == 0 :
        print(
            'Epoch: {}/{}\t'.format(epoch, 1000),
            'Training Loss: {:.3f}\t'.format(
                train_loss / len(dataloader)
            ),
            'Test Loss: {:.3f}'.format(
                test_loss / len(dataloader)
            )
        )

 训练是在这个循环里面对所有批次的训练数据进行的。

for (x_train_num_batch,x_train_cat_batch,y_train_batch) in dataloader:
        (x_train_num_batch,x_train_cat_batch, y_train_batch) = (
                x_train_num_batch.to(device),
                x_train_cat_batch.to(device),
                y_train_batch.to(device))
        pred_ytrain = house_model.forward(x_train_num_batch, x_train_cat_batch)
        loss = torch.sqrt(criterion(pred_ytrain, y_train_batch)) 

        optimizer.zero_grad() 
        loss.backward() 
        optimizer.step()
        train_loss += loss.item()
        with torch.no_grad():
            house_model.eval()
            pred_ytest = house_model.forward(X_test_num_pt, X_test_cat_pt)
            test_loss += torch.sqrt(criterion(pred_ytest, y_test_pt))

        train_losses.append(train_loss / len(dataloader))
        test_losses.append(test_loss / len(dataloader))

训练结果如下:

我们取 nn.MSELoss 的平方根,因为 PyTorch 中 nn.MSELoss 的定义如下:

((input-target)**2).mean()

绘制一下我们的模型在训练期间对训练和验证数据集的表现。

plt.plot(
    np.array(train_losses).reshape((n_epochs, -1)).mean(axis=1),
    label='Training loss'
)
plt.plot(
    np.array(test_losses).reshape((n_epochs, -1)).mean(axis=1),
    label='Validation loss'
)
plt.legend(frameon=False)
plt.xlabel('epochs')
plt.ylabel('MSE')

        在我们的验证损失停止下降之前,我们及时停止了训练。我们还可以对目标变量进行排序和bin,并将预测结果与之对比绘制,以便了解模型在整个房价范围内的表现。这是为了避免回归中的情况,尤其是用MSE作为损失,即你只对一个中值范围的预测很好,接近平均值,但对其他任何东西都做得不好。

        我们可以看到,事实上,这个模型在整个房价范围内的预测非常接近。事实上,我们得到的Spearman秩相关度约为93%,具有非常高的显著性,这证实了这个模型的表现具有很高的准确性。

四、原理讲解

        深度学习神经网络框架使用不同的优化算法。其中流行的有随机梯度下降(SGD)、均方根推进(RMSProp)和自适应矩估计(ADAM)。我们定义了随机梯度下降作为我们的优化算法。另外,我们还可以定义其他优化器。

opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.6)
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.1)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.8, 0.98))

        SGD的工作原理与梯度下降相同,只是它每次只在一个例子上工作。有趣的是,收敛性与梯度下降相似,并且更容易占用计算机内存。

        RMSProp的工作原理是根据梯度符号来调整算法的学习率。最简单的变体是检查最后两个梯度符号,然后调整学习率,如果它们相同,则增加一个分数,如果它们不同,则减少一个分数。

        ADAM是最流行的优化器之一。它是一种自适应学习算法,根据梯度的第一和第二时刻改变学习率。

        Captum是一个工具,可以帮助我们了解在数据集上学习的神经网络模型的来龙去脉。它可以帮助我们学习以下内容。

  • 特征重要性

  • 层级重要性

  • 神经元的重要性

        这在学习可解释的神经网络中是非常重要的。在这里,综合梯度已经被应用于理解特征重要性。之后,还用层传导法来证明神经元的重要性。

五、补充

        既然我们已经定义并训练了我们的神经网络,那么让我们使用 captum 库找到重要的特征和神经元。

from captum.attr import (
    IntegratedGradients,
    LayerConductance,
    NeuronConductance
)
house_model.cpu()
for embedding in house_model.embeddings:
    embedding.cpu()

house_model.cpu()
ing_house = IntegratedGradients(forward_func=house_model.forward, )
#X_test_cat_pt.requires_grad_()
X_test_num_pt.requires_grad_()
attr, delta = ing_house.attribute(
 X_test_num_pt.cpu(),
 target=None,
 return_convergence_delta=True,
 additional_forward_args=X_test_cat_pt.cpu()
)
attr = attr.detach().numpy()

 现在,我们有了一个NumPy的特征重要性数组。层和神经元的重要性也可以用这个工具获得。让我们来看看我们第一层的神经元importances。我们可以传递house_model.act1,这是第一层线性层上面的ReLU激活函数。

cond_layer1 = LayerConductance(house_model, house_model.act1)
cond_vals = cond_layer1.attribute(X_test, target=None)
cond_vals = cond_vals.detach().numpy()
df_neuron = pd.DataFrame(data = np.mean(cond_vals, axis=0), columns=['Neuron Importance'])
df_neuron['Neuron'] = range(10)

这张图显示了神经元的重要性。显然,一个神经元就是不重要的。我们还可以通过对之前得到的NumPy数组进行排序,看到最重要的变量。

df_feat = pd.DataFrame(np.mean(attr, axis=0), columns=['feature importance'] )
df_feat['features'] = num_features
df_feat.sort_values(
    by='feature importance', ascending=False
).head(10)

 这里列出了10个最重要的变量

        通常情况下,特征导入可以帮助我们既理解模型,又修剪我们的模型,使其变得不那么复杂(希望减少过度拟合)。

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

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

相关文章

Linux查看端口

目录 1.查看已知端口的使用情况 2.查看所有端口的占用情况 3.查看占用端口的程序的进程号 4.杀死进程号 1.查看已知端口的使用情况 #例:8080 可使用命令: netstat -anp | grep 8080 结果如下: 还可以使用这条命令: netstat -tln | grep 8080 结果如下: 区别:第一条命令后面显示…

评分卡模型(二)基于评分卡模型的用户付费预测

评分卡模型&#xff08;二&#xff09;基于评分卡模型的用户付费预测 小P&#xff1a;小H&#xff0c;这个评分卡是个好东西啊&#xff0c;那我这想要预测付费用户&#xff0c;能用它吗 小H&#xff1a;尽管用&#xff5e; &#xff08;本想继续薅流失预测的&#xff0c;但想了…

DevExpress WinForms电子表格控件,更快拥有现代办公体验!(二)

DevExpress WinForm Spreadsheet组件能读写XLSx、XLS、CSV、TXT文件、打印并导出为PDF等&#xff0c;为终端用户提供了当今流行的办公UI体验&#xff01;在上文中&#xff08;点击这里回顾>>&#xff09;&#xff0c;我们介绍了DevExpress WinForm中Excel启发式的电子表格…

【计算机网络-数据链路层】集线器、网桥、交换机

本文许多文字和图片使用了湖科大教书匠&#xff08;高军老师&#xff09;的 PPT&#xff0c;在此表示感谢。正是他让非科班的我能以奇妙的方式走进网络的世界。 文章目录1 【物理层】集线器&#xff08;Hub&#xff09;——共享式以太网1.1 为什么使用集线器&#xff1f;1.2 集…

救命,我好像发现了测试工程师面试通关秘籍

一、自我介绍 &#xff08;自我介绍不局限于下面模板&#xff0c;灵活表达&#xff09; 面试官你好&#xff0c;我叫xxx&#xff0c;今年xx岁&#xff0c;家乡是xx省xx市。20xx年毕业后一直从事软件测试工作&#xff0c;到现在已经x年了。 目前为止&#xff0c;经历过x家公司…

基于SpringBoot的大学生体质测试管理系统源码数据库论文

目录 目录 1 绪 论 1.1系统背景介绍 1.2课题研究的目的和意义 1.3系统的研究现状 1.4系统实现的功能 1.5系统的特点 2 开发工具和技术 2.1 B/S体系结构 2.2 Java语言简介 2.3 SpringBoot框架 2.4 MySQL简介 3 系统需求分析 3.1 系统可行性分析及目的…

JS数组reduce()方法详解及高级技巧

reduce()方法可以搞定的东西&#xff0c;for循环&#xff0c;或者forEach方法有时候也可以搞定&#xff0c;那为啥要用reduce()&#xff1f;这个问题&#xff0c;之前我也想过&#xff0c;要说原因还真找不到&#xff0c;唯一能找到的是&#xff1a;通往成功的道路有很多&#…

QtableWidget插入数据卡顿优化方法

最近要使用Qtablewidget保存4300多的数据&#xff0c;发现以下刷新4300条数据&#xff0c;界面会变得非常卡顿&#xff0c;于是想了优化一下&#xff1b;因为要对所有数据排序&#xff0c;想用一下Qtablewidget自动排序功能&#xff0c;而且数据量不多&#xff0c;不想采用动态…

【教学类-32-02】十二生肖2.0版(绘画+手工+排序+左右分类+玩牌)(中班:偏科学-数)

作品展示 2.0样式——动物头部方向随机向左、或者向右 背景需求 1.0样式——动物头部方向全部向右&#xff0c; 我希望孩子分类的时候还能够“判断生肖头部的方向做一个左右分类” 素材准备&#xff1a; 1、图片准备 office PPT2013里面有一个图标的功能&#xff0c;内置大量…

java继承类怎么写

继承类是通过把父类的方法和属性继承到一个类中&#xff0c;而子类的方法和属性是子类自己定义的。 Java中有一个很重要的概念叫做继承&#xff0c;这也是 Java语言的精髓所在。Java语言提供了一种机制&#xff0c;叫做派生类。在 Java中&#xff0c;如果没有实现了某个派生类方…

终端和文件运行python代码

如何创建python文件&#xff1f;新建一个txt&#xff0c;然后修改后缀名为 .py&#xff0c; 然后修改打开方式为记事本&#xff0c;写入一行代码&#xff0c;然后关闭 接下来如何运行呢&#xff1f;让他输出这一段代码 winR cmd 回车 &#xff0c;然后输入python 文件地址 我…

ChatGPT 未来的前景以及发展趋势

当谈到ChatGPT的未来和发展趋势时&#xff0c;需要考虑人工智能技术以及文本生成和交互的迅速发展。在这方面&#xff0c;ChatGPT的前景非常有希望&#xff0c;因为它是一种迄今为止最先进的人工智能技术之一。 ChatGPT是一种基于机器学习的自然语言处理技术&#xff0c;它能够…

MyBatis学习总结(四) MyBatis 延迟加载策略MyBatis 一级缓存、二级缓存MyBatis注解开发

MyBatis学习总结&#xff08;四&#xff09; MyBatis 延迟加载策略/MyBatis 一级缓存、二级缓存/MyBatis注解开发 一、 MyBatis 延迟加载策略 通过前面的学习&#xff0c;我们已经掌握了 MyBatis 中一对一&#xff08;多对一&#xff09;、一对多、多对多关系的配置及实现&am…

【Android入门到项目实战-- 5.1】—— 广播(一):接收系统广播

目录 一、什么是广播&#xff1f; 二、广播的类型 标准广播 有序广播 三、接收系统广播 1、动态注册监听网络变化 如何注册广播接收器&#xff1f; 2、静态注册实现开机启动 使用快捷方式创建广播接收器 实现开机广播 一、什么是广播&#xff1f; android广播机制就是…

全网最详细,Jmeter性能测试-性能进阶, 多协议实战Websocket/Dubbo(七)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 Jmeter是目前主流的…

自行车及电动自行车出口美国GCC认证要求

所有进口商和美国本土制造商都必须签发普通合格证书&#xff08;GCC&#xff09;证明其产品符合具体规定要求。进口商和本土制造商应向认可的第三方实验室提交样品测试其产品是否符合相关安全法规。提供第三方实验室测试报告&#xff0c;合格证书由进口商和本土制造商提供。在外…

pytorch通过不同的维度提高cifar10准确率

各个维度通过模型通过优化器通过batchsize通过数据增强总结当前网络的博客上都是普遍采用某个迁移学习训练cifar10&#xff0c;无论是vgg&#xff0c;resnet还是其他变种模型&#xff0c;最后通过实例代码&#xff0c;将cifar的acc达到95以上&#xff0c;本篇博客将采用不同的维…

九龙证券|300亿空袭,港股吓懵了!

港股再度大幅回调&#xff0c;腾讯成了“导火索”。 当地时刻4月11日&#xff0c;腾讯大股东Prosus发布公告称拟再度进行回购&#xff0c;作为回购方案的一部分&#xff0c;Prosus本周将采纳行动&#xff0c;把9600万股腾讯股票以凭据方式移入香港中心结算系统&#xff0c;以便…

八、市场活动-创建

需求分析 用户在市场活动主页面,点击"创建"按钮,弹出创建市场活动的模态窗口; 用户在创建市场活动的模态窗口填写表单,点击"保存"按钮,完成创建市场活动的功能. *所有者是动态的(//在现实市场活动主页面时&#xff0c;就从数据库中查询出所有用户并且…

基于ChatGLM-6b+Streamlit+QDrant+DuckDuckGo搭建本地问答机器人及缓解时效性问题方案

本地部署chatglm及缓解时效性问题的思路&#xff1a; 模型使用chatglm-6b 4bit&#xff0c;推理使用hugging face&#xff0c;前端应用使用streamlit或者gradio。 微调对显存要求较高&#xff0c;还没试验。可以结合LoRA进行微调。 缓解时效性问题&#xff1a;通过本地数据库…