鱼C论坛

 找回密码
 立即注册
查看: 398|回复: 4

解读自定义的神经网络模型

[复制链接]
发表于 2024-10-26 18:26:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. class Net(torch.nn.Module):
  2.     def __init__(self):
  3.         super(Net,self).__init__()
  4.         self.hidden_layer1 = nn.Linear(331,1024)
  5.         self.hidden_layer2 = nn.Linear(1024,1024)
  6.         self.hidden_layer3 = nn.Linear(1024,1024)
  7.         self.hidden_layer4 = nn.Linear(1024,1024)
  8.         self.output_layer = nn.Linear(1024,1)
  9.         self.dropout = nn.Dropout(p=0.2)
  10.         nn.init.xavier_uniform_(self.hidden_layer1.weight)
  11.         nn.init.xavier_uniform_(self.hidden_layer2.weight)
  12.         nn.init.xavier_uniform_(self.hidden_layer3.weight)
  13.         nn.init.xavier_uniform_(self.hidden_layer4.weight)
  14.         nn.init.xavier_uniform_(self.output_layer.weight)
  15.     def forward(self,x):
  16.         inputs = x
  17.         layer1_out = torch.nn.functional.gelu(self.hidden_layer1(inputs))
  18.         layer1_out = self.dropout(layer1_out)
  19.         layer2_out = torch.nn.functional.gelu(self.hidden_layer2(layer1_out))
  20.         layer2_out = self.dropout(layer2_out)
  21.         layer3_out = torch.nn.functional.gelu(self.hidden_layer3(layer2_out))
  22.         layer3_out = self.dropout(layer3_out)
  23.         layer4_out = torch.nn.functional.gelu(self.hidden_layer4(layer3_out))
  24.         layer4_out = self.dropout(layer4_out)
  25.         output = torch.relu(self.output_layer(layer4_out))
  26.         return output
复制代码


这个网络的gelu函数是什么?nn.init.xavier_uniform_是什么方法?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-10-26 18:33:08 | 显示全部楼层
这个自定义的神经网络模型有几个关键点:

1. **GELU函数**:GELU(Gaussian Error Linear Unit)是激活函数,常用于神经网络中。它结合了ReLU和Sigmoid的优点,通过保留输入的高斯分布特性,以提升模型性能,公式为:
   \[
   \text{GELU}(x) = x \cdot \Phi(x)
   \]
   其中,\(\Phi(x)\) 是标准正态分布的累积分布函数。

2. **Xavier初始化**:`nn.init.xavier_uniform_`是用来初始化网络权重的方法。通过维持每层输出的方差一致,能有效减轻梯度消失或爆炸问题。Xavier均匀初始化在输入和输出神经元数量的基础上,使用一个均匀分布来初始化权重。

这个模型使用了多层线性层和GELU激活函数,并加入了Dropout正则化,以减少过拟合。最终输出用ReLU激活函数处理。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-10-26 19:01:41 | 显示全部楼层
FishC 发表于 2024-10-26 18:33
这个自定义的神经网络模型有几个关键点:

1. **GELU函数**:GELU(Gaussian Error Linear Unit)是激活 ...

归一化之前损失特别高,我对特征进行了归一化,损失一下子降到零点几,是什么原因
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-26 19:14:02 | 显示全部楼层
Terence888 发表于 2024-10-26 19:01
归一化之前损失特别高,我对特征进行了归一化,损失一 ...


特征归一化能够帮助模型更快收敛,主要原因如下:

1. **数值稳定性**:归一化后的特征值通常更小且在相似的范围内,这可以增加数值计算的稳定性。

2. **梯度下降效率**:特征值范围一致,使得梯度下降算法能够更有效地调整权重,避免某些特征主导梯度更新。

3. **避免偏置问题**:未归一化的特征可能导致模型偏向处理某些特征,归一化能够防止这种情况。

