基于深度学习多层感知机进行手机价格预测

news2024/10/7 11:16:19

数据集介绍

数据集采用了Kaggle实战数据集,链接如下,如有需要可自行下载

https://www.kaggle.com/datasets/atefehmirnaseri/cell-phone-price/data

数据集简要介绍

battery_power:电池的总能量存储(毫安时)

blue:设备是否有蓝牙功能,1 表示有,0 表示没有

clock_speed:微处理器执行指令的速度

dual_sim:设备是否支持同时使用两张 SIM 卡

fc:前置摄像头的质量(以百万像素为单位)

four_g:设备是否支持 4G 网络

int_memory:设备的内部存储容量(以 GB 为单位)

m_dep:设备的厚度(以厘米为单位)

mobile_wt:设备的重量

n_cores:处理器的核心数量

pc:主摄像头的质量(以百万像素为单位)

px_height:像素分辨率的高度

px_width:像素分辨率的宽度

ram:随机存取存储器的容量(以 MB 为单位)

sc_h:设备屏幕的高度(以厘米为单位)

sc_w:设备屏幕的宽度(以厘米为单位)

talk_time:设备满电时支持的最长通话时间

three_g:设备是否支持 3G 网络

touch_screen:设备是否有触摸屏

wifi:设备是否有 WiFi 功能

price_range:设备的价格分类

其中要预测的标签值为price_range,价格范围为四分类,标签值为0,1,2,3

代码开源地址

由于Kaggle数据集并未提供测试集数据的标签值,所以本篇博客为基于其训练集数据集进行划分训练测试训练的样例讲解.

Kaggle代码地址

Phone Price Prediction MLP | Kaggle

这是我于该数据集下发布的notebook链接,里面使用本篇博客要介绍的四种测试模型中的多层感知机+层归一化+Dropout正则+leaky relu激活的模型版本,但是其在训练集上的表现并不是最好的,其中有包括数据集信息提取和特征关系矩阵的提取和可视化.

Github开源地址

https://github.com/Foxbabe1q/Cell-Phone-Price-Prediction-using-MLP

这是我样例代码的Github仓库链接,其中包含了完整的4个模型的代码,模型二进制文件,以及损失和准确率变化图,但是由于官方并没有提供测试集标签,所以这里使用训练集进行划分后训练测试,具体的四个模型的建模方式在本篇博客进行讲解

Gitee码云开源地址

深度学习_手机价格预测数据集 Cell Phone Price Prediction using MLP: 使用多层感知机对手机价格数据集进行价格预测,数据集为Kaggle开源数据集,链接如下https://www.kaggle.com/datasets/atefehmirnaseri/cell-phone-price/data

与Github仓库中的内容相同

多层感知机建模详解

6层MLP加上sigmoid激活

class SimpleNet(nn.Module):
    def __init__(self, input_size, output_size):
        super(SimpleNet, self).__init__()
        self.fc1 = nn.Linear(input_size, 128)
        self.fc2 = nn.Linear(128, 256)
        self.fc3 = nn.Linear(256, 512)
        self.fc4 = nn.Linear(512, 256)
        self.fc5 = nn.Linear(256, 128)
        self.fc6 = nn.Linear(128, output_size)
    def forward(self, x):
        x = F.sigmoid(self.fc1(x))
        x = F.sigmoid(self.fc2(x))
        x = F.sigmoid(self.fc3(x))
        x = F.sigmoid(self.fc4(x))
        x = F.sigmoid(self.fc5(x))
        x = self.fc6(x)
        return x

这里使用了简单的6层全连接层,选用了Sigmoid激活,这里由于模型层数较深,容易造成过拟合的现象,但实际表现却是最好的,测试集准确率达到了百分之97

6层MLP加上层归一化,sigmoid激活,xavier参数初始化

