鱼C论坛

 找回密码
 立即注册
查看: 366|回复: 5

如何添加绘制损失函数曲线

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

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

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

x
  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__()
  11.         self.hidden_layer1 = nn.Linear(154,1024)
  12.         self.hidden_layer2 = nn.Linear(1024,1024)
  13.         self.hidden_layer3 = nn.Linear(1024,256)
  14.         #self.hidden_layer4 = nn.Linear(1024,1024)
  15.         self.output_layer = nn.Linear(256,1)
  16.         self.dropout = nn.Dropout(p=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.     def forward(self,x):
  23.         inputs = x
  24.         layer1_out = torch.nn.functional.relu(self.hidden_layer1(inputs))
  25.         layer1_out = self.dropout(layer1_out)
  26.         layer2_out = torch.nn.functional.relu(self.hidden_layer2(layer1_out))
  27.         layer2_out = self.dropout(layer2_out)
  28.         layer3_out = torch.nn.functional.relu(self.hidden_layer3(layer2_out))
  29.         layer3_out = self.dropout(layer3_out)
  30.         #layer4_out = torch.nn.functional.gelu(self.hidden_layer4(layer3_out))
  31.         #layer4_out = self.dropout(layer4_out)
  32.         #output = torch.relu(self.output_layer(layer4_out))
  33.         output = torch.relu(self.output_layer(layer3_out))
  34.         return output

  35. # 设置超参数
  36. k = 5
  37. batch_size = 64
  38. num_epochs = 1000
  39. weight_decay = 0.001

  40. #初始化模型和优化器
  41. dnn_model = SimpleNN().to(device)  # 将模型移到GPU上
  42. optimizer = optim.AdamW(dnn_model.parameters(),lr=0.0001,weight_decay=weight_decay) #定义优化器


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




  59. #初始化列表
  60. train_ls, valid_ls = [], []

  61. for i in range(k):
  62.     X_train, y_train, X_valid, y_valid = get_k_fold_data(k, i, X, y)
  63.     print(f'FOLD {i}')
  64.     print('--------------------------------')
  65.    

  66.     # 将DataFrame数据转换为NumPy数组,然后再转换为PyTorch张量,并且移动到GPU上
  67.     X_train = torch.tensor(X_train.astype(np.float32).values, dtype=torch.float32).to(device)
  68.     y_train = torch.tensor(y_train.astype(np.float32).values, dtype=torch.float32).to(device)
  69.     X_valid = torch.tensor(X_valid.astype(np.float32).values, dtype=torch.float32).to(device)
  70.     y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32).to(device)
  71.    
  72.    
  73.     #创建数据集
  74.     train_ds = data.TensorDataset(X_train, y_train)
  75.     valid_ds = data.TensorDataset(X_valid, y_valid)

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

  91.             train_loss += train_l.item() * len(tensor_x)
  92.             
  93.         train_loss /= len(train_ds) #每次迭代平均损失
  94.         
  95.         if epoch % 50 == 0:
  96.             print('Loss: {}  Epoch:{}'.format(train_loss, epoch))
  97.             #print(train_l)
  98.         
  99.         
  100.         with torch.no_grad():
  101.             valid_loss = 0
  102.             
  103.             for tensor_x, tensor_y in valid_iter:
  104.                 tensor_x = tensor_x.float()
  105.                 tensor_y = tensor_y.float().reshape(-1, 1)
  106.                 pre_valid = dnn_model(tensor_x)
  107.                 valid_l = MSLE_loss(pre_valid, tensor_y)
  108.                 valid_loss += valid_l.item() * len(tensor_x)
  109.                   
  110.             valid_loss /= len(valid_ds)
  111.                   
  112.             if epoch % 50 == 0:
  113.                 print('Valid Loss: {}  Epoch:{}'.format(valid_loss, epoch))
  114.                 #print(valid_l)
  115.         
  116.       #将每折的损失添加到列表中
  117.     train_ls.append(train_loss)
  118.     valid_ls.append(valid_loss)

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


