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

数据集介绍

数据集采用了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激活

python 复制代码
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参数初始化

python 复制代码
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参数初始化

python 复制代码
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参数初始化

python 复制代码
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

训练机制

python 复制代码
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参数初始化

相关推荐
AI狂热爱好者4 分钟前
A3超级计算机虚拟机,为大型语言模型LLM和AIGC提供强大算力支持
服务器·人工智能·ai·gpu算力
边缘计算社区4 分钟前
推理计算:GPT-o1 和 AI 治理
人工智能·gpt
虞书欣的66 分钟前
Python小游戏24——小恐龙躲避游戏
开发语言·python·游戏·小程序·pygame
FHYAAAX14 分钟前
【机器学习】任务十:从函数分析到机器学习应用与BP神经网络
开发语言·python
PyAIGCMaster23 分钟前
python环境中,敏感数据的存储与读取问题解决方案
服务器·前端·python
OBOO鸥柏1 小时前
OBOO鸥柏“触摸屏广告一体机交互”亮相2024中国珠海航展
大数据·人工智能·科技·交互
何曾参静谧1 小时前
「Py」模块篇 之 PyAutoGUI库自动化图形用户界面库
运维·python·自动化
Geeksend邮件营销1 小时前
定时清理潜在客户列表中的无效邮箱可提高EDM电子邮件自动化营销邮件送达率
人工智能·产品运营·用户运营·内容运营
pumpkin845141 小时前
客户端发送http请求进行流量控制
python·网络协议·http
新加坡内哥谈技术1 小时前
提升AI性能的关键大型语言模型(LLM)压缩策略
人工智能·语言模型·自然语言处理