class SimpleNet(nn.Module):
    def __init__(self, input_size, output_size):
        super(SimpleNet, self).__init__()
        self.fc1 = nn.Linear(input_size, 128)
        self.bn1 = nn.BatchNorm1d(num_features=128)
        self.dropout1 = nn.Dropout(0.2)
        self.fc2 = nn.Linear(128, 256)
        self.bn2 = nn.BatchNorm1d(num_features=256)
        self.dropout2 = nn.Dropout(0.2)
        self.fc3 = nn.Linear(256, 512)
        self.bn3 = nn.BatchNorm1d(num_features=512)
        self.dropout3 = nn.Dropout(0.2)
        self.fc4 = nn.Linear(512, 256)
        self.bn4 = nn.BatchNorm1d(num_features=256)
        self.dropout4 = nn.Dropout(0.2)
        self.fc5 = nn.Linear(256, 128)
        self.bn5 = nn.BatchNorm1d(num_features=128)
        self.dropout5 = nn.Dropout(0.2)
        self.fc6 = nn.Linear(128, output_size)
        self.initialize_weights()

    def initialize_weights(self):
        nn.init.xavier_normal_(self.fc1.weight)
        nn.init.xavier_normal_(self.fc2.weight)
        nn.init.xavier_normal_(self.fc3.weight)
        nn.init.xavier_normal_(self.fc4.weight)
        nn.init.xavier_normal_(self.fc5.weight)
        nn.init.xavier_normal_(self.fc6.weight)

    def forward(self, x):
        x = F.sigmoid(self.fc1(x))
        x = self.bn1(x)
        x = self.dropout1(x)

        x = F.sigmoid(self.fc2(x))
        x = self.bn2(x)
        x = self.dropout2(x)

        x = F.sigmoid(self.fc3(x))
        x = self.bn3(x)
        x = self.dropout3(x)

        x = F.sigmoid(self.fc4(x))
        x = self.bn4(x)
        x = self.dropout4(x)

        x = F.sigmoid(self.fc5(x))
        x = self.bn5(x)
        x = self.dropout5(x)

        x = self.fc6(x)
        return x

这里为了防止模型过拟合添加了Dropout正则,神经元失活比例为0.2,并且在每层后都添加了可学习的层归一化,由于使用了sigmoid激活,所以选用了较为适合这种激活方式的xavier参数初始化,最后的在测试集上的准确率达到了百分之87

6层MLP加上ReLU激活,kaiming参数初始化

class SimpleNet(nn.Module):
    def __init__(self, input_size, output_size):
        super(SimpleNet, self).__init__()
        self.fc1 = nn.Linear(input_size, 128)
        self.bn1 = nn.BatchNorm1d(num_features=128)
        self.dropout1 = nn.Dropout(0.2)
        self.fc2 = nn.Linear(128, 256)
        self.bn2 = nn.BatchNorm1d(num_features=256)
        self.dropout2 = nn.Dropout(0.2)
        self.fc3 = nn.Linear(256, 512)
        self.bn3 = nn.BatchNorm1d(num_features=512)
        self.dropout3 = nn.Dropout(0.2)
        self.fc4 = nn.Linear(512, 256)
        self.bn4 = nn.BatchNorm1d(num_features=256)
        self.dropout4 = nn.Dropout(0.2)
        self.fc5 = nn.Linear(256, 128)
        self.bn5 = nn.BatchNorm1d(num_features=128)
        self.dropout5 = nn.Dropout(0.2)
        self.fc6 = nn.Linear(128, output_size)
        self.initialize_weights()

    def initialize_weights(self):
        nn.init.kaiming_normal_(self.fc1.weight, nonlinearity='relu')
        nn.init.kaiming_normal_(self.fc2.weight, nonlinearity='relu')
        nn.init.kaiming_normal_(self.fc3.weight, nonlinearity='relu')
        nn.init.kaiming_normal_(self.fc4.weight, nonlinearity='relu')
        nn.init.kaiming_normal_(self.fc5.weight, nonlinearity='relu')
        nn.init.kaiming_normal_(self.fc6.weight, nonlinearity='relu')

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = self.bn1(x)
        x = self.dropout1(x)

        x = F.relu(self.fc2(x))
        x = self.bn2(x)
        x = self.dropout2(x)

        x = F.relu(self.fc3(x))
        x = self.bn3(x)
        x = self.dropout3(x)

        x = F.relu(self.fc4(x))
        x = self.bn4(x)
        x = self.dropout4(x)

        x = F.relu(self.fc5(x))
        x = self.bn5(x)
        x = self.dropout5(x)

        x = self.fc6(x)
        return x

