深度学习基础小结_项目实战:手机价格预测

发布于:2024-12-07 ⋅ 阅读:(35) ⋅ 点赞:(0)

目录

库函数导入

一、构建数据集

 二、构建分类网络模型

三、编写训练函数

四、编写评估函数

五、网络性能调优


鲍勃开了自己的手机公司。他想与苹果、三星等大公司展开硬仗。 他不知道如何估算自己公司生产的手机的价格。在这个竞争激烈的手机市场,你不能简单地假设事情。为了解决这个问题,他收集了各个公司的手机销售数据。

鲍勃想找出手机的特性(例如:RAM、内存等)和售价之间的关系。但他不太擅长机器学习。所以他需要你帮他解决这个问题。 在这个问题中,你不需要预测实际价格,而是要预测一个价格区间,表明价格多高。

需要注意的是: 在这个问题中,我们不需要预测实际价格,而是一个价格范围,它的范围使用 0、1、2、3 来表示,所以该问题也是一个分类问题。

数据说明:手机价格分类_数据集-阿里云天池 Mobile Price Classification

库函数导入

import torch
import torch.nn as nn
import pandas as pd
from sklearn.model_selection import train_test_split
from torch.utils.data import import Dataset,DataLoader,TensorDataset
from sklearn.preprocessing import StandardScaler
import time

一、构建数据集

数据共有 2000 条, 其中 1600 条数据作为训练集, 400 条数据用作测试集。 我们使用 sklearn 的数据集划分工作来完成。并使用 PyTorch 的 TensorDataset 来将数据集构建为 Dataset 对象,方便构造数据集加载对象。

"""构建数据"""
def phone_data_set(path):
    # 加载本地数据文件
    data = pd.read_csv(path)
    # 抽离特征和目标数据
    x = data.iloc[:,:-1]
    y = data.iloc[:,-1]
    # 标准化
    transfer = StanderdScaler()
    x = transfer.fit_transform(x.values)

    x = torch.tensor(x,dtype=torch.float32)
    y = torch.tensor(y.values,dtype=torch.int64) # 输出是分类结果,所以用整型
    # 数据集划分
    x_trian,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=42,stratify=y)
    return x_trian,x_test,y_train,y_test

class my_phone_data_loader(Dataset):
# TensorDataset 可取代该类的作用
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def __len__(self):
        return len(self.x)
    def __getitem__(self, index):
        return self.x[index],self.y[index]

def data_loader(x_trian,y_train,batch_size=16):
    # data=my_phone_data_loader(x_train,y_train)
    data = TensorDataset(x_train,y_trian)
    data_loader = DataLoader(data,batch_size=batch_size,shuffle=True)
    return data_loader
                                                                          

 二、构建分类网络模型

构建用于手机价格分类的模型叫做全连接神经网络。它主要由数个线性层来构建,在每个线性层后,还需使用激活函数。

"""模型 构建和初始化参数"""
class Net(torch.nn.Module):
    def __init__(self,input_features,out_features):
        super(Net,self).__init__()

        # 隐藏层 LeakyReLU 激活和输出层 Softmax 激活
        self.hide1 = nn.Sequential(nn.Linear(input_features,128),nn.LeakyReLU())
        self.hide2 = nn.Sequential(nn.Linear(128,256),nn.LeakyReLU())
        self.hide3 = nn.Sequential(nn.Linear(256,512),nn.LeakyReLU())
        self.hide4 = nn.Sequential(nn.Linear(512,128),nn.LeakyReLU())
        self.out = nn.Sequential(nn.Linear(128,out_features),nn.Softmax())
        self.initdata()

    def forward(self,input_data):
        # 前向传播
        x = self.hide1(iput_data)
        x=self.hide2(x)
        x=self.hide3(x)
        x=self.hide4(x)
        y_pred=self.out(x)

        return y_pred#分类结果,混淆矩阵 [[0.9,0.01,.02,.7],[...],...]

    def initdata(self):
        # 权重He初始化
        nn.init.kaiming_uniform_(self.hide1[0].weight,nonlinearity="leaky_relu")
        nn.init.kaiming_uniform_(self.hide2[0].weight,nonlinearity="leaky_relu")
        nn.init.kaiming_uniform_(self.hide3[0].weight,nonlinearity="leaky_relu")
        nn.init.kaiming_uniform_(self.hide4[0].weight,nonlinearity="leaky_relu")       

三、编写训练函数

网络编写完成之后,我们需要编写训练函数。所谓的训练函数,指的是输入数据读取、送入网络、计算损失、更新参数的流程,该流程较为固定。我们使用的是多分类交叉生损失函数、使用 SGD 优化方法。最终,将训练好的模型持久化到磁盘中。

"""训练数据"""
# 加载数据
x_train,x_test,y_trian,y_test=phone_data_set("./data/手机价格预测.csv")
def train():
    data_loader_=data_loader(x_train,y_trian)
    # 模型生成
    x_features=x_train.shape[1]
    y_features=torch.unique(y_trian).shape[0]# 输出特征(类别的数量)
    model=Net(x_features,y_features)
    # 初始化模型参数
    # 默认是初始化过的
    torch.nn.init.kaiming_uniform_(model.linear1.weight,nonlinearity="leaky_relu")
    torch.nn.init.kaiming_uniform_(model.linear2.weight,nonlinearity="leaky_relu") 


    # 3.损失函数
    loss_fn=torch.nn.CrossEntropyLoss()#torch.nn.MSELoss()#虽然分类的结果也可以用均方误差来计算,但是一般用交叉熵(因为计算出来的梯度更大)

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

    # 定义训练参数
    epoch=100
    for i in range(epoch):
        e=0
        count=0
        start_time=time.time()
        for x,y in data_loader_:
            count+=1
            # 生成预测值
            y_pred=model(x)#执行model对象的forward
            # 损失计算
            loss=loss_fn(y_pred,y)
            e+=loss
            # 梯度清零
            optim.zero_grad()
            # 反向传播
            loss.backward()
            # 更新参数
            optim.step()
        end_time=time.time()
        print(f"epoch:{i},loss:{e/count},time:{end_time-start_time}") 
    # 保存模型参数
    # model.linear1.weight.data
    torch.save(model.state_dict(),"./model/model.pth")

四、编写评估函数

评估函数、也叫预测函数、推理函数,主要使用训练好的模型,对未知的样本的进行预测的过程。这里使用前面单独划分出来的测试集来进行评估。

"""评估函数"""
def test():
    # 加载数据
    data_loader_=data_loader(x_test,y_test,batch_size=16)
    # data_loader_=DataLoader(data,batch_size=4,shuffle=True)
    # 加载模型
    # 模型生成
    x_test_features=x_test.shape[1]
    y_test_features=torch.unique(y_test).shape[0]# 类别数
    model=Net(x_test_features,y_test_features)
    # model.linear1.weight=model.linear1.weight.data
    state_dict=torch.load("./model/model.pth",map_location="cpu")
    model.load_state_dict(state_dict)
    total=0
    for x,y in data_loader_:
        y_pred=model(x)#[0.4,0.3,0.1,0.1,0.1]
        y_pred=torch.argmax(y_pred,dim=1)
        # print("y",y)
        # print("y_pred",y_pred)
        total+=torch.sum(y_pred==y)
    print(f"精准度:{total/len(x_test)}")

五、网络性能调优

可以通过以下方面对模型进行调优:

  1. 对输入数据进行标准化

  2. 调整优化方法

  3. 调整学习率

  4. 增加批量归一化层

  5. 增加网络层数、神经元个数

  6. 增加训练轮数


网站公告

今日签到

点亮在社区的每一天
去签到