新手小白的pytorch学习第八弹------分类问题模子和简单猜测 ...

打印 上一主题 下一主题

主题 959|帖子 959|积分 2877

这篇是接着新手小白的pytorch学习第七弹------分类问题模子这一篇的,代码也是哟~
1 启动丧失函数和优化器

   对于我们的二分类问题,我们常常使用 binary cross entropy 作为丧失函数
可以使用torch.optim.SGD() 和 torch.optim.Adam() 作为优化器
    有两个 binary cross entropy 函数
  

  • torch.nn.BCELoss()-在label(target)和features(input)之间举行衡量
  • torch.nn.BCEWithLogitsLoss()-这个和上面这个一样,不过它有一个sigmoid嵌入层(nn.Sigmoid)[之后我们会看这个方式的]
  下面我们会创建丧失函数和优化器,优化器我们使用SGD,优化器使用模子的参数,学习率为0.1
  1. import torch.nn as nn
  2. import torch.optim as optim
  3. # 创建一个损失函数
  4. loss_fn = nn.BCEWithLogitsLoss() # 嵌入sigmoid()函数
  5. # 创建一个优化器
  6. optimizer = optim.SGD(params=model_0.parameters(),
  7.                       lr=0.1)
复制代码
我们再引入一个新的东西,评估尺度,它也可以像丧失函数一样,来衡量你的模子怎么样。毕竟使用多个角度来衡量模子,能够让模子更加的公正客观。Accuracy精确度,可以看出在总样本中精确样本的数量,所以100%是最好的,毕竟我们期望它全部猜测对,对吧。
  1. # 创建一个计算准确率的accuracy函数
  2. def accuracy_fn(y_true, y_pred):
  3.     correct = torch.eq(y_true, y_pred).sum().item() # torch.eq()计算两个相同的张量
  4.     acc = (correct/len(y_pred))*100
  5.     return acc
复制代码
现在我们可以使用这个函数来衡量我们的模子啦。
2 练习模子

这里使用的丧失函数是nn.BCEWithLogits(),因此这个丧失函数的输入是logits.
什么是logits呢,我的理解就是我们的模子输出的原始值,不颠末处理的值,由于这个丧失函数是有一个torch.sigmoid()函数的,所以数据的转换有三个步骤:logits -> prediction probability -> prediction labels
  1. # 查看测试数据的前5个输出
  2. with torch.inference_mode():
  3.     y_logits = model_0(X_test.to(device))[:5]
  4. y_logits
复制代码
  tensor([[0.6003],
[0.6430],
[0.5095],
[0.6260],
[0.5431]], device=‘cuda:0’)
  因为我们的模子没有被练习,因此这些输出都是随机的。
而且我们模子的原始输出是logits,这些数字难以解释,我们需要能够和真实数据相比力的数据。
我们可以使用torch.sigmoid()激活函数来将数据转换为我们需要的情势.
  1. # 使用 torch.sigmoid() 激活函数
  2. y_pred_probs = torch.sigmoid(y_logits)
  3. y_pred_probs
复制代码
  tensor([[0.6457],
[0.6554],
[0.6247],
[0.6516],
[0.6325]], device=‘cuda:0’)
  y_pred_probs 现在是 prediction probability 猜测概率的情势,概率就是有多大的大概,有多大的几率。在我们的环境中,我们理想的输出是0或1,所以这些值可以被看做一个决定的边界。好比说值越靠近零,那模子就将这个样本分类为0, 值越接近1,模子就将这个样本分类为1.
   更详细地说:
if y_pred_probs >= 0.5, y=1(class 1)
if y_pred_probs < 0.5, y=0(class 0)
  将猜测概率转酿成猜测标签,我们四舍五入torch.sigmoid()函数的输出即可
  1. # 将概率转变为标签
  2. y_preds = torch.round(y_pred_probs)
  3. # 将刚才的过程连起来放在一起
  4. y_preds_labels = torch.round(torch.sigmoid(model_0(X_test.to(device))[:5]))
  5. # 查看预测值和标签相等
  6. print(torch.eq(y_preds.squeeze(), y_preds_labels.squeeze()))
  7. # 去掉额外的维度
  8. y_preds.squeeze()
复制代码
  tensor([True, True, True, True, True], device=‘cuda:0’)
tensor([1., 1., 1., 1., 1.], device=‘cuda:0’)
  1. y_test[:5]
