很肝的东西,目前还在学习当中,就浅浅的先记录一下,等日后学完了再回来看看,或者逐行的加上注释
一.先看数据集
housing.data
这是关于某个地区的房价数据记录,前13列都是一些关于房子的特性指标
最后一列是关于房子的的价格
下面直接上代码
import torch
#data
import numpy as np
import re
ff = open("housing.data").readlines()
data = []
for item in ff:
out = re.sub(r"\s{2,}", " ", item).strip()
print(out)
data.append(out.split(" "))
data = np.array(data).astype(np.float32)
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)
#net
class Net(torch.nn.Module):
def __init__(self, n_feature, n_output):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, 100)
self.predict = torch.nn.Linear(100, n_output)
def forward(self, x):
out = self.hidden(x)
out = torch.relu(out)
out = self.predict(out)
return out
net = Net(13, 1)
#loss
loss_func = torch.nn.MSELoss()
#optimiter
optimizer = torch.optim.Adam(net.parameters(), lr=0.01)
#training
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)
loss = loss_func(pred, y_data) * 0.001
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("ite:{}, loss_train:{}".format(i, loss))
print(pred[0:10])
print(y_data[0:10])
#test
x_data = torch.tensor(X_test, dtype=torch.float32)
y_data = torch.tensor(Y_test, dtype=torch.float32)
pred = net.forward(x_data)
pred = torch.squeeze(pred)
loss_test = loss_func(pred, y_data) * 0.001
print("ite:{}, loss_test:{}".format(i, loss_test))
torch.save(net, "model/model.pkl")
大概说一下代码的具体执行流程
前几行是对数据的预处理环节,因为原生数据每一列之间有很多的空格,不利于我们后期的使用
所以使用正则表达式,对数据进行统一的处理
out = re.sub(r"\s{2,}", " ", item).strip()
这一行的代码就是把所有的空格全都换成了一个空格注意sub的第二个参数不是全空,而且是引号的中间有一个空格,这样方便我们以后对数据进行操作。
然后最后用strip去掉每一行的换行符。
然后使用np.array将数据转化成我们需要的格式并且类型是float32
然后就是处理数据,因为之前我们说过,前13列是房子的一些指标特征
而最后一列,就是第14列才是我们的房价数据
所以我们使用python中数组的切片然后提取我们的X和Y
Y = data[:, -1]
X = data[:, 0:-1]
然后划分我们的训练数据和测试数据
最近看西瓜书中说数据的划分有很多种办法,这我们就浅浅的随便分一下
前496条作为训练数据,后10条作为测试数据
X_train = X[0:496, ...]
Y_train = Y[0:496, ...]
X_test = X[496:, ...]
Y_test = Y[496:, ...]
下面就是一些高深莫测的代码了
我们需要定义我们的网络Net
class Net(torch.nn.Module):
def __init__(self, n_feature, n_output):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, 100)
self.predict = torch.nn.Linear(100, n_output)
def forward(self, x):
out = self.hidden(x)
out = torch.relu(out)
out = self.predict(out)
return out
介于目前还处于基础阶段,抛开这个类的定义不说
我们浅说一下
torch.nn.Module
先看一下官网的介绍
Base class for all neural network modules. Your models should also subclass this class. Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes: pytorch官网
就是说我们的model都应该继承于他
下面这些说法也均来自于网络:
根据官方注释我们了解到Module类是所有神经网络模块的基类,Module可以以树形结构包含其他的Module。Module类中包含网络各层的定义及forward方法,下面介绍我们如何定义自已的网络:
1.需要继承nn.Module类,并实现forward方法;
2.一般把网络中具有可学习参数的层放在构造函数__init__()中;
3.不具有可学习参数的层(如ReLU)可在forward中使用nn.functional来代替;
4.只要在nn.Module的子类中定义了forward函数,利用Autograd自动实现反向求导。
这里有一些名词比如LeRu函数还有Sigmoid等激活函数,日后慢慢讲解,
关于forward是说已知neural network的参数值向前计算
那backward就是说反向计算参数的值,
关于forward & backward 目前笔者的了解甚微,相信会在以后的文章里给大家带来更多的介绍。
因为是浅谈,所以38行以后的代码,我会在下一章中介绍。
今天就到这里咯,
peace&love