首页 > 其他分享 >2024.3.6学习笔记

2024.3.6学习笔记

时间:2024-03-06 23:00:24浏览次数:37  
标签:loss 2024.3 torch tensor val labels 笔记 学习 train

1. InfoNCE loss(源自知乎https://zhuanlan.zhihu.com/p/506544456 )

1.引入

把对比学习看成是一个字典查询的任务,即训练一个编码器从而去做字典查询的任务。假设已经有一个编码好的queryq以及一系列编码好的样本k0, k1, k2..., 把k0, k1, k2...可以看作是字典里的key。假设只有一个keyk+q匹配, 那么qk+为正样本对,其余的key为q的负样本。一旦定义好了正负样本对,就需要一个对比学习的损失函数来指导模型来进行学习。

2. 目的

query和唯一的正样本k+相似,并且和其他所有负样本key都不相似的时候,这个loss的值应该比较低。反之,如果query和k+不相似,或者和其他负样本的key相似了,那么loss就应该大,从而惩罚模型,促使模型进行参数更新。

3. 公式

\[L_q = -\log \frac{\exp(q \cdot k_l / \tau)}{\sum_{i=0}^k \exp(q \cdot k_i / \tau)} \]

这个k指的是负样本的数量, \(\tau\) 是一个温度超参数。
上式分母中的sum是在1个正样本和k个负样本上做的,从0到k,所以共k+1个样本,也就是字典里所有的key。
InfoNCE loss其实就是一个cross entropy loss,做的是一个k+1类的分类任务,目的就是想把q这个图片分到\(k_+\)这个类。

2. Instance discrimination(下面的概念均来自b站https://www.bilibili.com/video/BV1C3411s7t9/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=4afdb0bf8f80389d3492b886b5277ddc)

大致定义

B站中朱老师讲解的例子是做代理任务(即原先任务过于复杂或者抽象, 采用方便模型学习理解的简单的任务来促进模型进行后续任务的学习), 本例子中采用的是图像分类的例子。假如采用ImageNet的图像数据集, 取出其中一张照片分为两组进行旋转裁剪和插值等操作,然后把这两张图片定义为一个正样本对, 而对于其他的图片作为负样本, 利用编码器分别提取这些图片的特征, 对比学习就是让正样本之间的特征距离拉近, 而负样本对之间的距离拉远。而这篇原本的论文MoCohttps://arxiv.org/abs/1911.05722这种采用无监督学习的方式,在不同的应用场景下发现比监督学习方式的模型几乎接近, 真是让人惊叹!有机会刷完朱老师的视频, 感觉还是知之甚少

3. 对于多标签二分类问题的思考

今天在做kaggle上面machine learning比赛课程时, 想采用BP神经网络的方法解决钢轨有损检测的问题, 可以发现它的测试数据和需要提交的csv文件如下:


可以发现要进行测试的数据均为0, 1 二分类的数据, 因此想的采用BP神经网络实现较为方便。

1. chatGPT的思路

下面是Chat GPT给出的样例代码, 结合本案例做出的代码:

点击查看代码
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import train_test_split

train_X, val_X, train_labels, val_labels = train_test_split(X, y,random_state=1)

train_X_np = train_X.values
val_X_np = val_X.values
train_labels_np = train_labels.values
val_labels_np = val_labels.values

train_X_tensor = torch.from_numpy(train_X_np)
val_X_tensor = torch.from_numpy(val_X_np)
train_labels_tensor = torch.from_numpy(train_labels_np)
val_labels_tensor = torch.from_numpy(val_labels_np

train_X_tensor = torch.tensor(train_X_tensor, dtype=torch.float32) 
val_X_tensor = torch.tensor(val_X_tensor, dtype=torch.float32)
train_labels_tensor = torch.tensor(train_labels_tensor, dtype=torch.float32) 
val_labels_tensor = torch.tensor(val_labels_tensor, dtype=torch.float32)

n_features = train_X_tensor.shape[1]
n_labels = train_labels_tensor.shape[1]
batch_size = 32

train_dataset = TensorDataset(train_X_tensor, train_labels_tensor)
val_dataset = TensorDataset(val_X_tensor, val_labels_tensor)

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)

class MultiLabelClassifier(nn.Module):
    def __init__(self, n_features, n_labels):
        super(MultiLabelClassifier, self).__init__()
        self.layer1 = nn.Linear(n_features, 64)
        self.layer2 = nn.Linear(64, 128)
        self.layer3 = nn.Linear(128,512)
        self.layer4 = nn.Linear(512, 512)
        self.layer5 = nn.Linear(512, n_labels)
        self.dropout = nn.Dropout(p=0.5)
    
    def forward(self, x):
        x = torch.relu(self.layer1(x))
        x = self.dropout(x)
        x = torch.relu(self.layer2(x))
        x = self.dropout(x)
        x = torch.relu(self.layer3(x))
        x = self.dropout(x)
        x = torch.relu(self.layer4(x))
        x = self.dropout(x)
        x = torch.sigmoid(self.layer5(x))  # 使用Sigmoid函数,以便每个输出都是独立的标签概率
        return x

model = MultiLabelClassifier(n_features, n_labels)
loss_fn = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

def binary_accuracy(output, target, threshold=0.5):
    """计算多标签分类的准确率"""
    # 使用阈值将输出概率转换为二进制预测
    preds = (output > threshold).float()
    # 比较预测和真实标签
    correct = (preds == target).float()
    # 计算每个样本的准确率
    acc = correct.sum(1) / target.size(1)
    # 返回所有样本的平均准确率
    return acc.mean()

epochs = 20
best = 0


# 训练和评估, 并将效果最好的进行参数保存
for epoch in range(epochs):
    total_acc = 0
    total_loss = 0
    total_acc_val = 0
    total_loss_val =0
    for batch_inputs, batch_labels in train_loader:
        model.train()
        optimizer.zero_grad()
        outputs = model(batch_inputs)
        
        loss = loss_fn(outputs, batch_labels)
        acc = binary_accuracy(outputs, batch_labels)
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
        total_acc += acc.item()
        train_loss, train_acc = total_loss/len(train_loader), total_acc / len(train_loader)
    if train_acc >= best:
        best = train_acc
        torch.save(model.state_dict(), 'best.pth')
        print("save best model param")
    print(f'Epoch {epoch+1}/{epochs}, train_Loss: {train_loss:.4f}, train_Accuracy: {train_acc:.4f}')
    for batch_inputs, batch_labels in val_loader:
        model.eval()
        with torch.no_grad():
            outputs = model(batch_inputs)
        
            loss_val = loss_fn(outputs, batch_labels)
            acc_val = binary_accuracy(outputs, batch_labels)
                
            total_loss_val += loss_val.item()
            total_acc_val += acc_val.item()
                
            average_loss = total_loss_val/len(val_loader)
            average_acc = total_acc_val/len(val_loader)
    print(f'val_loss:{average_loss:.4f}, val_acc:{average_acc:.4f}')

best_net = MultiLabelClassifier(n_features, n_labels)
# print(best_net.state_dict())
best_param = torch.load('best.pth')
best_net.load_state_dict(best_param)
# print(best_net.state_dict())

test_np = test_data.values
test_tensor = torch.from_numpy(test_np).float()
preds = (best_net(test_tensor) > 0.5).int()
preds = preds.numpy()

submission_new = pd.DataFrame(preds, columns=['Pastry',
'Z_Scratch',
'K_Scatch',
'Stains',
'Dirtiness',
'Bumps',
'Other_Faults'])
submission_new.insert(0, 'id', submission_id)
submission_new.to_csv('pytorch test.csv', index=False)
但是经过测试发现, 训练和测试的评估指标保持不动, 而且最终预测的结果基本上都是0, 且基本上完全依靠设置的门限值来进行预测, 因此想在后面改进成多输出进行门限值的预测。

标签:loss,2024.3,torch,tensor,val,labels,笔记,学习,train
From: https://www.cnblogs.com/xiaoyaoxie/p/18057460

相关文章

  • ICLR 2024|图像匹配新突破!GIM:首个从互联网视频中学习通用图像匹配器的框架
    前言 为了解决基于深度学习方法泛化性的问题,来自厦门大学、Intel、大疆的研究者们提出了GIM:LearningGeneralizableImageMatcherfromInternetVideos。GIM是第一个可以让匹配模型从互联网视频中学习到强泛化能力的训练框架。本文转载自机器之心仅用于学术分享,若侵权请......
  • 模拟退火学习笔记
    模拟退火,优雅的暴力我认为有必要摘抄一下提单上的简介ZX写的前言:本片适用于模拟退火入门-进阶模拟退火(SA)是一种随机化算法。当一个问题的方案数量极大(甚至是无穷的)而且不是一个单峰函数时,我们常使用模拟退火求解。一般的,很多题都可以用模拟退火水过,在OI界称之[优雅的暴......
  • EGF 练习题(近期总结 2024.3.6)
    Luogu5401珍珠题意:有\(n\)个变量,取值范围均为\([1,D]\)中的整数。求有多少种取值方案,使得可以选出至少\(m\)对变量满足每对都相等。\(1\leD\le10^5,\space0\lem\len,\space1\len\le10^9\)注意到\(D\)很小,我们可以计算出个数为奇数的值最多\(n-2m\)个,偶数最......
  • 2024.3.06
    今日跟着一个人进行了Androidstudio上创建数据库和数据表的联系,这应该是老师留的作业中,进行数据库的连接。原文链接:https://blog.csdn.net/fjh_xx/article/details/131404230一.前言二.SQLite数据库介绍1.什么是SQLite数据库2.特点3.SQLite操作API4.SQLite数据类型三.S......
  • 学习笔记
    coreUSER:存放工程文件、主函数文件main.c,以及其他包括system_stm32f10x.c等CORE:用来存放核心文件和启动文件OBJ:是用来存放编译过程文件以及hex文件STM32F10x_FWLib:用来存放ST官方提供的库函数源码文件SYSTEM:此文件夹里面的代码由ALIENTEK提供,是STM32F10x系列的底......
  • 学习进度条
     2024-03-05   所花时间(包括上课)2h   代码量(行)300   博客量(篇)1   了解到的知识点课上学习及java编程练习内容   ......
  • Android开发学习之路01
    今日跟着一个人进行了Androidstudio上创建数据库和数据表的联系,这应该是老师留的作业中,进行数据库的连接。原文链接:https://blog.csdn.net/fjh_xx/article/details/131404230一.前言二.SQLite数据库介绍1.什么是SQLite数据库2.特点3.SQLite操作API4.SQLite数据类型三.S......
  • SOME/IP 笔记
    参考链接1:https://mp.weixin.qq.com/s?__biz=MzI0NTU1NDQ3Mw==&mid=2247483718&idx=1&sn=35ec9b655c6d20b9ea14972133a2ce28&chksm=e94d8d00de3a04162fd1acf8eb1dd3300266cc5be77fb66b018a882dd7274ba5a71f1347ab41&scene=21#wechat_redirect#SOME/IP协议......
  • Java学习总结 Day2
    Java学习总结Day2构造器publicclassperson{//一个类默认会有一个方法(构造器)Stringname;intage;//实例化初始值/*1.使用new必须有构造器,本质是调用构造器*2.初始化值*3.快捷键alt+insert*/publicperson(){}//有......
  • java复习笔记 - 1
           java是一门面向对象的语言,其解决问题的方式是通过封装属性和方法为对象,通过调用对象的不同方法来达到解决问题的步骤。其本身一开始封装了不少类,可以直接使用,常见的比如String,包装类,集合类,文件类,异常类等常用的,还有一些关于数字处理的后面再说。因为最近在看数据......