如何在上述代码中绘制损失函数曲线?训练损失和验证损失画在同一张图
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-10-29 10:16:17 | 显示全部楼层
要在训练过程中绘制损失函数曲线,你可以利用`matplotlib`库来绘制损失随训练迭代次数变化的图。我们可以在每个epoch结束时记录训练和验证损失,然后在所有epochs结束后再绘制这些数据。

以下是如何修改你的代码以绘制损失曲线的步骤:

1. 在代码最前面添加`matplotlib`库的导入:
   
  1. import matplotlib.pyplot as plt
复制代码


2. 在每个epoch结束时,记录下当前epoch的训练和验证损失:

   
  1. # 初始化列表来存储每个epoch的损失
  2.     epoch_train_losses = []
  3.     epoch_valid_losses = []

  4.     for epoch in range(num_epochs):
  5.         train_loss = 0
  6.         ...
  7.         train_loss /= len(train_ds)
  8.         epoch_train_losses.append(train_loss)  # 记录训练损失

  9.         with torch.no_grad():
  10.             valid_loss = 0
  11.             ...
  12.             valid_loss /= len(valid_ds)
  13.             epoch_valid_losses.append(valid_loss)  # 记录验证损失
复制代码


3. 在所有k折训练完成后,绘制损失曲线:

   
  1. # 训练结束后绘制损失曲线
  2.     plt.plot(range(num_epochs), epoch_train_losses, label='Train Loss')
  3.     plt.plot(range(num_epochs), epoch_valid_losses, label='Validation Loss')
  4.     plt.xlabel('Epoch')
  5.     plt.ylabel('Loss')
  6.     plt.title('Loss Curve')
  7.     plt.legend()
  8.     plt.show()
复制代码


注意:
- 确保`matplotlib`库已经安装,你可以通过运行`pip install matplotlib`来安装它。
- 上述代码在每个epoch记录损失,并在所有训练结束后绘图。根据需要,你可以调整记录频率,比如每隔几个epoch记录一次以减少数据量。
- 如果你希望在每折k折结束时绘制其损失曲线,可以在k折内部引入这样的绘图代码,然后为不同folds追加在一起绘图。

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

使用道具 举报

 楼主| 发表于 2024-10-29 10:47:00 | 显示全部楼层
FishC 发表于 2024-10-29 10:16
要在训练过程中绘制损失函数曲线,你可以利用`matplotlib`库来绘制损失随训练迭代次数变化的图。我们可以在 ...
  1. ---------------------------------------------------------------------------
  2. ValueError                                Traceback (most recent call last)
  3. Cell In[41], line 2
  4.       1 # 训练结束后绘制损失曲线
  5. ----> 2 plt.plot(range(num_epochs), epoch_train_losses, label='Train Loss')
  6.       3 plt.plot(range(num_epochs), epoch_valid_losses, label='Validation Loss')
  7.       4 plt.xlabel('Epoch')

  8. File /opt/conda/lib/python3.10/site-packages/matplotlib/pyplot.py:2812, in plot(scalex, scaley, data, *args, **kwargs)
  9.    2810 @_copy_docstring_and_deprecators(Axes.plot)
  10.    2811 def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
  11. -> 2812     return gca().plot(
  12.    2813         *args, scalex=scalex, scaley=scaley,
  13.    2814         **({"data": data} if data is not None else {}), **kwargs)

  14. File /opt/conda/lib/python3.10/site-packages/matplotlib/axes/_axes.py:1688, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
  15.    1445 """
  16.    1446 Plot y versus x as lines and/or markers.
  17.    1447
  18.    (...)
  19.    1685 (``'green'``) or hex strings (``'#008000'``).
  20.    1686 """
  21.    1687 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
  22. -> 1688 lines = [*self._get_lines(*args, data=data, **kwargs)]
  23.    1689 for line in lines:
  24.    1690     self.add_line(line)

  25. File /opt/conda/lib/python3.10/site-packages/matplotlib/axes/_base.py:311, in _process_plot_var_args.__call__(self, data, *args, **kwargs)
  26.     309     this += args[0],
  27.     310     args = args[1:]
  28. --> 311 yield from self._plot_args(
  29.     312     this, kwargs, ambiguous_fmt_datakey=ambiguous_fmt_datakey)

  30. File /opt/conda/lib/python3.10/site-packages/matplotlib/axes/_base.py:504, in _process_plot_var_args._plot_args(self, tup, kwargs, return_kwargs, ambiguous_fmt_datakey)
  31.     501     self.axes.yaxis.update_units(y)
  32.     503 if x.shape[0] != y.shape[0]:
  33. --> 504     raise ValueError(f"x and y must have same first dimension, but "
  34.     505                      f"have shapes {x.shape} and {y.shape}")
  35.     506 if x.ndim > 2 or y.ndim > 2:
  36.     507     raise ValueError(f"x and y can be no greater than 2D, but have "
  37.     508                      f"shapes {x.shape} and {y.shape}")

  38. ValueError: x and y must have same first dimension, but have shapes (350,) and (1750,)
