Chapter4 利用机器学习解决分类和回归问题

news2025/8/2 18:00:09

目录

4.1 机器学习和神经网络基本概念

4.1.1 感知器

4.1.2 前向传播

4.1.3 反向传播

4.1.4 过拟合和欠拟合

4.2 利用神经网络解决回归问题

4.2.1 问题介绍

4.2.2 利用pytorch解析数据

4.2.2 利用pytorch定义网络结构

4.2.3 开始训练

4.2.4 将模型进行保存

4.3 利用pytorch解决手写数字识别问题


4.1 机器学习和神经网络基本概念

4.1.1 感知器

        每一个节点称之为一个神经元,神经元之间通过相应运算来完成信息的传递或者是特征的抽取。

        这个运算一般是指线性运算:x_{1}^{'}= f(x_{1},x_{2},x_{3},1)\ \ \ y=wx+b,这里的b是指偏置项,这个我在机器学习的博客已经详细说明,这里不再解释。

        所谓深度学习,就是把中间的隐藏层变得更深。

         一个感知器可以理解为如上图的结构:如上上图从输入层到隐藏层有三个感知器,感知器的输入为上层的经过激活函数算出的结果,通过输入与权值的加权得到了加权和,再由非线性激活函数得到下一层的输入,总结以来,符合下列公式:y_{output} = g(w^{T}x_{input})

4.1.2 前向传播

        前向传播的前提是参数已知,即w全部已知(我们训练的参数)

4.1.3 反向传播

         我们定义损失为输出层真实值和测量值之间的偏差,通过反向传播实现参数的逐层调节参数(调节w,b使得损失值最小),同时用梯度下降的方法进行求解,对参数方程进行求导拿到梯度,顺着导数下降的方向对导数进行调节直到找到最低点,最低点所对应的值就是我们所要求解的值。

4.1.4 过拟合和欠拟合

4.2 利用神经网络解决回归问题

4.2.1 问题介绍

         利用pytorch回归网络解决房价模型预测问题:利用已知的十三种信息,预测第十四种信息!

4.2.2 利用pytorch解析数据

        我们要用回归问题解决房价预测问题,我们通过十三种的数据(地段、房屋面积、房价指数....)预测房价,数据集如下:

利用机器学习解决分类和回归问题

        我们首先要把数据集读取到我们的变量中,代码如下:

import torch
import numpy as np
import re
ff = open("/home/liuhongwei/桌面/housing.data").readlines()
data = []
for item in ff:
	out = re.sub(r"\s{2,}", " ",item).strip()           #由于不同列空的空格数量不一致,都处理为1个空格,即将多个空格编成一个空格
	print(out)
	data.append(out.split(" "))			    #空格对数据进行分割
data = np.array(data).astype(np.float)                      #转换成float类型
print(data)
print(data.shape)
Y = data[:,-1]
X = data[:,0:-1]                                            #定义自变量和因变量

X_train = X[0:496,...]
Y_train = Y[0:496,...]
X_test = X[496:,...]
Y_test = Y[496:,...]

print(X_train.shape)
print(Y_train.shape)
print(X_test.shape)
print(Y_test.shape)

        打开数据集文件,制定按行读取。对每一行进行读取,但存在一个问题,每一行的数据间隔虽然是以空格隔开的,但有的空了一个空格有的空了多个空格,我们用正则表达式去掉多余的空格。然后用np库函数将数据转换成浮点型向量。我们再定义了训练集和测试集。

4.2.2 利用pytorch定义网络结构

class Net(torch.nn.Module):
	def __init__(self,n_feature,n_out):
		super(Net,self).__init__()              		 #super来继承父类
		self.predict = torch.nn.Linear(n_feature,n_out)		#定义线性函数

	def forward(self,x):
		out = self.pridect(x)
		return out

net = Net(13,1)

        我们定义一个回归网络,初始化的时候传入特征(n_feature)和输出(n_out),用super继承父类,定义一个线性函数回归模型。定义了只有一个隐藏层的网络。

4.2.3 开始训练

import torch
import numpy as np
import re


#解析数据

#读取所有行的数据
ff = open("/home/liuhongwei/桌面/housing.data").readlines()
data = []
for item in ff:
	out = re.sub(r"\s{2,}", " ",item).strip()           #由于不同列空的空格数量不一致,都处理为1个空格,即将多个空格编成一个空格
	#print(out)
	data.append(out.split(" "))			    #空格对数据进行分割
data = np.array(data).astype(np.float)                      #转换成float类型
#print(data)
#print(data.shape)
Y = data[:,-1]
X = data[:,0:-1]                                            #定义自变量和因变量

X_train = X[0:496,...]
Y_train = Y[0:496,...]
X_test = X[496:,...]
Y_test = Y[496:,...]

#print(X_train.shape)
#print(Y_train.shape)
#print(X_test.shape)
#print(Y_test.shape)

#搭建网络:搭建回归网络

class Net(torch.nn.Module):
	def __init__(self,n_feature,n_out):
		super(Net,self).__init__()              		 #super来继承父类
		self.predict = torch.nn.Linear(n_feature,n_out)		#定义线性函数

	def forward(self,x):
		out = self.predict(x)
		return out

net = Net(13,1)
#定义loss

loss_func = torch.nn.MSELoss()             				#采用均方损失作为loss


#定义优化器

optimizer = torch.optim.SGD(net.parameters(),lr = 0.0001)		#利用SGD作为损失函数,学习率=0.0001

#开始训练

for i in range(10000):
	x_data = torch.tensor(X_train,dtype = torch.float32)
	y_data = torch.tensor(Y_train,dtype = torch.float32)

	pred = net.forward(x_data)					#定义前向运算
	pred = torch.squeeze(pred)					#用线性函数计算出输出,这时的pred是二维的 496*1 496
	loss = loss_func(pred,y_data) * 0.001				#定义loss

	optimizer.zero_grad()						#将神经网络参数置为0
	loss.backward()							#反响传播
	optimizer.step()						#对优化好的参数进行更新
	
	print("item:{},loss:{}".format(i,loss))
	print(pred[0:10])						#预测结果的前十个值
	print(y_data[0:10])

        代码已经标注了,但是训练结果不尽人意。误差较大,即使加大训练次数也没用,因为已经收敛了,模型处于欠拟合的状态。我们修改损失函数Adam。

#optimizer = torch.optim.SGD(net.parameters(),lr = 0.0001)		#利用SGD作为损失函数,学习率=0.0001
optimizer = torch.optim.Adam(net.parameters(),lr = 0.0001)		#利用Adam作为损失函数,学习率=0.0001

        

         好像好一点了。我们再适当增加下学习率:

         好像又更好了一点。我们再加入隐藏层:

#搭建网络:搭建回归网络

class Net(torch.nn.Module):
	def __init__(self,n_feature,n_out):
		super(Net,self).__init__()              		 #super来继承父类
		self.hidden = torch.nn.Linear(n_feature,100)
		self.predict = torch.nn.Linear(100,n_out)		#定义线性函数

	def forward(self,x):
		out = self.hidden(x)
		out = torch.relu(out)
		out = self.predict(out)
		return out

net = Net(13,1)

        效果卓越!但是不难发现,测试集合和训练集合的loss存在差异性,主要是因为样本容量比较小

4.2.4 将模型进行保存

torch.save(net,"/home/liuhongwei/桌面/model.pkl")   #模型整体性保存

         在桌面上有了我们的模型数据,我们尝试去加载它。

import torch
import numpy as np
import re


class Net(torch.nn.Module):
	def __init__(self,n_feature,n_out):
		super(Net,self).__init__()              		 #super来继承父类
		self.hidden = torch.nn.Linear(n_feature,100)
		self.predict = torch.nn.Linear(100,n_out)		#定义线性函数

	def forward(self,x):
		out = self.hidden(x)
		out = torch.relu(out)
		out = self.predict(out)
		return out


#读取所有行的数据
ff = open("/home/liuhongwei/桌面/housing.data").readlines()
data = []
for item in ff:
	out = re.sub(r"\s{2,}", " ",item).strip()           #由于不同列空的空格数量不一致,都处理为1个空格,即将多个空格编成一个空格
	#print(out)
	data.append(out.split(" "))			    #空格对数据进行分割
data = np.array(data).astype(np.float)                      #转换成float类型
Y = data[:,-1]
X = data[:,0:-1]                                            #定义自变量和因变量

X_train = X[0:496,...]
Y_train = Y[0:496,...]
X_test = X[496:,...]
Y_test = Y[496:,...]


net = torch.load("/home/liuhongwei/桌面/model.pkl")
loss_func = torch.nn.MSELoss()             				#采用均方损失作为loss


x_test = torch.tensor(X_test,dtype = torch.float32)
y_test = torch.tensor(Y_test,dtype = torch.float32)

pred = net.forward(x_test)					#定义前向运算
pred = torch.squeeze(pred)					#用线性函数计算出输出,这时的pred是二维的 496*1 496
loss_test = loss_func(pred,y_test) * 0.001			#定义loss
print("loss_test:{}".format(loss_test))

4.3 利用pytorch解决手写数字识别问题

代码解释:

手写数字识别的数据集已经集成在torchvision这个包中,

import torchvision.datasets as dataset引用了数据集,我们用

train_data = dataset.MNIST(root = "/home/liuhongwei/桌面/dataset",train=True,transform=transforms.ToTensor(),download=True)

        加载了手写数字的训练集,定义了存放数据集的路径,下载训练集,并将训练集转化成tensor形式的,如果文件夹内没有该数据集则进行下载。

train_loader = data_untils.Dataloader(dataset = train_data,batch_size = 64,shuffle=True)

        对数据进行分批提取,分为64块进行读取并随机打乱。

        定义一个卷积层和一个线性层完成对手写数字的分类:在cnn的结构中,我们采用序列工具构建我们的网络结构,定义卷积层Conv2d(通道数量、输出的通道、卷积核大小)

import torch
import torchvision.datasets as dataset
import torchvision.transforms as transforms
import torch.utils.data as data_utils
from CNN import CNN
#data
train_data = dataset.MNIST(root="mnist",
                           train=True,
                           transform=transforms.ToTensor(),
                           download=True)

test_data = dataset.MNIST(root="mnist",
                           train=False,
                           transform=transforms.ToTensor(),
                           download=False)
#batchsize
train_loader = data_utils.DataLoader(dataset=train_data,
                                     batch_size=64,
                                     shuffle=True)

test_loader = data_utils.DataLoader(dataset=test_data,
                                     batch_size=64,
                                     shuffle=True)

cnn = CNN()
cnn = cnn.cuda()
#loss

loss_func = torch.nn.CrossEntropyLoss()

#optimizer

optimizer = torch.optim.Adam(cnn.parameters(), lr=0.01)

#training
for epoch in range(10):
    for i, (images, labels) in enumerate(train_loader):
        images = images.cuda()
        labels = labels.cuda()

        outputs = cnn(images)
        loss = loss_func(outputs, labels)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    print("epoch is {}, ite is "
          "{}/{}, loss is {}".format(epoch+1, i,
                                     len(train_data) // 64,
                                     loss.item()))
    #eval/test
    loss_test = 0
    accuracy = 0
    for i, (images, labels) in enumerate(test_loader):
        images = images.cuda()
        labels = labels.cuda()
        outputs = cnn(images)
        #[batchsize]
        #outputs = batchsize * cls_num
        loss_test += loss_func(outputs, labels)
        _, pred = outputs.max(1)
        accuracy += (pred == labels).sum().item()

    accuracy = accuracy / len(test_data)
    loss_test = loss_test / (len(test_data) // 64)

    print("epoch is {}, accuracy is {}, "
          "loss test is {}".format(epoch + 1,
                                   accuracy,
                                   loss_test.item()))

torch.save(cnn, "model/mnist_model.pkl")




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

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

相关文章

云中马在A股上市:总市值约为40亿元,叶福忠为实际控制人

11月18日,浙江云中马股份有限公司(下称“云中马”,SH:603130)在上海证券交易所主板上市。本次上市,云中马的发行价为19.72元/股,发行数量为3500万股,募资总额约为6.90亿元,募资金额约…

码农必备?清华大学开源了一款写代码神器。。。

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 提升程序员编码效率,是一个经久不衰的话题,从最初用纯文本编辑器到后来代码自动补全,再到后来基于AI智能补全代码,开发者效率的确在不断提升。 关于新工…

这就是程序员眼中的函数吗?(一)

小叮当的任意门1. 函数是什么?2. C语言中的函数分类1. 库函数2. 自定义函数3. 函数的参数1. 实际参数(实参)2. 形式参数(形参)4. 函数的调用1. 传值调用2. 传址调用练习1. 写一个函数可以判断一个数是不是素数三级标题…

5分钟实现「视频检索」:基于内容理解,无需任何标签

Notebook 教程:text-video retrieval 「视频检索」任务就是输入一段文本,检索出最符合文本描述的视频。随着各类视频平台的兴起和火爆,网络上视频的数量呈现井喷式增长,「视频检索」成为人们高效查找视频的一项新需求。传统的视频…

Matlab点云处理及可视化第1期—基于KD树的邻域点搜索(柱状邻域、球状邻域及KNN)

目录 1 概述 2 代码实现 3 可视化验证 数据及完整代码获取方式: 观前提示:本文文字内容请勿直接用于论文写作,否则后果自负。 特别提示:《Matlab点云处理及可视化》系列文章旨在为初入点云处理领域的朋友提供一份较为权威、可…

MR直播(混合现实直播)做一场高品质企业培训

阿酷TONY / 2022-11-18 / 长沙 MR,是英文Mixed Reality两个单词的缩写,中文翻译为混合现实。 MR混合现实直播技术是通过在现实环境中引入虚拟场景信息,增强用户体验的真实感,具有真实性、实时互动性等特点。 MR直播解决方案是深…

基于springboot农产品交易平台的设计与实现

摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于特色农产品电商平台 当然也不能排除在外,随着网络技术的不断成熟,带动了特色农产品电商平台,它彻底…

软件需求分析——需求的理论基础

如果有兴趣了解更多相关内容,可以来我的个人网站看看:瞳孔空间 一:需求的涵义 研究对象:软件加强型系统中的软件 软件加强型系统:泛指由计算机技术支持的互相联系着的一组人类活动组成的系统。与物理设备和人类社会…

linux网络协议栈源码分析 - 传输层(TCP的输出)

1、TCP write系统调用(tcp_sendmsg) 1.1、write系统调用 socket的write系统调用栈: write最终调用tcp_sendmsg发送消息。 1.2、tcp_sendmsg报文分段 tcp_sendmsg主要是对用户的消息按MSS进行分段、添加到发送队列并将用户数据拷贝到分段里面,根据相关判断设置PSH标…

[附源码]SSM计算机毕业设计超市收银系统论文JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

学生台灯是灯管的好还是led的好?分享学生专用台灯第一品牌

给学生使用的话肯定是led灯更好的,主要是对眼睛有保护作用的,灯管一般当做主要照明灯具是可以的,在家中客厅里,卧室就是灯管,使用led灯是想要补足亮度的,全光谱的国AA级台灯,更健康、更适应人类…

计算机网络---ARP、DHCP与ICMP

(一)IP 地址与硬件地址 IP地址是网络层使用的地址,它是分层次等级的。硬件地址是数据链路层使用的地址(MAC地址),它是平面式的。在网络层及网络层之上使用IP地址,IP地址放在IP数据报的首部&…

并肩刘德华,对战周杰伦,腾格尔老师线上演唱会即将拉开帷幕

在刚刚结束的第三十五届金鸡奖上面,著名爱国艺人刘德华,又一次出现在大众的视野当中。来自香港的天王刘德华,是一个著名的音乐人和演员,他拳拳的爱国之情,也感动了无数的粉丝。 刘德华作为中国华语乐坛的中坚力量&…

22071班(11月18日)

1.在串口工具进行输入: echo 1 > /dev/myled0 ---->led1灯点亮 echo 0 > /dev/myled0 ---->led1灯熄灭 echo 1 > /dev/myled1 ---->led1灯点亮 echo 0 > /dev/myled1 ---->led1灯熄灭 echo 1 > /dev/myled2 ----…

【附源码】计算机毕业设计JAVA校园跑腿平台

【附源码】计算机毕业设计JAVA校园跑腿平台 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JAVA mybati…

什么是PaaS平台

PaaS平台概述 PaaS平台通常是基于IaaS平台构建的,PaaS平台和IaaS平台最大的差别是需求即服务。所有的管理都是以服务为粒度的,在IaaS以资源管理为中心的平台上提供了更高层次的抽象。 PaaS的本质 (1)运维自动化,故障…

统计聚类法的基本步骤:

统计聚类法的基本步骤: 1>形成数据框 2>计算距离阵 计算n个样品两两间的距离D。 3>进行系统聚类 (I)构造n个类,每个类只包含一个样品; (2)合并距离最近的两类为一新类; (3)计算新类与当前各类的距离,若类个数为1,…

观测云产品更新|Pipeline 使用体验优化;支持写入用户的自定义事件;自定义查看器支持选择更多类型的数据等

观测云更新 Pipeline 使用体验优化 Pipeline 支持过滤条件配置多选 支持将任意一个 Pipeline 脚本设置为“默认 Pipeline 脚本“,若当前数据类型在匹配 Pipeline 处理的时候,未匹配到其他的 Pipeline 脚本,则数据会按照默认 Pipeline 脚本的…

vs2017编译的64位libssh2库

需求:使用sftp上传下载文件 环境:windows vs2017 参考 链接: link 链接: link 编译 环境准备 libssh2依赖于openssl和zlib,所以需要有所以需要先编译:openssl和zlib才行。openssl和zlib。openssl和zlib我是下载人家编译好的…

【MySQL基础】数据库系统之关系型数据库与非关系型数据库

目录 一、数据库系统 1. 数据库 2. 数据库应用 3. 数据库管理系统(数据库软件) 3.1关系型数据库【RDBMS】 3.2非关系型数据库【NoSQL】 4. SQL和数据库管理系统的关系 5. 关系型数据库管理系统的组成 💟 创作不易,不妨点…