神经网络学习笔记(6) - 从训练到评价

训练集与测试集的划分

和其他机器学习问题一样,要评价模型,就要先将原始训练数据划分为训练集和测试集,用训练集训练模型,再用测试集来评价。假设原始数据data是Pandas DataFrame,columns是一个特征列名构成的数组,target是结果列名构成的数组。可以用sklearn的train_test_split函数直接生成训练集和测试集。


features = data[columns]
target = data[targets]
from sklearn.model_selection import train_test_split
X_train, x_test, Y_train, y_test = train_test_split(features,target,test_size=0.2)

分批训练

当训练样本数量过大时,为了降低内存消耗和性能考虑,可以在每次迭代时分批次进行子迭代。
在神经网络里,有以下术语:
epoch 所有训练集样本都经过一次正向/反向传播
batch_size 一次进行正向/反向传播的样本数
iteration 每batch_size个样本进行一次正向/反向传播

假设总共有1000个训练样本,设置batch_size为500,epoch为10000,那么我们就先用前500个样本进行一次参数更新,再用后500个样本进行一次更新,就需要两次iteration来完成一次epoch。而这样的epoch总共进行10000次。值得注意的是,推荐把每个epoch喂给模型的数据打散(随机化),能一定程度防止过拟合。这里使用了PyTorch的DataLoader的shuffle参数来实现。


#转换为PyTorch的Tensor
X_train_tensor = torch.tensor(X_train.values, dtype = torch.float)
x_test_tensor = torch.tensor(x_test.values, dtype = torch.float)
Y_train_tensor = torch.tensor(Y_train.values, dtype = torch.float)
y_test_tensor = torch.tensor(y_test.values, dtype = torch.float)

#使用PyTorch的DataLoader进行分批训练
import torch.utils.data as data_utils
train_data = data_utils.TensorDataset(X_train_tensor, Y_train_tensor)
train_loader = data_utils.DataLoader(train_data, batch_size=100, shuffle=True)

#注意训练样本的Tensor维度。确保第一维为样本,第二维为特征。因此可以直接取Tensor的shape[1]作为输入节点的个数。
inp = X_train_tensor.shape[1]
out = Y_train_tensor.shape[1]
hid = 10

loss_fn = torch.nn.MSELoss()

model = torch.nn.Sequential(torch.nn.Linear(inp, hid),
torch.nn.Linear(hid, out))
optimizer = torch.optim.Adam(model.parameters(), lr = 0.001)

num_epochs = 10000

for epoch in range(num_epochs + 1):
    for i, (features, target) in enumerate(train_loader):
        output = model(features)
        loss = loss_fn(output, target)

        optimizer.zero_grad()

        loss.backward()

        optimizer.step()

#训练完毕后,要调用model.eval()进入模型评价模式。
model.eval()

#计算测试集的预测结果
with torch.no_grad():
    y_pred_tensor = model(x_test_tensor)

#使用sklearn的r2_score进行评价
sklearn.metrics.r2_score(y_test, y_pred)

#模型的保存和加载。加载后的模型就能像跳过训练过程,直接使用了。
torch.save(model, 'my_model')
saved_model = torch.load('my_model')
y_pred_tensor = saved_model(x_test_tensor)
y_pred = y_pred_tensor.detach().numpy()