复制代码


上述代码修改后报错
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-29 11:04:19 | 显示全部楼层
Terence888 发表于 2024-10-29 10:47
-------------------------------------------------- ...


报错的原因是`x`和`y`的长度不匹配,可能是由于在每个epoch都进行了多个k-fold的累积。

要解决这个问题,可以在每个k-fold的最后阶段计算平均损失。这是如何做的:

1. 在每个fold开始时,初始化一个临时的存储器:

   
  1. fold_train_losses = []
  2.     fold_valid_losses = []
复制代码


2. 在epoch循环内记录损失:

   
  1. fold_train_losses.append(train_loss)
  2.     fold_valid_losses.append(valid_loss)
复制代码


3. 在k-fold结束时,累加这些损失:

   
  1. if i == 0:
  2.         epoch_train_losses = fold_train_losses
  3.         epoch_valid_losses = fold_valid_losses
  4.     else:
  5.         epoch_train_losses = [x + y for x, y in zip(epoch_train_losses, fold_train_losses)]
  6.         epoch_valid_losses = [x + y for x, y in zip(epoch_valid_losses, fold_valid_losses)]
复制代码


4. 在k-fold循环结束后,计算平均损失:

   
  1. epoch_train_losses = [x / k for x in epoch_train_losses]
  2.     epoch_valid_losses = [x / k for x in epoch_valid_losses]
复制代码


5. 然后绘制图形:

   
  1. plt.plot(range(num_epochs), epoch_train_losses, label='Train Loss')
  2.     plt.plot(range(num_epochs), epoch_valid_losses, label='Validation Loss')
  3.     plt.xlabel('Epoch')
  4.     plt.ylabel('Loss')
  5.     plt.title('Loss Curve')
  6.     plt.legend()
  7.     plt.show()
复制代码


这样可以确保`x`和`y`的长度一致,并且每个epoch的损失值是所有fold平均后的值。

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

使用道具 举报

 楼主| 发表于 2024-10-29 11:34:26 | 显示全部楼层
FishC 发表于 2024-10-29 11:04
报错的原因是`x`和`y`的长度不匹配,可能是由于在每个epoch都进行了多个k-fold的累积。