因此,通过归一化,模型可以更好地训练和收敛,从而明显降低损失。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-10-26 21:13:00 | 显示全部楼层
Terence888 发表于 2024-10-26 19:01
归一化之前损失特别高,我对特征进行了归一化,损失一下子降到零点几,是什么原因

  1. #使用dnn模型(k折交叉验证)
  2. import torch
  3. import torch.nn as nn
  4. from torch.utils import data
  5. from torch.utils.data import Dataset,DataLoader
  6. from torch import optim

  7. #定义神经网络模型

  8. class SimpleNN(nn.Module):
  9.     def __init__(self):
  10.         super(SimpleNN, self).__init__()  # 继承需要用 SimpleNN
  11.         self.hidden_layer1 = nn.Linear(154,1024)
  12.         self.hidden_layer2 = nn.Linear(1024,1024)
  13.         self.hidden_layer3 = nn.Linear(1024,1024)
  14.         self.hidden_layer4 = nn.Linear(1024,1024)
  15.         self.output_layer = nn.Linear(1024,1)
  16.         self.dropout = nn.Dropout(0.2)
  17.         nn.init.xavier_uniform_(self.hidden_layer1.weight) #初始化每层网络的权重参数
  18.         nn.init.xavier_uniform_(self.hidden_layer2.weight)
  19.         nn.init.xavier_uniform_(self.hidden_layer3.weight)
  20.         nn.init.xavier_uniform_(self.hidden_layer4.weight)
  21.         nn.init.xavier_uniform_(self.output_layer.weight)
  22.       
  23.     def forward(self, X):
  24.         inputs = X
  25.         layer1_out = torch.nn.functional.gelu(self.hidden_layer1(inputs))
  26.         layer1_out = self.dropout(layer1_out)
  27.         layer2_out = torch.nn.functional.gelu(self.hidden_layer2(layer1_out))
  28.         layer2_out = self.dropout(layer2_out)
  29.         layer3_out = torch.nn.functional.gelu(self.hidden_layer3(layer2_out))
  30.         layer3_out = self.dropout(layer3_out)
  31.         layer4_out = torch.nn.functional.gelu(self.hidden_layer4(layer3_out))
  32.         layer4_out = self.dropout(layer4_out)
  33.         output = torch.relu(self.output_layer(layer4_out))
  34.         return output
  35.    
  36. #初始化模型和优化器
  37. dnn_model = SimpleNN()
  38. loss = nn.MSELoss() #定义损失函数
  39. optimizer = optim.Adam(dnn_model.parameters(),lr=0.0001,weight_decay=0) #定义优化器


  40. #k折交叉验证选取训练集与验证集
  41. def get_k_fold_data(k, i, X, y):
  42.     assert k > 1
  43.     fold_size = len(X) // k
  44.     X_train, y_train = None, None
  45.     for j in range(k):
  46.         start = j * fold_size
  47.         end = (j + 1) * fold_size
  48.         if j == i:
  49.             X_valid, y_valid = X.iloc[start:end], y.iloc[start:end]
  50.         elif X_train is None:
  51.             X_train, y_train = X.iloc[start:end], y.iloc[start:end]
  52.         else:
  53.             X_train = pd.concat([X_train, X.iloc[start:end]], ignore_index=True)
  54.             y_train = pd.concat([y_train, y.iloc[start:end]], ignore_index=True)
  55.     return X_train, y_train, X_valid, y_valid


  56. # 开始训练
  57. k = 5
  58. batch_size = 64
  59. num_epochs = 100
  60. #weight_decay = 0

  61. #初始化损失
  62. train_l_sum, valid_l_sum = 0, 0

  63. #初始化列表
  64. train_ls, valid_ls = [], []

  65. for i in range(k):
  66.     X_train, y_train, X_valid, y_valid = get_k_fold_data(k, i, X, y)
  67.     print(f'FOLD {i}')
  68.     print('--------------------------------')
  69.    

  70.     #将DataFrame数据转换为NumPy数组,然后再转换为PyTorch张量
  71.     X_train = torch.tensor(X_train.astype(np.float32).values, dtype=torch.float32)
  72.     y_train = torch.tensor(y_train.astype(np.float32).values, dtype=torch.float32)
  73.     X_valid = torch.tensor(X_valid.astype(np.float32).values, dtype=torch.float32)
  74.     y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32)
  75.    
  76.     #创建数据集
  77.     train_dataset = data.TensorDataset(X_train, y_train)
  78.     valid_dataset = data.TensorDataset(X_valid, y_valid)

  79.     # 获取一个数据迭代器
  80.     train_iter = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True,num_workers=2)#shuffle=True相当于sampler=RandomSampler(dataset)
  81.     valid_iter = DataLoader(dataset=valid_dataset,batch_size=batch_size,shuffle=True,num_workers=2)
  82.    
  83.     #开始迭代
  84.     for epoch in range(num_epochs):
  85.         train_loss = 0
  86.         for tensor_x, tensor_y in train_iter:#训练集执行梯度更新
  87.             tensor_x = tensor_x.float()
  88.             tensor_y = tensor_y.float().reshape(-1, 1)
  89.             optimizer.zero_grad() #梯度清零
  90.             pre_train = dnn_model(tensor_x)
  91.             train_l = loss(pre_train, tensor_y) #损失应避免与全局变量loss重名
  92.             train_l.backward()#前向传播
  93.             optimizer.step()#梯度下降

  94.             train_loss += train_l.item() * len(tensor_x) #批量规模损失累加
  95.             
  96.         train_loss /= len(train_dataset) #每次迭代平均损失
  97.         
  98.         if epoch % 20 == 0:
  99.             print('Loss: {}  Epoch:{}'.format(train_loss, epoch))
  100.         
  101.         with torch.no_grad():
  102.             valid_loss = 0
  103.             
  104.             for tensor_x, tensor_y in valid_iter:
  105.                 tensor_x = tensor_x.float()
  106.                 tensor_y = tensor_y.float().reshape(-1, 1)
  107.                 pre_valid = dnn_model(tensor_x)
  108.                 valid_l = loss(pre_valid, tensor_y)
  109.                 valid_loss += valid_l.item() * len(tensor_x)
  110.                   
  111.             valid_loss /= len(valid_dataset)
  112.                   
  113.             if epoch % 20 == 0:
  114.                 print('Valid Loss: {}  Epoch:{}'.format(valid_loss, epoch))
  115.         
  116.     if i == 0:
  117.         plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls],xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')
  118.     #将每折的损失添加到列表中
  119.     train_ls.append(train_loss)
  120.     valid_ls.append(valid_loss)

  121.         
  122. print('Training Ended')
  123. print('Train Average Loss: {} Valid Average Loss: {}'.format(np.mean(train_ls),np.mean(valid_ls)))