在与上一个模型选用了相同的Dropout正则和层归一化方式后,将激活方式换为了ReLU,并将参数初始化方式换位了适合ReLU的kaiming参数初始化,最后在测试集上的准确率达到了百分之83

6层MLP加上Leaky ReLU激活,kaiming参数初始化

class SimpleNet(nn.Module):
    def __init__(self, input_size, output_size):
        super(SimpleNet, self).__init__()
        self.fc1 = nn.Linear(input_size, 128)
        self.bn1 = nn.BatchNorm1d(num_features=128)
        self.dropout1 = nn.Dropout(0.2)
        self.fc2 = nn.Linear(128, 256)
        self.bn2 = nn.BatchNorm1d(num_features=256)
        self.dropout2 = nn.Dropout(0.2)
        self.fc3 = nn.Linear(256, 512)
        self.bn3 = nn.BatchNorm1d(num_features=512)
        self.dropout3 = nn.Dropout(0.2)
        self.fc4 = nn.Linear(512, 256)
        self.bn4 = nn.BatchNorm1d(num_features=256)
        self.dropout4 = nn.Dropout(0.2)
        self.fc5 = nn.Linear(256, 128)
        self.bn5 = nn.BatchNorm1d(num_features=128)
        self.dropout5 = nn.Dropout(0.2)
        self.fc6 = nn.Linear(128, output_size)
        self.initialize_weights()

    def initialize_weights(self):
        nn.init.kaiming_normal_(self.fc1.weight, nonlinearity='leaky_relu')
        nn.init.kaiming_normal_(self.fc2.weight, nonlinearity='leaky_relu')
        nn.init.kaiming_normal_(self.fc3.weight, nonlinearity='leaky_relu')
        nn.init.kaiming_normal_(self.fc4.weight, nonlinearity='leaky_relu')
        nn.init.kaiming_normal_(self.fc5.weight, nonlinearity='leaky_relu')
        nn.init.kaiming_normal_(self.fc6.weight, nonlinearity='leaky_relu')

    def forward(self, x):
        x = F.leaky_relu(self.fc1(x))
        x = self.bn1(x)
        x = self.dropout1(x)

        x = F.leaky_relu(self.fc2(x))
        x = self.bn2(x)
        x = self.dropout2(x)

        x = F.leaky_relu(self.fc3(x))
        x = self.bn3(x)
        x = self.dropout3(x)

        x = F.leaky_relu(self.fc4(x))
        x = self.bn4(x)
        x = self.dropout4(x)

        x = F.leaky_relu(self.fc5(x))
        x = self.bn5(x)
        x = self.dropout5(x)

        x = self.fc6(x)
        return x

这里与上一个模型的唯一区别为将ReLU换为了Leaky ReLU,最后在测试集上的准确率也达到了百分之83

训练机制

def train():
    torch.manual_seed(0)
    train_dataset, test_dataset, input_dim, output_dim = create_dataset()

    model = SimpleNet(input_size=input_dim, output_size=output_dim).to(device)

    optimizer = optim.Adam(params=model.parameters(),lr=0.0001)

    criterion = nn.CrossEntropyLoss()

    epochs = 50

    loss_list = []
    acc_list = []

    start_time = time.time()

    for epoch in range(epochs):
        dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
        total_loss = 0.0
        num = 0
        start_time = time.time()
        total_correct = 0

        for x, y in dataloader:
            output = model(x)
            optimizer.zero_grad()
            loss = criterion(output, y)
            loss.backward()
            optimizer.step()
            total_loss += loss.item()*len(y)
            total_correct += (torch.argmax(output, dim=1)==y).sum().item()
            num += len(y)
        loss_list.append(total_loss)
        acc_list.append(total_correct/num)
        print("epoch:%d, loss:%.2f, time:%.2f" %(epoch+1,total_loss/num,time.time()-start_time))
    torch.save(model.state_dict(), 'model1.pt')

    fig = plt.figure(figsize=(6,4))
    axes1 = plt.subplot(1,2,1)
    axes2 = plt.subplot(1,2,2)
    axes1.plot(np.arange(1,epochs+1),loss_list)
    axes1.grid()
    axes1.set_title('loss')
    axes1.set_xlabel('epoch')
    axes1.set_ylabel('loss')
    axes2.plot(np.arange(1,epochs+1),acc_list)
    axes2.grid()
    axes2.set_title('accuracy')
    axes2.set_xlabel('epoch')
    axes2.set_ylabel('accuracy')
    fig.savefig('loss_acc1.png')
    plt.show()