要解决这个 ...
  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__()
  11.         self.hidden_layer1 = nn.Linear(154,1024)
  12.         self.hidden_layer2 = nn.Linear(1024,1024)
  13.         self.hidden_layer3 = nn.Linear(1024,256)
  14.         #self.hidden_layer4 = nn.Linear(1024,1024)
  15.         self.output_layer = nn.Linear(256,1)
  16.         self.dropout = nn.Dropout(p=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.     def forward(self,x):
  23.         inputs = x
  24.         layer1_out = torch.nn.functional.relu(self.hidden_layer1(inputs))
  25.         layer1_out = self.dropout(layer1_out)
  26.         layer2_out = torch.nn.functional.relu(self.hidden_layer2(layer1_out))
  27.         layer2_out = self.dropout(layer2_out)
  28.         layer3_out = torch.nn.functional.relu(self.hidden_layer3(layer2_out))
  29.         layer3_out = self.dropout(layer3_out)
  30.         #layer4_out = torch.nn.functional.gelu(self.hidden_layer4(layer3_out))
  31.         #layer4_out = self.dropout(layer4_out)
  32.         #output = torch.relu(self.output_layer(layer4_out))
  33.         output = torch.relu(self.output_layer(layer3_out))
  34.         return output

  35. # 设置超参数
  36. k = 5
  37. batch_size = 112
  38. num_epochs = 350
  39. weight_decay = 0.001

  40. #初始化模型和优化器
  41. dnn_model = SimpleNN().to(device)  # 将模型移到GPU上
  42. optimizer = optim.Adam(dnn_model.parameters(),lr=0.0001,weight_decay=weight_decay) #定义优化器


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




  59. #初始化列表
  60. train_ls, valid_ls = [], []

  61. for i in range(k):
  62.     X_train, y_train, X_valid, y_valid = get_k_fold_data(k, i, X, y)
  63.     print(f'FOLD {i}')
  64.     print('--------------------------------')
  65.    

  66.     # 将DataFrame数据转换为NumPy数组,然后再转换为PyTorch张量,并且移动到GPU上
  67.     X_train = torch.tensor(X_train.astype(np.float32).values, dtype=torch.float32).to(device)
  68.     y_train = torch.tensor(y_train.astype(np.float32).values, dtype=torch.float32).to(device)
  69.     X_valid = torch.tensor(X_valid.astype(np.float32).values, dtype=torch.float32).to(device)
  70.     y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32).to(device)
  71.    
  72.    
  73.     #创建数据集
  74.     train_ds = data.TensorDataset(X_train, y_train)
  75.     valid_ds = data.TensorDataset(X_valid, y_valid)

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

  91.             train_loss += train_l.item() * len(tensor_x)
  92.             
  93.         train_loss /= len(train_ds) #每次迭代平均损失
  94.         
  95.         
  96.         if epoch % 50 == 0:
  97.             print('Loss: {}  Epoch:{}'.format(train_loss, epoch))
  98.             
  99.         
  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 = MSLE_loss(pre_valid, tensor_y)
  109.                 valid_loss += valid_l.item() * len(tensor_x)
  110.                   
  111.             valid_loss /= len(valid_ds)
  112.             
  113.                   
  114.             if epoch % 50 == 0:
  115.                 print('Valid Loss: {}  Epoch:{}'.format(valid_loss, epoch))
  116.                
  117.     if i == 0:
  118.             d2l.plot(list(range(1, num_epochs + 1)), [train_loss, valid_loss],
  119.                      xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],
  120.                      legend=['train', 'valid'], yscale='log')   
  121.       #将每折的损失添加到列表中
  122.     train_ls.append(train_loss)
  123.     valid_ls.append(valid_loss)

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