复制代码
  y_test[:5]

  创建练习和测试循环

  1. # 设置随机种子,有利于代码的复现
  2. torch.manual_seed(42)
  3. epochs = 100
  4. # 将数据放到指定的设备上
  5. X_train, y_train = X_train.to(device), y_train.to(device)
  6. X_test, y_test = X_test.to(device), y_test.to(device)
  7. # 创建训练和测试循环
  8. for epoch in range(epochs):
  9.     # 进入训练模式
  10.     model_0.train()
  11.    
  12.     # 预测
  13.     y_logits = model_0(X_train).squeeze()
  14.     y_pred_prob = torch.sigmoid(y_logits)
  15.     y_pred = torch.round(y_pred_prob)
  16.    
  17.     # 计算损失函数和准确率
  18.     loss = loss_fn(y_logits,
  19.                    y_train)
  20.     acc = accuracy_fn(y_true = y_train,
  21.                       y_pred = y_pred)
  22.    
  23.     optimizer.zero_grad()
  24.     loss.backward()
  25.     optimizer.step()
  26.    
  27.     # 测试
  28.     model_0.eval()
  29.     with torch.inference_mode():
  30.         test_logits = model_0(X_test).squeeze()
  31.         test_pred = torch.round(torch.sigmoid(test_logits))
  32.         test_loss = loss_fn(test_logits,
  33.                             y_test)
  34.         test_acc = accuracy_fn(y_true = y_test,
  35.                                y_pred = test_pred)
  36.    
  37.     # 打印出内容
  38.     if epoch % 10 == 0:
  39.         print(f"Epoch:{epoch} | Loss:{loss:.5f} | Accuracy:{acc:.2f}% | Test loss:{test_loss:.2f} | Test accuracy:{test_acc:.2f}%")
复制代码
  Epoch:0 | Loss:0.69313 | Accuracy:51.75% | Test loss:0.69 | Test accuracy:48.50%
Epoch:10 | Loss:0.69310 | Accuracy:51.75% | Test loss:0.69 | Test accuracy:48.00%
Epoch:20 | Loss:0.69308 | Accuracy:51.25% | Test loss:0.69 | Test accuracy:49.00%
Epoch:30 | Loss:0.69307 | Accuracy:50.75% | Test loss:0.69 | Test accuracy:48.00%
Epoch:40 | Loss:0.69306 | Accuracy:50.38% | Test loss:0.69 | Test accuracy:48.00%
Epoch:50 | Loss:0.69305 | Accuracy:51.12% | Test loss:0.69 | Test accuracy:47.50%
Epoch:60 | Loss:0.69304 | Accuracy:51.12% | Test loss:0.69 | Test accuracy:48.00%
Epoch:70 | Loss:0.69303 | Accuracy:50.75% | Test loss:0.69 | Test accuracy:47.50%
Epoch:80 | Loss:0.69303 | Accuracy:50.75% | Test loss:0.69 | Test accuracy:47.00%
Epoch:90 | Loss:0.69303 | Accuracy:50.38% | Test loss:0.69 | Test accuracy:46.50%
  通过上面的数据,丧失函数几乎没变化,精确度50%左右,感觉模子啥也没有学到,这就意味着它分类是随机的
3 猜测和评估模子

从上面的数据,感觉我们的模子好像是随机猜测,我们来可视化一下看看毕竟是怎么个事儿。
我们接着会写代码下载并导入helper_functions.py script来自Learn PyTorch for Deep Learning repo.
在这里有一个叫做 plot_decision_boundary() 的函数,它来可视化我们模子的分类的不同的点
我们也会导入我们在 01 中自己写的 plot_predictions()
  1. import requests
  2. from pathlib import Path
  3. # 从仓库下载文档
  4. if Path("helper_functions.py").is_file():
  5.     print("helper_functions.py already exists, skipping download")
  6. else:
  7.     print("Downloading helper_functions.py")
  8.     request = requests.get("https://raw.githubusercontent.com/mrdbourke/pytorch-deep-learning/main/helper_functions.py")
  9.     with open("helper_functions.py", "wb") as f:
  10.         f.write(request.content)
  11. from helper_functions import plot_predictions, plot_decision_boundary
复制代码
  Downloading helper_functions.py
  这里大概需要科学上网,我把文件helper_functions.py的代码放到文末了,可以自己创建一个.py文件粘进去。
  1. plt.figure(figsize=(12, 6))
  2. plt.subplot(1, 2, 1)
  3. plt.title("Train")
  4. plot_decision_boundary(model_0, X_train, y_train)
  5. plt.subplot(1, 2, 2)
  6. plt.title("Test")
  7. plot_decision_boundary(model_0, X_test, y_test)
复制代码

看中间这条白色的线,模子是通过这条直线来区分赤色和蓝色的点,所以是50%的精确率,明显是不对的,因为我们的数据明显是圈圈。
从机器学习的方面看,我们的模子欠拟合(underfitting),即没有从数据中学习到数据的模式.
那我们如何改善呢?请听下回分解
终于把今天的学习整理出来了,BB啊,今天中午吃了个超级物美价廉的套餐,里面的土豆炖牛腩和我平常吃的不一样,它这个带汤,尊嘟很好吃,熏过的香干一定要尝尝啊,皮蛋也很八错。还喝了一杯瑞幸的美式,一般般吧,室友说苦,我就喜欢喝这种苦苦的,嘻嘻嘻。
师姐通过一个电话说我喜欢一个男孩子,就说我喜欢他,哈哈哈哈,不知道咋听出来的,乌龙但是闹大了呢,话说,我们见面次数确实不多,但听到她的声音,莫名有点想她了,晚上就是多愁善感啊,别管我!
BB啊,今天就到这吧,不敢想象来日诰日的学习有多开心,终于到了要改善模子啦~
假如文章对您有帮助的话,记得给俺点个呐!
靴靴,谢谢~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表