在模型超参数设置上,选用Adam优化器,学习率设置为0.0001,epoch次数为50,batch_size为64

在选用不同模型的时候只需更改实例化的类即可,并且所有数据集在加载的时候已经经过了标准化

模型的效果可视化

6层MLP加上sigmoid激活

6层MLP加上层归一化,sigmoid激活,xavier参数初始化

6层MLP加上ReLU激活,kaiming参数初始化

6层MLP加上Leaky ReLU激活,kaiming参数初始化

 

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

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

相关文章

人工智能对未来工作影响的四种可能性

随着人工智能(AI)技术的迅速发展,其对人类工作的影响已成为讨论的热点话题。我们经常听到有关AI威胁论的观点,担心它将取代人类工作,但也有专家认为AI将成为一种辅助工具,帮助人类提升工作效率。宾夕法尼亚…

嵌入式硬件设计

嵌入式硬件设计是指针对嵌入式系统(一种专用的计算机系统,通常嵌入到其他设备中)进行的硬件设计工作。嵌入式系统广泛应用于消费电子、工业控制、医疗设备、汽车电子、航空航天等领域。以下是嵌入式硬件设计的主要内容和步骤: 1.…

括号匹配——(栈实现)

题目链接 有效的括号https://leetcode.cn/problems/valid-parentheses/description/ 题目要求 样例 解题代码 import java.util.*; class Solution {public boolean isValid(String str) {Stack<Character> stacknew Stack<>();for(int i0;i<str.length();i)…

传统流程图和N-S流程图的区别

传统流程图和N-S流程图在表示算法和逻辑结构时有不同的特点和用途。以下是它们的主要区别&#xff1a; ### 传统流程图 1. **符号多样**&#xff1a;传统流程图使用多种几何形状表示不同的操作类型&#xff0c;如椭圆表示开始和结束&#xff0c;平行四边形表示输入输出&#…

JumperServer入门

一、安装部署 官方安装文档&#xff1a;快速入门 - JumpServer 文档 机器准备 CentOS7 ip 角色 192.168.252.145 主节点 192.168.252.146 被控节点1 192.168.252.148 被控节点2 安装JumperServer curl -sSL https://resource.fit2cloud.com/jumpserver/jumpserver…

数据结构——七种排序(java)实现

文章目录 直接插入排序希尔排序选择排序冒泡排序快速排序归并排序计数排序 直接插入排序 思想&#xff1a; /*** 直接插入排序* 具有稳定性* 时间复杂度为&#xff1a;&#xff08;计算时间复杂度的时候应计算执行次数最多的语句类&#xff0c;在直接插入排序中次数最多的语句…

【AI大模型】深入Transformer架构:编码器部分的实现与解析(下)

目录 &#x1f354; 编码器介绍 &#x1f354; 前馈全连接层 2.1 前馈全连接层 2.2 前馈全连接层的代码分析 2.3 前馈全连接层总结 &#x1f354; 规范化层 3.1 规范化层的作用 3.2 规范化层的代码实现 3.3 规范化层总结 &#x1f354; 子层连接结构 4.1 子层连接结…

环境对于写作有何影响?

如果你是有灵性、热爱文学创作的人&#xff0c;多半就会喜欢安静的生活环境。因为你会感受到唯有在这样的环境里更才能够沉下心来思考创作的路径。而且此时的你&#xff0c;显得头脑清醒、思维活跃而自由&#xff0c;因之文思泉涌。 网络图&#xff1a;宁静的书房 反之&#x…

快递物流跟踪:掌握最后更新时间,高效筛选单号管理

