PyTorch构建简单的网络——波士顿房价数据集
一、数据集准备
1.数据加载
使用波士顿房价数据集(Boston House Price Dataset)下载地址。使用sklearn.datasets.load_boston
即可加载
(scikit-learn,又写作sklearn,是一个开源的基于python语言的机器学习工具包。sklearn中常用的模块有分类、回归、聚类、降维、模型选择、预处理)
from sklearn.datasets import load_boston
boston = load_boston()
使用keys()
查看字典关键字,其中data
是我们要使用的输入数据(506组数据,每组数据有13个属性,13个属性的意义分别对应feature_names
的13个值),target
是目标值(或叫输出值,是我们要预测的值。506组数据,一组对应一个目标值)。
2.数据预处理
通过print(boston['data'])
发现数据的数量级差别很大,为了能让梯度下降速度更快,需要做特征缩放(Feature Scaling)或均值归一化(Mean Normalization),这两个操作都是针对某一属性而不是所有数据的。
特征缩放 | 均值归一化 |
---|---|
x/max | (x-mean)/(max-min) |
这里我们使用sklearn MinMaxScaler()
函数。
from sklearn.preprocessing import MinMaxScaler
ss_input = MinMaxScaler()
ss_output = MinMaxScaler()
data_set_input = ss_input.fit_transform(boston['data'])
data_set_output = ss_output.fit_transform(boston['target'][:, np.newaxis])
boston['target'][:, np.newaxis]
的作用是将一维数组转换为二维数组,不然会出现以下错误:
3.划分训练集、测试集
数据集划分有两种方法:
分为2类 | 分为3类 | |
---|---|---|
训练集 Training set | 70% | 60% |
交叉验证集 Cross Validation set | 20% | |
测试集 Test set | 30% | 20% |
训练集:用来拟合模型中的参数
交叉验证集:用来选择合适的模型参数。模型中除了一些需要学习的参数,还有一些需要提前人为指定的参数,验证集就是为了选取效果最佳的模型所对应的参数
测试集:用来衡量从交叉验证集中选出的最优模型的性能
简单点,分为两类:
train_set_input = data_set_input[0:350, :]
train_set_output = data_set_output[0:350, :]
test_set_input = data_set_input[351:506, :]
test_set_output = data_set_output[351:506, :]
二、构建网络
构建最简单的网络:全连接,只有三层,输入—>14个神经元的隐藏层—>输出。由于有13个属性,所以输入单元有13个;1层隐藏层,隐藏层单元个数随便选的(隐藏层数量大于1层时,各隐藏层单元数目一般一样)。
激活函数选取: 常用的激活函数有ReLU()、Sigmoid()、Tanh()
。
ReLU | Sigmoid | Tanh |
---|---|---|
使用较多 | mean=0.5 输出只有正值 |
mean=0 输出有正有负 |
既然ReLU()
是使用较多的,那隐藏层激活函数用ReLU()
;房价只有正值,所以输出层用 Sigmoid()
。
from torch import nn
net = nn.Sequential(
nn.Linear(13, 14),
nn.ReLU(),
nn.Linear(14, 1),
nn.Sigmoid()
)
另一种方法:
注意:
用这种方法时,需要将predict = net(input)
换成predict = net.forward(input)
class net_structure(nn.Module):
def __init__(self,input_num,hidden_num,output_num):
super(net_structure,self).__init__()
self.net = nn.Sequential(
nn.Linear(input_num, hidden_num),
nn.ReLU(),
nn.Linear(hidden_num, output_num),
nn.Sigmoid()
)
def forward(self, input):
return self.net(input)
net = net_structure(13,14,1)
如果网络权重不初始化,pytorch有一套默认初始化机制,使用下面代码查看权重:
print(net.state_dict().keys())
三、定义损失函数和优化器
损失函数就是目标函数cost(在函数里都用loss表示。cost、loss意思一样,目标函数、损失函数、误差函数意思也一样)。nn.MSELoss()
函数就是均方损失函数(y-y*)^2
优化器就是根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数值的作用。大家都说RMSprop()
最好使,那就用这个。
cost = nn.MSELoss()
optimizer = torch.optim.RMSprop(net.parameters(), lr=0.01)
四、训练网络
网络输入只能是张量,数据集是numpy.ndarray
(可以使用train_set_input.type()
查看数据类型),需要使用torch.FloatTensor()
进行类型转换。
变量声明:
1.max_epoch:迭代次数
2.iter_loss:每次迭代损失函数的平均值
3.batch_loss:一次迭代中所有样本的损失函数的值
梯度下降中,学习速率a乘的是每次迭代所有样本的目标函数cost,关于权重weight的导数,的和sum。因此每次迭代需要将“目标函数cost关于权重weight的导数的和sum”清零。