复制代码

自定义的神经网络如上,结果如下,代码存在什么问题?
  1. FOLD 0
  2. --------------------------------
  3. Loss: 36344742366.57045  Epoch:0
  4. Valid Loss: 29782921659.381443  Epoch:0
  5. Loss: 3065413660.5910654  Epoch:20
  6. Valid Loss: 2382111456.329897  Epoch:20
  7. Loss: 2432799436.09622  Epoch:40
  8. Valid Loss: 2090321211.8213058  Epoch:40
  9. Loss: 2391088845.85567  Epoch:60
  10. Valid Loss: 1990942727.9175258  Epoch:60
  11. Loss: 2284166063.065292  Epoch:80
  12. Valid Loss: 2163259427.1890035  Epoch:80
  13. FOLD 1
  14. --------------------------------
  15. Loss: 2206484537.182131  Epoch:0
  16. Valid Loss: 2204314296.742268  Epoch:0
  17. Loss: 1998103985.2646048  Epoch:20
  18. Valid Loss: 2287907708.9209623  Epoch:20
  19. Loss: 2017798130.1443298  Epoch:40
  20. Valid Loss: 2118876600.3024056  Epoch:40
  21. Loss: 1974789904.274914  Epoch:60
  22. Valid Loss: 2002172580.5085912  Epoch:60
  23. Loss: 1853698483.4639175  Epoch:80
  24. Valid Loss: 1899964549.718213  Epoch:80
  25. FOLD 2
  26. --------------------------------
  27. Loss: 1769865234.5841925  Epoch:0
  28. Valid Loss: 1894314067.573883  Epoch:0
  29. Loss: 1821377592.742268  Epoch:20
  30. Valid Loss: 2032567193.95189  Epoch:20
  31. Loss: 1743828709.6082475  Epoch:40
  32. Valid Loss: 2015808563.024055  Epoch:40
  33. Loss: 1722286362.8316152  Epoch:60
  34. Valid Loss: 1898440543.0103092  Epoch:60
  35. Loss: 1575469064.7972507  Epoch:80
  36. Valid Loss: 1905074117.9381444  Epoch:80
  37. FOLD 3
  38. --------------------------------
  39. Loss: 1642522463.8900344  Epoch:0
  40. Valid Loss: 1701700081.4845362  Epoch:0
  41. Loss: 1600776652.975945  Epoch:20
  42. Valid Loss: 1750697497.5120275  Epoch:20
  43. Loss: 1523211206.1580756  Epoch:40
  44. Valid Loss: 1828443650.8591065  Epoch:40
  45. Loss: 1462216860.5910654  Epoch:60
  46. Valid Loss: 1648079266.3092782  Epoch:60
  47. Loss: 1537743156.5635738  Epoch:80
  48. Valid Loss: 1658678443.1065292  Epoch:80
  49. FOLD 4
  50. --------------------------------
  51. Loss: 1444227294.790378  Epoch:0
  52. Valid Loss: 1351599504.274914  Epoch:0
  53. Loss: 1354902019.079038  Epoch:20
  54. Valid Loss: 1279266340.7285223  Epoch:20
  55. Loss: 1205427271.257732  Epoch:40
  56. Valid Loss: 1247919564.5360825  Epoch:40
  57. Loss: 1265103737.8419244  Epoch:60
  58. Valid Loss: 1256292511.0103092  Epoch:60
  59. Loss: 1193805096.467354  Epoch:80
  60. Valid Loss: 1190893154.969072  Epoch:80
  61. Training Ended
  62. Train Average Loss: 1595598623.2302403 Valid Average Loss: 1713117385.5450172
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-19 17:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表