在现代社会&#xff0c;快递物流已成为人们日常生活中不可或缺的一部分&#xff0c;无论是网购商品还是寄送文件&#xff0c;都离不开快递服务。然而&#xff0c;随着快递单量的不断增加&#xff0c;如何有效跟踪快递物流信息&#xff0c;特别是掌握最后更新时间&#xff0c;并…

SSM湘农乐市农产品交易平台-计算机毕业设计源码28246

目 录 SSM湘农乐市农产品交易平台 1 绪论 1.1研究背景 1.2研究意义 1.3研究方法 1.4论文结构与章节安排 2 湘农乐市农产品交易平台系统分析 2.1 可行性分析 2.2 系统流程分析 2.3 系统功能分析 2.4 系统用例分析 2.5本章小结 3 湘农乐市农产品交易平…

通信工程学习:什么是RIP路由信息协议

RIP&#xff1a;路由信息协议 RIP&#xff08;Routing Information Protocol&#xff09;路由信息协议是一种基于距离矢量算法的内部网关协议&#xff08;IGP&#xff09;&#xff0c;主要用于在自治系统&#xff08;AS&#xff09;内部进行路由信息的交换和传播。以下是关于RI…

第6篇:三大渗透测试框架权限维持技术

0x00 前言 在渗透测试中&#xff0c;有三个非常经典的渗透测试框架----Metasploit、Empire、Cobalt Strike。 那么&#xff0c;通过漏洞获取到目标主机权限后&#xff0c;如何利用框架获得持久性权限呢&#xff1f; 0x01 MSF权限维持 使用MSF维持权限的前提是先获得一个met…

SpringBoot驱动的明星周边产品电商解决方案

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

透过现象看本质,《Final Glory》缘何能成为现象级链游?

近期&#xff0c;《黑神话&#xff1a;悟空》的爆火不仅让 AAA 游戏重回焦点&#xff0c;也引发了玩家与开发者的热议。Web2 游戏的持续成功导致部分 Web3 玩家们的倒戈&#xff0c;对比之下 Web3 游戏存在生命周期短且商业模式难以明确的问题&#xff0c;尤其在当前加密市场环…

SSM社区慢性病管理系统—计算机毕业设计源码37572

摘 要 社区慢性病管理是社区卫生服务的主要内容&#xff0c;发展社区卫生服务是提供基本卫生服务、满足人民群众日益增长的卫生服务需求&#xff0c;也是提高人民健康水平的重要保障。为迎接慢性病防治的挑战我国进行了社区卫生服务改革&#xff0c;但由于社区卫生存在的诸多问…

✨ComfyUI workflow加密工具节点ComfyUI_CryptoCat

✨背景 玩comfyui的朋友都了解&#xff0c;工作流workflow是一种很重要的资产&#xff0c;可以通过workflow把一系列的处理工作组织起来&#xff0c;提升工作效率&#xff0c;甚至分享生成的图片就可以还原整个的工作流&#xff0c;对于分享传播是个好事情&#xff0c;但是对于…

C语言实践: 使用哨兵找出数组中的最大元素

开篇 本题来源于《编程珠玑》第9章【代码调优】课后习题8。旨在实现一段使用哨兵找出数组中最大元素的逻辑代码。 题目描述 如何在程序中使用哨兵来找出数组中的最大元素? 思路分析 这个问题相对来说比较简单&#xff0c;以初始值作为哨兵&#xff0c;和后续的值进行比较及处理…

前端公共资源CDN存储库大全

具体请前往&#xff1a;前端公共资源CDN存储库大全-持续更新

Python+ffmpeg实现字幕视频合并

背景 我想给自己的视频添加字幕&#xff0c;但是市面上比较好的软件都不太对我口味&#xff0c;要么贵&#xff0c;要么就是学习版不给力。兜兜转转&#xff0c;我决定用多款开源软件分步实现&#xff0c;当然&#xff0c;也可以去白piao某些软件的字幕功能。 驱动力 ffmpeg…

基于springboot vue3 在线考试系统设计与实现 源码数据库 文档

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm springcloud等开发框架&#xff09; vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆…