神经网络应用于回归问题
神经网络是处理回归问题的强大工具,它们能够学习输入数据和输出之间的复杂关系。
神经网络提供了一种灵活且强大的框架,用于建模和预测回归问题。通过 适当的 网络结构、训练策略和正则化技术,可以有效地从数据中学习并做出准确的预测。
在实际应用中,选择合适的网络架构和参数对于构建一个高效的回归模型至关重要。
所以说,虽然神经网络是处理回归问题的强大工具,但是也存在很多问题,需要我们掌握很多方法技巧才能建立一个高效准确的回归模型:
- 正则化(Regularization): 为了防止过拟合,可以在损失函数中添加正则化项,如L1或L2正则化。
- Dropout: 这是一种技术,可以在训练过程中随机地丢弃一些神经元的激活,以减少模型对特定神经元的依赖。
- 批量归一化(Batch Normalization): 通过对每一层的输入进行归一化处理,可以加速训练过程并提高模型的稳定性。
- 早停(Early Stopping): 当验证集上的性能不再提升时,停止训练以避免过拟合。
- 超参数调整(Hyperparameter Tuning): 通过调整网络结构(如层数、每层的神经元数量)和学习率等超参数,可以优化模型的性能。
生成数据集:
输入数据:
X
1
=
100
×
N
(
1
,
1
)
X_{1} = 100 \times \mathcal{N}(1, 1)
X1=100×N(1,1)
X
2
=
N
(
1
,
1
)
10
X_{2} = \frac{\mathcal{N}(1, 1) }{10}
X2=10N(1,1)
X
3
=
10000
×
N
(
1
,
1
)
X_{3} = 10000 \times \mathcal{N}(1, 1)
X3=10000×N(1,1)
输出数据
Y
Y
Y和
Y
1
Y_1
Y1:
Y
=
6
X
1
−
3
X
2
+
X
3
2
+
ϵ
Y = 6X_{1} - 3X_2 + X_3^2 + \epsilon
Y=6X1−3X2+X32+ϵ
Y
1
=
X
1
⋅
X
2
−
X
1
X
3
+
X
3
X
2
+
ϵ
1
Y_1 = X_1 \cdot X_2 - \frac{X_1}{X_3} + \frac{X_3}{X_2} + \epsilon_1
Y1=X1⋅X2−X3X1+X2X3+ϵ1
其中,
ϵ
1
\epsilon_1
ϵ1 是均值为0,方差为0.1的正态分布噪声。
请注意,这里的 N ( μ , σ 2 ) {N}(\mu, \sigma^2) N(μ,σ2) 表示均值为 μ \mu μ ,方差为 σ 2 \sigma^2 σ2的正态分布。
下面是生成数据集的代码:
# 生成测试数据
import numpy as np
import pandas as pd
# 训练集和验证集样本总个数
sample = 2000
train_data_path = 'train.csv'
validate_data_path = 'validate.csv'
predict_data_path = 'test.csv'
# 构造生成数据的模型
X1 = np.zeros((sample, 1))
X1[:, 0] = np.random.normal(1, 1, sample) * 100
X2 = np.zeros((sample, 1))
X2[:, 0] = np.random.normal(2, 1, sample) / 10
X3 = np.zeros((sample, 1))
X3[:, 0] = np.random.normal(3, 1, sample) * 10000
# 模型
Y = 6 * X1 - 3 * X2 + X3 * X3 + np.random.normal(0, 0.1, [sample, 1])
Y1 = X1 * X2 - X1 / X3 + X3 / X2 + np.random.normal(0, 0.1, [sample, 1])
# 将所有生成的数据放到data里面
data = np.zeros((sample, 5))
data[:, 0] = X1[:, 0]
data[:, 1] = X2[:, 0]
data[:, 2] = X3[:, 0]
data[:, 3] = Y[:, 0]
data[:, 4] = Y1[:, 0]
# 将data分成测试集和训练集
num_traindata = int(0.8*sample)
# 将训练数据保存
traindata = pd.DataFrame(data[0:num_traindata, :], columns=['x1', 'x2', 'x3', 'y', 'y1'])
traindata.to_csv(train_data_path, index=False)
print('训练数据保存在: ', train_data_path)
# 将验证数据保存
validate_data = pd.DataFrame(data[num_traindata:, :], columns=['x1', 'x2', 'x3', 'y', 'y1'])
validate_data.to_csv(validate_data_path, index=False)
print('验证数据保存在: ', validate_data_path)
# 将预测数据保存
predict_data = pd.DataFrame(data[num_traindata:, 0:-2], columns=['x1', 'x2', 'x3'])
predict_data.to_csv(predict_data_path, index=False)
print('预测数据保存在: ', predict_data_path)
通用神经网络拟合函数
要根据生成的数据集建立回归模型应该如何实现呢?对于这样包含非线性的方程,直接应用通用的神经网络模型可能效果并不好,就像这样:
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
class FNN(nn.Module):
def __init__(self,Arc,func,device):
super(FNN, self).__init__() # 调用父类的构造函数
self.func = func # 定义激活函数
self.Arc = Arc # 定义网络架构
self.device = device
self.model = self.create_model().to(self.device)
# print(self.model)
def create_model(self):
layers = []
for ii in range(len(self.Arc) - 2): # 遍历除最后一层外的所有层
layers.append(nn.Linear(self.Arc[ii], self.Arc[ii + 1], bias=True))
layers.append(self.func) # 添加激活函数
if ii < len(self.Arc) - 3: # 如果不是倒数第二层,添加 Dropout 层
layers.append(nn.Dropout(p=0.1))
layers.append(nn.Linear(self.Arc[-2], self.Arc[-1], bias=True)) # 添加最后一层
return nn.Sequential(*layers)
def forward(self,x):
out = self.model(x)
return out
if __name__ == "__main__":
# 定义网络架构和激活函数
Arc = [3, 10, 20, 20, 20, 10, 2]
func = nn.ReLU() # 选择ReLU激活函数
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 根据是否有GPU来选择设备
# 创建FNN模型实例
model = FNN(Arc, func, device)
# 定义损失函数和优化器
criterion = nn.MSELoss() # 均方误差损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001) # 使用Adam优化器
# 训练数据
train_data_path = 'train.csv'
train_data = pd.read_csv(train_data_path)
features = np.array(train_data.iloc[:, :-2])
labels = np.array(train_data.iloc[:, -2:])
#转换成张量
inputs_tensor = torch.from_numpy(features).float().to(device) # 转换为浮点张量
labels_tensor = torch.from_numpy(labels).float().to(device) # 如果标签是数值型数
loss_history = []
# 训练模型
for epoch in range(20000):
optimizer.zero_grad() # 清空之前的梯度
outputs = model(inputs_tensor) # 前向传播
loss = criterion(outputs, labels_tensor) # 计算损失
loss_history.append(loss.item()) # 将损失值保存在列表中
loss.backward() # 反向传播
optimizer.step() # 更新权重
if epoch % 1000 == 0:
print('epoch is', epoch, 'loss is', loss.item(), )
import matplotlib.pyplot as plt
loss_history = np.array(loss_history)
plt.plot(loss_history)
plt.xlabel = ('epoch')
plt.ylabel = ('loss')
plt.show()
torch.save(model, 'model\entire_model.pth')
应用这个代码得到的损失随迭代次数变化曲线如图:
这损失值也太大了!!!
那么应该如何修改神经网络模型使其损失函数降低呢?
————————————————