绘制图像时报错
  1. ---------------------------------------------------------------------------
  2. ValueError                                Traceback (most recent call last)
  3. Cell In[44], line 133
  4.     130             print('Valid Loss: {}  Epoch:{}'.format(valid_loss, epoch))
  5.     132 if i == 0:
  6. --> 133         d2l.plot(list(range(1, num_epochs + 1)), [train_loss, valid_loss],
  7.     134                  xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],
  8.     135                  legend=['train', 'valid'], yscale='log')   
  9.     136   #将每折的损失添加到列表中
  10.     137 train_ls.append(train_loss)

  11. Cell In[43], line 101, in plot(X, Y, xlabel, ylabel, legend, xlim, ylim, xscale, yscale, fmts, figsize, axes)
  12.      99 for x, y, fmt in zip(X, Y, fmts):
  13.     100     if len(x):
  14. --> 101         axes.plot(x, y, fmt)
  15.     102     else:
  16.     103         axes.plot(y, fmt)

  17. File /opt/conda/lib/python3.10/site-packages/matplotlib/axes/_axes.py:1688, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
  18.    1445 """
  19.    1446 Plot y versus x as lines and/or markers.
  20.    1447
  21.    (...)
  22.    1685 (``'green'``) or hex strings (``'#008000'``).
  23.    1686 """
  24.    1687 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
  25. -> 1688 lines = [*self._get_lines(*args, data=data, **kwargs)]
  26.    1689 for line in lines:
  27.    1690     self.add_line(line)

  28. File /opt/conda/lib/python3.10/site-packages/matplotlib/axes/_base.py:311, in _process_plot_var_args.__call__(self, data, *args, **kwargs)
  29.     309     this += args[0],
  30.     310     args = args[1:]
  31. --> 311 yield from self._plot_args(
  32.     312     this, kwargs, ambiguous_fmt_datakey=ambiguous_fmt_datakey)

  33. File /opt/conda/lib/python3.10/site-packages/matplotlib/axes/_base.py:504, in _process_plot_var_args._plot_args(self, tup, kwargs, return_kwargs, ambiguous_fmt_datakey)
  34.     501     self.axes.yaxis.update_units(y)
  35.     503 if x.shape[0] != y.shape[0]:
  36. --> 504     raise ValueError(f"x and y must have same first dimension, but "
  37.     505                      f"have shapes {x.shape} and {y.shape}")
  38.     506 if x.ndim > 2 or y.ndim > 2:
  39.     507     raise ValueError(f"x and y can be no greater than 2D, but have "
  40.     508                      f"shapes {x.shape} and {y.shape}")

  41. ValueError: x and y must have same first dimension, but have shapes (350,) and (2,)
复制代码

如何修改
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-29 11:35:02 | 显示全部楼层
Terence888 发表于 2024-10-29 11:34
#使用dnn模型(k折交叉验证)
import torch
import ...


你遇到的错误是因为`x`和`y`列表在绘图时的维度不匹配。具体地说,是绘图函数`d2l.plot`中所传的`y`数据有问题。结合你的代码,我来帮你理清思路,并给出完整、正确的损失曲线绘制方法。

首先,我们需要在每次迭代过程中记录下训练和验证损失,并确保它们和`x`轴所表示的`epoch`数量是一致的。以下是一些清晰的步骤及代码示例:

1. 确保导入了`matplotlib`库:

  
  1. import matplotlib.pyplot as plt
复制代码


2. 初始化列表来存储每个epoch的损失:

  
  1. train_ls = []
  2.    valid_ls = []
复制代码


3. 在训练循环内部添加记录损失的逻辑:

  
  1. for epoch in range(num_epochs):
  2.        train_loss = 0
  3.        ...
  4.        train_loss /= len(train_ds)
  5.        fold_train_losses.append(train_loss)  # 记录训练损失

  6.        valid_loss = 0
  7.        ...
  8.        valid_loss /= len(valid_ds)
  9.        fold_valid_losses.append(valid_loss)  # 记录验证损失
复制代码


4. 在k-fold循环外进行绘图:

  
  1. # 初始化列表以记录平均损失
  2.    avg_train_losses = [0] * num_epochs
  3.    avg_valid_losses = [0] * num_epochs

  4.    # 对于每个Fold,计算损失
  5.    for epoch in range(num_epochs):
  6.        avg_train_losses[epoch] += fold_train_losses[epoch] / k
  7.        avg_valid_losses[epoch] += fold_valid_losses[epoch] / k

  8.    # 画图
  9.    plt.plot(range(1, num_epochs + 1), avg_train_losses, label='Train Loss')
  10.    plt.plot(range(1, num_epochs + 1), avg_valid_losses, label='Validation Loss')
  11.    plt.xlabel('Epoch')
  12.    plt.ylabel('Loss')
  13.    plt.title('Loss Curve')
  14.    plt.legend()
  15.    plt.show()
复制代码


这里,我们在每个Epoch的基础上累加来自不同Folds的损失,并计算其平均值。这会确保绘图时数据维度是一致的。`avg_train_losses`和`avg_valid_losses`都是长度为`num_epochs`的列表,这样可以保证`x`和`y`在绘图时的维度相同。

希望这能解决你在绘图过程中遇到的问题!如果在某个地方有不清楚或需要进一步解释的细节,请随时告知!

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-18 17:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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