精华内容
下载资源
问答
  • Windows下基于挂钩技术的数据标注,王丽艳,张志斌,清晰标注网络数据对研究和实际工程都有很重要意义,现阶段研究主要是采用人工模拟和DPI分析。人工模拟引入人为因素,受到实验
  • 免费试用地址:https://cloud.videojj.com/)文章来源:COCO数据标注详解​cloud.videojj.comCOCO数据集简单介绍COCO 全称是Common Objects in Context,是微软团队提供一个可以用来进行图像识别数...

    46e43ed68b9c74bf4f376321b2b47bd6.png

    来源 | 极链AI云(性价比最高的共享GPU算力平台,双十活动进行中 10.9-10.11,充值就送!最多可送2500元现金券!免费试用地址https://cloud.videojj.com/

    文章来源:

    COCO数据集标注详解cloud.videojj.com
    b713057ece61555ab6557b7440c0e287.png

    COCO数据集简单介绍

    COCO的 全称是Common Objects in Context,是微软团队提供的一个可以用来进行图像识别的数据集。这里以COCO2017数据集为例。MS COCO数据集中的图像分为训练、验证和测试集。一共80个类,分别是:

    [‘person’, ‘bicycle’, ‘car’, ‘motorcycle’, ‘airplane’, ‘bus’, ‘train’, ‘truck’, ‘boat’, ‘traffic light’, ‘fire hydrant’, ‘stop sign’, ‘parking meter’, ‘bench’, ‘bird’, ‘cat’, ‘dog’, ‘horse’, ‘sheep’, ‘cow’, ‘elephant’, ‘bear’, ‘zebra’, ‘giraffe’, ‘backpack’, ‘umbrella’, ‘handbag’, ‘tie’, ‘suitcase’, ‘frisbee’, ‘skis’, ‘snowboard’, ‘sports ball’, ‘kite’, ‘baseball bat’, ‘baseball glove’, ‘skateboard’, ‘surfboard’, ‘tennis racket’, ‘bottle’, ‘wine glass’, ‘cup’, ‘fork’, ‘knife’, ‘spoon’, ‘bowl’, ‘banana’, ‘apple’, ‘sandwich’, ‘orange’, ‘broccoli’, ‘carrot’, ‘hot dog’, ‘pizza’, ‘donut’, ‘cake’, ‘chair’, ‘couch’, ‘potted plant’, ‘bed’, ‘dining table’, ‘toilet’, ‘tv’, ‘laptop’, ‘mouse’, ‘remote’, ‘keyboard’, ‘cell phone’, ‘microwave’, ‘oven’, ‘toaster’, ‘sink’, ‘refrigerator’, ‘book’, ‘clock’, ‘vase’, ‘scissors’, ‘teddy bear’, ‘hair drier’, ‘toothbrush’]

    COCO数据集现在有3种标注类型:object instances(目标实例,用于目标检测), object keypoints(目标上的关键点,用于姿态估计), and image captions(看图说话),每种标注类型都有相应的json标注文件。如下图,这是COCO的训练集、验证集的标注文件:

    c0c5f5438d63670c253385e21621c742.png

    基本的json结构体类型

    object instances(目标实例)、object keypoints(目标上的关键点)、image captions(看图说话)这3种类型共享这些基本类型:info、image、license。而annotation类型则呈现出了多态:

    {
        "info": info,
        "licenses": [license],
        "images": [image],
        "annotations": [annotation],
    }
    
    上面的info又包括以下内容
    info{
        "year": int,
        "version": str,
        "description": str,
        "contributor": str,
        "url": str,
        "date_created": datetime,
    }
    
    licence又包括以下内容
    license{
        "id": int,
        "name": str,
        "url": str,
    } 
    
    image又包括以下内容
    image{
        "id": int,
        "width": int,
        "height": int,
        "file_name": str,
        "license": int,
        "flickr_url": str,
        "coco_url": str,
        "date_captured": datetime,
    }
    

    1、info类型,比如一个info类型的实例

    "info": {
             "description": "COCO 2017 Dataset",
             "url": "http://cocodataset.org",
             "version": "1.0",
             "year": 2017,
             "contributor": "COCO Consortium",
             "date_created": "2017/09/01"
             }
    

    2、Images是包含多个image实例的数组,对于一个image类型的实例:

    {
       "license": 4,
       "file_name": "000000397133.jpg",
       "coco_url": "http://images.cocodataset.org/val2017/000000397133.jpg",
       "height": 427,
       "width": 640,
       "date_captured": "2013-11-14 17:02:52",
       "flickr_url": "http://farm7.staticflickr.com/6116/6255196340_da26cf2c9e_z.jpg",
       "id": 397133
    }

    3、licenses是包含多个license实例的数组,对于一个license类型的实例:

    {
      "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/",
      "id": 1,
      "name": "Attribution-NonCommercial-ShareAlike License"
    }
    

    Object Instance 类型的标注格式

    相应的训练、验证标注文件为 instances_train2017.json、instances_val2017.json

    Object Instance这种格式的文件从头至尾按照顺序分为以下段落:

    {
        "info": info,
        "licenses": [license],
        "images": [image],
        "annotations": [annotation],
        "categories": [category]
    }

    其中,info、licenses、images这三个结构体/类型 在上一节中已经说了,在不同的JSON文件中这三个类型是一样的,定义是共享的。不共享的是annotation和category这两种结构体,他们在不同类型的JSON文件中是不一样的。

    images数组元素的数量等同于划入训练集(或者测试集)的图片的数量;

    annotations数组元素的数量等同于训练集(或者测试集)中bounding box的数量;

    categories数组元素的数量为80(2017年);

    from pycocotools.coco import COCO   # 这里需要事先安装pycocotools,安装方法见 https://blog.csdn.net/qq_29631521/article/details/89038361
    
    ann_train_file='dataset/coco/2017/annotations/instances_train2017.json'
    coco_train = COCO(ann_train_file)
    print(len(coco_train.dataset['categories'])) # 80
    print(len(coco_train.dataset['images'])) # 118287
    print(len(coco_train.dataset['annotations'])) # 860001

    2、annotations字段
    annotations字段是包含多个annotation实例的一个数组,annotation类型本身又包含了一系列的字段,如这个目标的category id和segmentation mask。segmentation格式取决于这个实例是一个单个的对象(即iscrowd=0,将使用polygons-多边形格式)还是一组对象(即iscrowd=1,将使用RLE格式-一种压缩方式)。如下所示:

    annotation{
        "id": int,    
        "image_id": int,                  #图片id
        "category_id": int,               # 类别id,对应COCO 81个类中的一个
        "segmentation": RLE or [polygon], # 目标的分割区域
        "area": float,                    # 标注区域面积
        "bbox": [x,y,width,height],       #图片中目标的边框 ;注意这里给的是左上角坐标及宽度、高度,有时需要转化为左上角、右下角坐标
        "iscrowd": 0 or 1,                # 一个目标(0)还是多个目标(1)
    }

    注意,单个的对象(iscrowd=0)可能需要多个polygon来表示,比如这个对象在图像中被挡住了。而iscrowd=1时(将标注一组对象,比如一群人)的segmentation使用的就是RLE格式。

    注意啊,只要是iscrowd=0那么segmentation就是polygon格式;只要iscrowd=1那么segmentation就是RLE格式。另外,每个对象(不管是iscrowd=0还是iscrowd=1)都会有一个矩形框bbox ,矩形框左上角的坐标和矩形框的长宽会以数组的形式提供,数组第一个元素就是左上角的横坐标值。

    area是area of encoded masks,是标注区域的面积。如果是矩形框,那就是高乘宽;如果是polygon或者RLE,那就复杂点。

    最后,annotation结构中的categories字段存储的是当前对象所属的category的id,以及所属的supercategory的name。

    iscrowd = 0,polygon格式比较简单,这些数按照相邻的顺序两两组成一个点的xy坐标,如果有n个数(必定是偶数),那么就是n/2个点坐标。下面就是一段解析polygon格式的segmentation并且显示多边形的示例代码:

    from PythonAPI.pycocotools.coco import COCO
    from skimage import io
    from matplotlib import pyplot as plt
    
    anno_file = 'dataset/coco/2017/annotations/instances_train2017.json'
    coco = COCO(anno_file)
    catIds = coco.getCatIds(catNms=['person'])
    imgIds = coco.getImgIds(catIds=catIds)
    
    for i in range(len(imgIds)):
        image = coco.loadImgs(imgIds[i])[0]
        I = io.imread(image['coco_url'])
        plt.imshow(I)
        anno_id = coco.getAnnIds(imgIds = image['id'], catIds = catIds, iscrowd= None)
        annotation = coco.loadAnns(anno_id)
        coco.showAnns(annotation)
        plt.show()

    效果图

    cbf51f833a89346452bbf06e70b4f69c.png

    如果iscrowd=1,那么segmentation就是RLE格式(segmentation字段会含有counts和size数组),在json文件中gemfield挑出一个这样的例子,如下所示:

    segmentation : 
    {
        u'counts': [272, 2, 4, 4, 4, 4, 2, 9, 1, 2, 16, 43, 143, 24......], 
        u'size': [240, 320]
    }

    COCO数据集的RLE都是uncompressed RLE格式(与之相对的是compact RLE)。 RLE所占字节的大小和边界上的像素数量是正相关的。RLE格式带来的好处就是当基于RLE去计算目标区域的面积以及两个目标之间的unoin和intersection时会非常有效率。 上面的segmentation中的counts数组和size数组共同组成了这幅图片中的分割 mask。其中size是这幅图片的宽高,然后在这幅图像中,每一个像素点要么在被分割(标注)的目标区域中,要么在背景中。很明显这是一个bool量:如果该像素在目标区域中为true那么在背景中就是False;如果该像素在目标区域中为1那么在背景中就是0。对于一个240x320的图片来说,一共有76800个像素点,根据每一个像素点在不在目标区域中,我们就有了76800个bit,比如像这样(随便写的例子,和上文的数组没关系):00000111100111110…;但是这样写很明显浪费空间,我们直接写上0或者1的个数不就行了嘛(Run-length encoding),于是就成了54251…,这就是上文中的counts数组。
    可以使用下面的代码将这个rle数组表示的分割区域画出来:

    import numpy as np
    from PythonAPI.pycocotools.coco import COCO
    from skimage import io
    from matplotlib import pyplot as plt
    
    anno_file = 'dataset/coco/2017/annotations/instances_val2017.json'
    coco = COCO(anno_file)
    catIds = coco.getCatIds(catNms=['person'])
    anno_id = coco.getAnnIds(catIds = catIds, iscrowd= 1)
    annotations = coco.loadAnns(anno_id)
    for j in range(len(annotations)):
        annotation = annotations[j]
        rle = annotation['segmentation']['counts']
        height = annotation['segmentation']['size'][0]
        width = annotation['segmentation']['size'][1]
        assert sum(rle) == height*width
        M = np.zeros(height*width)
        N = len(rle)
        n = 0
        val = 1
        for pos in range(N):
            val = not val
            for c in range(rle[pos]):
                M[n] = val
                n += 1
    
        GEMFIELD = M.reshape(([height, width]), order='F')
        plt.imshow(GEMFIELD)
        plt.show()

    显示结果:

    01d5452e814e6e6458f7b019945ab01f.png

    3,categories字段
    categories是一个包含多个category实例的数组,而category结构体描述如下:

    {
        "id": int,
        "name": str,                # 类别名(子类名)
        "supercategory": str,       # 父类名
    }

    从instances_val2017.json文件中摘出的2个category实例如下所示:

    {
    	"supercategory": "person",
    	"id": 1,
    	"name": "person"
    },
    {
    	"supercategory": "vehicle",
    	"id": 2,
    	"name": "bicycle"
    },

    Object Keypoint 类型的标注格式

    1,整体JSON文件格式

    相应的标注文件为person_keypoints_train2017.json、person_keypoints_val2017.json

    Object Keypoint这种格式的文件从头至尾按照顺序分为以下段落,看起来和Object Instance一样啊:

    {
        "info": info,
        "licenses": [license],
        "images": [image],
        "annotations": [annotation],
        "categories": [category]
    }

    其中,info、licenses、images这三个结构体/类型 在第一节中已经说了,在不同的JSON文件中这三个类型是一样的,定义是共享的。不共享的是annotation和category这两种结构体,他们在不同类型的JSON文件中是不一样的。

    images数组元素数量是划入训练集(测试集)的图片的数量;

    annotations是bounding box的数量,在这里只有人这个类别的bounding box;

    categories数组元素的数量为1,只有一个:person(2017年);

    2,annotations字段
    这个类型中的annotation结构体包含了Object Instance中annotation结构体的所有字段,再加上2个额外的字段。

    新增的keypoints是一个长度为3*k的数组,其中k是category中keypoints的总数量。每一个keypoint是一个长度为3的数组,第一和第二个元素分别是x和y坐标值,第三个元素是个标志位v,v为0时表示这个关键点没有标注(这种情况下x=y=v=0),v为1时表示这个关键点标注了但是不可见(被遮挡了),v为2时表示这个关键点标注了同时也可见。

    num_keypoints表示这个目标上被标注的关键点的数量(v>0),比较小的目标上可能就无法标注关键点。

    annotation{
        "keypoints": [x1,y1,v1,...],       # 关节点信息,按照(x,y,v)的顺序排列,即坐标为(x,y),可见性为v; v=0,没有标注;v=1,有标注不可见;v=2,有标注可见
        "num_keypoints": int,              # 标注的关节点数
        "id": int,
        "image_id": int,                   # 图片id
        "category_id": int,                # 类别id,等于1表示人这一类
        "segmentation": RLE or [polygon],  # 分割信息
        "area": float,                     # 标注区域面积
        "bbox": [x,y,width,height],        # 图片中人的边框
        "iscrowd": 0 or 1,                 # 是否是单人
    }

    从person_keypoints_val2017.json文件中摘出一个annotation的实例如下:

    {
    	"segmentation": [[125.12,539.69,140.94,522.43...]],
    	"num_keypoints": 10,
    	"area": 47803.27955,
    	"iscrowd": 0,
    	"keypoints": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,142,309,1,177,320,2,191,398...],
    	"image_id": 425226,"bbox": [73.35,206.02,300.58,372.5],"category_id": 1,
    	"id": 183126
    },

    3,categories字段
    对于每一个category结构体,相比Object Instance中的category新增了2个额外的字段,keypoints是一个长度为k的数组,包含了每个关键点的名字;skeleton定义了各个关键点之间的连接性(比如人的左手腕和左肘就是连接的,但是左手腕和右手腕就不是)。目前,COCO的keypoints只标注了person category (分类为人)。

    定义如下:

    {
        "id": int,
        "name": str,
        "supercategory": str,
        "keypoints": [str],
        "skeleton": [edge]
    }

    从person_keypoints_val2017.json文件中摘出一个category的实例如下:

    {
    	"supercategory": "person",
    	"id": 1,
    	"name": "person",
    	"keypoints": ["nose","left_eye","right_eye","left_ear","right_ear","left_shoulder","right_shoulder","left_elbow","right_elbow","left_wrist","right_wrist","left_hip","right_hip","left_knee","right_knee","left_ankle","right_ankle"],
    	"skeleton": [[16,14],[14,12],[17,15],[15,13],[12,13],[6,12],[7,13],[6,7],[6,8],[7,9],[8,10],[9,11],[2,3],[1,2],[1,3],[2,4],[3,5],[4,6],[5,7]]
    }

    Image Caption的标注格式1,整体JSON文件格式

    对应的文件是captions_train2017.json、captions_val2017.json
    Image Caption这种格式的文件从头至尾按照顺序分为以下段落,看起来和Object Instance一样,不过没有最后的categories字段:

    {
        "info": info,
        "licenses": [license],
        "images": [image],
        "annotations": [annotation]
    }

    其中,info、licenses、images这三个结构体/类型 在第一节中已经说了,在不同的JSON文件中这三个类型是一样的,定义是共享的。不共享的是annotations这种结构体,它在不同类型的JSON文件中是不一样的。

    images数组的元素数量等于划入训练集(或者测试集)的图片的数量;

    annotations的数量要多于图片的数量,这是因为一个图片可以有多个场景描述;

    2,annotations字段
    这个类型中的annotation用来存储描述图片的语句。每个语句描述了对应图片的内容,而每个图片至少有5个描述语句(有的图片更多)。annotation定义如下:

    annotation{
        "id": int,
        "image_id": int,
        "caption": str
    }

    从captions_val2017.json中摘取的一个annotation实例如下:

    {
    	"image_id": 179765,
    	"id": 38,"caption": "A black Honda motorcycle parked in front of a garage."
    }
    展开全文
  • 讨论了语义Web上用XML或RDF/XML标注元数据方法以及元数据标注在语义Web上两种存在形式:单一文件或XML包。在此基础上,介绍了从这些单独文件或XML包宿主文件中抽取元数据方法,包括XML解析器SAX和DOM以及XML包...
  • 数据标注

    2020-04-20 10:43:14
    数据标注如何自己建立数据数据标注 如何自己建立数据集 ...数据集是验证算法关键,而在论文中万一没有现成 数据标注 标注数据软件很多,labelme是很常用一个,可在python3上使用, ...

    labelme、labelimg数据集标注

    如何自己建立数据集

    入坑机器学习,首先要确定整体框架,而框架的构成就是对比算法、数据集和指标。数据集是验证算法的关键,而在论文中万一没有现成的

    数据集标注

    标注数据集的软件很多,labelme,labelimg可生成json和xml的标注文件,以下为安装方法:
    labelme安装,若pyqt5安装显示没有对应版本,可以在anaconda的可视化界面找此包。

    pip install pyqt5
    pip install labelme
    

    然后进入环境,输入labelme即可打开食用
    labelimg安装

    pip install PyQt5
    pip install pyqt5-tools
    pip install lxml
    pip install labelImg
    

    然后打开labelImg,注意是LABELIMG,而不是LABELLMG.

    展开全文
  • 改进后MCWD算法,让你标注多标签数据赢在起跑线上前言MCWD算法算法展示算法改进实现代码实验结果总结 前言 最近刷完了李航老师《统计学习与方法》,手痒到又想复现几个算法,正好碰上在云音乐云村视频...

    改进后的MCWD算法,让你的弱标注多标签数据赢在起跑线上


    前言

    最近刷完了李航老师的《统计学习与方法》,手痒到又想复现几个算法,正好碰上在云音乐的云村视频标签运维标注不完全问题,也算是弱标注数据吧,之前这比数据作了多标签分类,尽管特征上线后各项数据都有所提升,但总感觉用神经网络直接对弱标签数据进行多标签分类很不舒服。
    基于以下两个思考点:

    1. 存在标签缺失的问题,神经网络的意识在于我竟可能相信你给我的数据都是准确的,某个样本有某个标签是准确的,没有某个标签也是准确的。这会导致对于一些有缺失的标签,尽管网络见过相似的特征,但拟合的标签组却大不相同,无法有效学习到标签与特征的关系。
    2. 当标签缺失情况较少,而样本数据量足够多时,神经网络确实能比较好的应付脏数据带来的错误信息,但是对于那些本来就很少被标注,而且缺失情况较多的标签,最后模型在推理时,该类标签的产出也会非常稀有,预测不准确。尽管我们在最后加入了先验:即有效标注越少的标签越有可能被遗漏,对每个标签结果都乘以其IDF来纠正,但效果不是非常明显。这就导致最后输出的样本标签区分度较低,作为特征效果较差。
    3. 比较明显的问题:无法考虑标签之间的关联性,在MLOG方面,举例来说:风景标签与拍摄标签具有较强的关联性,女团标签与舞蹈、演唱等关联性较强,而神经网络无法利用这一信息。这个问题对于文本多标签分类任务已经有了一些解决方案,详情见论文:A Deep Reinforced Sequence-to-Set Model for Multi-Label Text Classification

    MCWD算法

    其实在寻找办法的过程中也看到了周志华团队的《Learning from Semi-Supervised Weak-Label Data》无奈其中数学公式复杂,尽管看懂了原理,但用python实现起来还是有一定的难度。

    最后将目标锁定在了《针对弱标记数据的多标签分类算法(王晶晶,杨有龙)》(原文请大家自行搜索)文章利用了样本间的加权KNN + 标签相关性的二阶策略 对弱标注数据的标签矩阵进行恢复,再通过多标签分类算法进行标注。

    算法展示

    原论文中算法具体步骤如下:

    算法改进

    1. 引入先验,适当增加随机的不相关标签数量: 在算法初始化第二步中,论文对于初始标签矩阵 C 中的每个标签 j ,在 C中随机选择 pj 个 Cij = 0 的实例,同时将选定实例的 Cij 值由原来的0变为−1,其中 pj 是每个标签 j 中所有相关标签的总数目。目的是为了,在训练数据的标签信息中添加一些不相关的标签信息,从而将缺失标签和不相关标签进行有效区分。但在复现过程中,发现对于稀疏的标签,往往由于初始的不相关标签信息不足,容易导致在迭代过程中过分补全。根据上述即有效标注越少的标签其本身先验概率也越低,我将该Pj值调整为—不包含该标签的样本数量 / n ( n为超参数,在实验过程中以 4 为佳)
    2. 在整体迭代结束后根据权重矩阵Wij来有选择的对Cij进行恢复,而是不论文中直接取sign(Cij),Wij * Cij 值高说明该标签越置信,而对于 Wij*Cij 值较低的,倾向于重置为0,让之后的标签相关矩阵去学习。较好的抑制算法过拟合。此处加入 阈值w(超参)
    3. 以及部分对原论文不合理之处的修改,详情见代码。

    实现代码

    import numpy as np
    import pandas as pd
    from sklearn.metrics import f1_score,hamming_loss
    
    def data_get_2(path,p):
        data = pd.read_csv(path)
        feature = np.array(data.iloc[:,:103])
        tag = np.array(data.iloc[:,103:])
        real_tag = tag.copy()
        for i in range(len(tag)):
            if len(np.where(tag[i,:] == 1)[0]) > p:
                index_list = np.random.choice(np.where(tag[i,:] == 1)[0],len(np.where(tag[i, :] == p)[0])-p,replace=False)
                tag[i,:][index_list] = 0
        '''
        随机drop掉每个样本的标签,至每个样本最多拥有p个标签。
        '''
        return feature,tag,real_tag
    
    def data_get_3(path,p):
        data = pd.read_csv(path)
        feature = np.array(data.iloc[:,1:1187])
        tag = np.array(data.iloc[:,1187:])
        real_tag = tag.copy()
        for i in range(len(tag)):
            if len(np.where(tag[i,:] == 1)[0]) > p:
                index_list = np.random.choice(np.where(tag[i,:] == 1)[0],len(np.where(tag[i, :] == p)[0])-p,replace=False)
                tag[i,:][index_list] = 0
        return feature,tag,real_tag
    
    class MCWD:
        def __init__(self,e=0.8,c=0.2,k_t=10,s=1,w_e=0.3,rate=0.5):
            self.e = e
            self.c = c
            self.k_t = k_t
            self.s = s
            self.w_e = w_e
            self.rate = rate
    
        def standetlize(self):
        '''
        涉及到距离计算,需要将特征标准化
        '''
            for i in range(self.feature_dim):
                mean = np.mean(self.feature[:,i])
                sii = 1/(self.sample_num-1) * np.sum((self.feature[:,i] - mean)**2)
                self.feature[:,i] = (self.feature[:,i]-mean)/sii
    	
        def add_nagtive_tag(self):
        '''
        训练数据的标签信息中添加一些不相关的标签信息
        '''
            for j in range(self.tag_c):
                zeros_way = np.where(self.old_tag_list[:,j] == 0)[0]
                pj = int(len(zeros_way) * self.rate)
                if len(zeros_way) < pj:
                    index_list = zeros_way
                else:
                    index_list = np.random.choice(np.where(self.old_tag_list[:,j] == 0)[0],pj,replace=False)
                self.tag_list[:,j][index_list] = -1
    
        def cauclate_dis(self,x1,x2):
            return np.sum(abs(x1-x2)**2)**(1/2)
    
        def get_dis_matrix(self):
            # self.dis_matrix = np.zeros((self.sample_num,self.sample_num))
            # for i in range(self.sample_num):
            #     print(i)
            #     for j in range(self.sample_num):
            #         if i < j:
            #             dis = self.cauclate_dis(self.feature[i],self.feature[j])
            #             self.dis_matrix[i][j] = dis
            #             self.dis_matrix[j][i] = dis
    		'''
        	快速计算样本之间的距离矩阵
        	'''
            G = np.dot(self.feature, self.feature.T)
            H = np.tile(np.diag(G), (self.sample_num, 1))  # n rows, 1 for each row
            D = H + H.T - G * 2
            self.dis_matrix = np.sqrt(D)
    
        def one_iter(self,t):
            n_near = t * self.k_t
            for index in range(self.sample_num):
                k_near_index = self.dis_matrix[index].argsort()[1:n_near+1]
                l_w = np.abs(self.tag_W[k_near_index])
                t_l = self.tag_list[k_near_index]
                self.tag_list[index] = np.sum(l_w * t_l,0)/(np.sum(l_w,0)+1e-8) #[-1,1]
    
            for index in range(self.sample_num):
                for j in range(self.tag_c):
    
                    qij = self.tag_list[index,j]
                    wij = self.tag_W[index,j]
    
                    if np.sign(qij) == np.sign(wij) and np.abs(qij) > self.e and np.abs(wij) > self.e:
                        self.tag_W[index,j] = np.sign(qij)
                    elif np.sign(qij) == -1 and np.sign(self.old_tag_list[index,j]) == 1:
                        self.tag_W[index, j] = self.c * (qij - np.min(self.tag_list[:,j]))/(np.max(self.tag_list[:,j]) - np.min(self.tag_list[:,j]))
                    else:
                        self.tag_W[index, j] = qij
    
                    if  qij > 0:
                        self.tag_list[index, j] = 1
                    elif qij < 0:
                        self.tag_list[index, j] = -1
                    else:
                        self.tag_list[index, j] = 0
    
            self.tag_list[np.where(self.old_tag_list == 1)] = 1
    
        def compute(self):
        '''
       	迭代结束后,根据W和C矩阵对标签矩阵进行恢复和补充
        '''
            for index in range(self.sample_num):
                for j in range(self.tag_c):
                    if self.tag_list[index, j] * self.tag_W[index, j] > self.w_e:
                        self.tag_list[index, j] = np.sign(self.tag_list[index, j])
                    else:
                        self.tag_list[index, j] = 0
            self.tag_list[np.where(self.old_tag_list == 1)] = 1
    
        def get_L_matricx(self):
        '''
       	计算标签相关矩阵
        '''
            self.L_matricx = np.zeros((self.tag_c,self.tag_c))
            for i in range(self.tag_c):
                for j in range(self.tag_c):
                    if i >= j:
                        a = np.sum((self.tag_list[:,i] == 1)*(self.tag_list[:,i] == 1)) + self.s
                        b = np.sum(self.tag_list[:,i] == 1) + 2 * self.s
                        c = np.sum(self.tag_list[:,j] == 1) + 2 * self.s
                        self.L_matricx[i][j] = a/b
                        self.L_matricx[j][i] = a/c
    
        def re_20_p(self):
        '''
       	根据标签相关矩阵补全剩余标签
        '''
            self.get_L_matricx()
            for i,j in zip(np.where(self.tag_list == 0)[0],np.where(self.tag_list == 0)[1]):
                qij = self.tag_list[i].T.dot(self.L_matricx[:,j])
                qij = (qij - np.min(self.tag_list[:, j])) / (np.max(self.tag_list[:, j]) - np.min(self.tag_list[:, j]))
                if qij > 0.5:
                    self.tag_list[i][j] = 1
                else:
                    self.tag_list[i][j] = -1
    
        def fit(self,feature,tag_list,max_iter=100,if_s=True):
            self.feature = np.array(feature,dtype=float)
            self.tag_list = np.array(tag_list,dtype=float)
            self.old_tag_list = np.array(tag_list)
            self.feature_dim = self.feature.shape[1]
            self.sample_num = self.feature.shape[0]
            self.tag_c = self.tag_list.shape[1]
            if if_s:
                print('standetlizing')
                self.standetlize()
                print('finish')
            print('add_nagtive_tag')
            self.add_nagtive_tag()
            print('finish')
            self.tag_W = self.tag_list.copy()
            print('get_dis_matrix')
            self.get_dis_matrix()
            print('finish')
            for iter in range(max_iter):
                print(iter)
                self.one_iter(iter+1)
                num = len(np.where((self.tag_list * self.tag_W) <= self.w_e)[0])
                print(num/(self.sample_num * self.tag_c))
                if num < self.sample_num * self.tag_c * 0.2:
                    self.compute()
                    break
            self.re_20_p()
    
    def main():
    
    # ------Yeast数据集--------------------------------------------------
    
        feature,tag,real_tag = data_get_2('./yeast.csv',1)
        mcwd = MCWD(e=0.8,c=0.2,k_t=10,s=1,w_e=0.5,rate=0.25)
        mcwd.fit(feature,tag)
        pred_tag = mcwd.tag_list
        pred_tag[np.where(pred_tag == -1)] = 0
        print(np.sum(real_tag) - np.sum(tag))
        print(np.sum(pred_tag[np.where(real_tag==1)]) - np.sum(tag[np.where(real_tag==1)]))
        print(np.sum(pred_tag[np.where(real_tag==0)]))
        print("f1_macro")
        print(f1_score(real_tag,tag, average='macro'))
        print(f1_score(real_tag,pred_tag,average='macro'))
        print("f1_micro")
        print(f1_score(real_tag,tag, average='micro'))
        print(f1_score(real_tag,pred_tag,average='micro'))
        print("hamming_loss")
        print(hamming_loss(real_tag,tag))
        print(hamming_loss(real_tag,pred_tag))
    
    #------genbase数据集--------------------------------------------------
    
        feature, tag, real_tag = data_get_3('./file27546ea66c1.csv', 1)
        mcwd = MCWD(e=0.8, c=0.2, k_t=5, s=1, w_e=0.5, rate=0.25)
        mcwd.fit(feature,tag,if_s=False)
        pred_tag = mcwd.tag_list
        pred_tag[np.where(pred_tag == -1)] = 0
    
        print(np.sum(real_tag) - np.sum(tag))
        print(np.sum(pred_tag[np.where(real_tag == 1)]) - np.sum(tag[np.where(real_tag == 1)]))
        print(np.sum(pred_tag[np.where(real_tag == 0)]))
        print("f1_macro")
        print(f1_score(real_tag,tag, average='macro'))
        print(f1_score(real_tag,pred_tag,average='macro'))
        print("f1_micro")
        print(f1_score(real_tag,tag, average='micro'))
        print(f1_score(real_tag,pred_tag,average='micro'))
        print("hamming_loss")
        print(hamming_loss(real_tag,tag))
        print(hamming_loss(real_tag,pred_tag))
    
    if __name__ == '__main__':
        main()
    
    

    实验结果


    总结

    根据实验结果可以发现,经过算法的补全,与补全前的标签矩阵比,F1值、hamming_loss等指标都有不同程度提升,证明了该算法的有效性。
    特别的:

    1. 在Genbase数据集上,算法补全了近2/3的标签,而仅产生了3个错误标签,表现惊人,且各项评估指标都有非常大的提升
    2. 对于标签缺失严重的数据,该算法能控制错误生成在可以接受的程度内,尽可能的补全标签。
    3. 但必须要考虑到错误生成带来的代价,有可能会影响之后的模型训练。但对于像短视频等内容,其标签多而杂,一个短视频所带的标签本没有一个真正准确的标准,因此,这种在内容相关性的逻辑下导致的错误生成,对于问题的解决其实并没有那么严重。
    4. 该算法改进,纯属本人摸索而出,能否应用于工作实践,还请各位斟酌尝试。
    展开全文
  • 最近看到一篇论文,是探讨关于NER数据标注中标签一致性问题数据标注在建立基准和确保使用正确信息来学习NER模型方面起着至关重要作用。要想获得准确标签,不仅需要时...

        最近看到一篇论文,是探讨关于NER数据标注中标签一致性问题的。

        数据标注在建立基准和确保使用正确的信息来学习NER模型方面起着至关重要的作用。要想获得准确的标签,不仅需要时间还需要专业知识。然而标签错误又几乎是无法避免的,错误的标签会导致标注数据子集(例如,训练集和测试集,或多个训练子集)之间的标签不一致。标签的不一致性是影响NER任务性能提升的因素之一,比如在被引用超过2300次的标准NER基准CoNLL03数据集中,发现测试集中有5.38%的标签错误,当对其中的错误标签进行纠正后,相比于原始测试集得到的结果更加准确和稳定。

        标签的一致性验证需要解决两个关键问题:1)如何识别标注的数据子集之间的标签不一致?2)如何验证纠正后的标签一致性得到恢复?

    1

    标签不一致性示例

        如下表所示,三个示例是用于比较SCIERC数据集的测试集中原始标注和校正后的标注。其中前两个是具有错误的实体类型,第三个是具有错误的实体边界。像前两个示例中的实体标记,如果在标注过程中始终遵循用于标注训练数据的“codebook”,那么一定能够将前两个示例中的实体标记为“Task”,而非“Method”。

    2

    标签不一致性识别

        如下图所示,是识别测试集与训练集的标签不一致性。以SCIERC数据集为例,从训练集中采样三个互斥子集(大小为x),选择这三个互斥子集中的一个子集作为新的测试集,然后构建三个新的训练集,分别为:

    • “TrainTest”:首先提供一个训练子集,然后再提供一个原始测试集

    • “PureTrain”:提供两个训练子集

    • “TestTrain”:首先输入原始测试集,然后输入一个训练子集

        然后训练NER模型以在新的测试集上执行,结果表明,“TestTrain”在早期阶段表现最差,因为原始测试集的质量不可靠。在“TrainTest”中,当开始向模型提供原始测试集时,性能不再提高。“PureTrain”表现最好。所有观察结果都得出结论,原始测试集比训练集本身对训练样本的预测性差。而在其他的两个数据集WikiGold和WNUT16上没有这样的观察结果,则这可能是由于标签不一致导致的问题。

    3

    标签一致性验证

        这是对纠正错误标签后的标签一致性进行验证,同样将训练数据中的子集作为新的测试集,以评估原始错误测试子集、更正后的测试子集以及其余训练子集的可预测性。以SCIERC数据集为例,假设在测试集中纠正了y+z个句子中的z个,原始的错误测试子集("Mistake")和校正后的测试子集(“Correct”)的大小均为z(z=147),在训练集中采样三个互斥子集,分别为x、y、w,使用训练集中第一个子集x作为新的测试集,然后建立四个新的训练集(每个新的训练集都有y+w+z=1355个句子)如下:

    • “TestTrainMistake”/“TestTrainCorrect”:原始的良好测试子集,第三个采样的训练子集和原始的错误测试子集(或校正后的测试子集)

    • “PureTrainMistake”/“PureTrainCorrect”:第二个和第三个采样的训练子集以及原始错误的测试子集(或校正后的测试子集)

    • “MistakeTestTrain”/“CorrectTestTrain”:原始错误的测试子集(或更正的测试子集),原始的良好测试子集和第三个采样的训练子集

    • “MistakePureTrain”/“CorrectPureTrain”:原始错误的测试子集(或更正的测试子集)以及第二个和第三个采样的训练子集。

        然后训练NER模型,结果表明,标签错误(即原始错误的测试子集)在开始或最后被输入时都会损害模型性能。校正后的测试子集可提供与原始良好测试子集和训练子集相当的性能。这证明了校正后的测试集与训练集的标签一致性。

    4

    标签一致性对NER模型性能的影响

    实验一:在SCIERC上的结果

        基于SCIERC数据集,部署五个NER模型,研究它们在校正后的SCIERC数据集上的性能。如下图所示,所有NER模型在校正后的SCIERC上都要比原始数据集提供更好的性能。

    实验二:在CoNLL03上的结果

        如下图a所示,在原始测试集中以错误的标签开头会使性能比从训练集或良好的测试子集开始的性能差。如下图b所示,在标签校正之后,此问题得到修复。


    参考资料:

    [1]https://arxiv.org/pdf/2101.08698v1.pdf

    - END -

    
    往期精彩回顾
    
    
    
    适合初学者入门人工智能的路线及资料下载机器学习及深度学习笔记等资料打印机器学习在线手册深度学习笔记专辑《统计学习方法》的代码复现专辑
    AI基础下载机器学习的数学基础专辑
    本站知识星球“黄博的机器学习圈子”(92416895)
    本站qq群704220115。
    加入微信群请扫码:
    
    
    展开全文
  • 众包数据标注隐类别分析

    千次阅读 2017-04-13 21:22:56
    0. 写在前面这时一篇关于田天、朱军一篇论文的读后感和自己一点思考。1. 众包众包(crowdsourcing)这个词,第一次听到还是众包数据库,是从老班长那里听到。细想起来,我对外包(outsourcing)这个词更加熟悉。...
  • 事件抽取是信息抽取领域一个重要研究方向,主要目的是从含有事件信息非结构化自然语言描述文本中抽取出事件信息并且以结构化形式表示出来。通常一个完整事件可以用5W1H表示出来。who(事件主动实施者),...
  • 最近想写一篇论文,需要点实验数据的支撑,无奈死活找不到字符级别的标注,老天不负有心人,终于找到了这篇文章百万级字符:清华大学提出中文自然文本数据集CTW,看看这张图片就知道这个数据标注的有多么牛逼了:...
  • Warp-CTC是一个可以应用在CPU和GPU上高效并行CTC代码库 (library) 介绍 CTCConnectionist Temporal Classification作为一个损失函数,用于在序列数据上进行监督式学习,不需要对齐输入数据及标签。比如,CTC可以...
  • 最近,随着深度学习发展,神经序列标注方案已经达到了很好性能,同时也依赖于大规模的标注数据。然而大部分规范标注数据来自于新闻领域,将在这些数据集上训练模型应用到其他领域时,模型性能往往会大幅...
  • 采用两级标注法,基于传统HMM理论,改进了HMM模型参数计算、数据平滑和未登入词处理方法,更好地体现了上下文依赖关系。同时,把基于自动分词词典词干提取算法与规则和统计相结合方法用于柯尔克孜语词性...
  • 编译 | 核子可乐、钰莹 最新论文指出,AI 行业正在残酷压榨刚刚兴起全球零工经济体系。 现代人工智能依赖各种算法处理规模达数百万示例、图像或文本素材。...数据标注是人工智能发展中至关重要
  • 反馈日志隐含图像语义信息有助于图像自动标注,但日志数据中存在噪声、片面性等问题制约了其作用,故提出基于日志协同图像自动标注算法。根据日志获取特点,采用增量关联规则挖掘处理日志信息去除其噪声,...
  • 缩小图像低层视觉特征与高层语义之间的鸿沟,以提高图像语义自动标注的精度,是研究大规模图像数据管理的关键。提出一种融合多特征的深度学习图像自动标注方法,将图像视觉特征以不同权重组合成词包,根据输入输出...
  • 提出的基于本体知识库的自动语义标注方法,旨在提高标注的质量。为识别出文档中的候选命名实体,设计了语义词典的逻辑结构,论述了以实体之间语义关联路径计算语义距离的方法;语义标注中的复杂问题是语义消歧,提出...
  • 论文信息: 硕士论文-网络新闻图像中人脸标注技术研究-...针对网络新闻数据图文互补特性,提出基于改进AP聚类人脸图像标注方法,以及标注一人多名问题处理方法。相对于k-means与AP聚类算法,改进AP聚类...
  • 01—背景介绍与研究动机面向方面细粒度观点抽取(Aspect-oriented Fine-grainedOpinion Extraction,AFOE)旨在自动地从评论文本中抽取出所有观点二元组,或者额外地抽取观点二元组表达情感极性构成观点三元组。...
  • 摘要:解决深度学习对数据依赖问题和减少数据标注成本成为了业界研究热点。本文将介绍以下几个研究方向:半监督/弱监督学习、数据合成、主动学习、自监督。 1. 引言 得益于深度学习发展,许多计算机视觉任务...
  • 针对微视频语义标注问题,提出一种基于半...该聚类算法实现了诸如微视频等多属性异构数据的聚类,提高了微视频标注效果。实验结果表明,所提微视频标注方法具有很强语义表达能力,该聚类方法也具有很强聚类准确度。
  • 最近想写一篇论文,需要点实验数据的支撑,无奈死活找不到字符级别的标注,老天不负有心人,终于找到了这篇文章百万级字符:清华大学提出中文自然文本数据集CTW,看看这张图片就知道这个数据标注的有多么牛逼了:...
  • 在人工标注语篇句子连贯性时,句群的划分成为最大的难点,句群内部句间关系的复杂性也增加了篇章标注的困难度。为了识别语篇标注的困难度,从多角度总结了句群边界以及类别的分布特点,分析了句群内部句间的各种连接...
  • 基于概率主题模型图像标注方法旨在通过学习图像语义进行图像标注,近年来倍受研究人员关注。考虑到类别对图像标注可提供有...在LabelMe和UIUC-Sport两个真实数据集上验证了提出模型的标注性能要高于其他相比较模型。
  • 莲花山数据集采用与或图作为视觉知识模型,实现对客观世界中视觉模式多层次表达,从而将多种标注任务统一到图像语法模型框架下。配套数据库通过两层模型分别管理视觉模型与标注数据,提供了灵活方便的数据导入、...
  • 在大规模人工标注的语料库的基础之上,研究了基于N元语言模型的维吾尔语词性自动标注的方法,分析了N元语言模型参数的选取以及数据平滑,比较了二元、三元文法模型对维吾尔语词性标注的效率;研究了标注集和训练语料...
  • 自动图像标注的异质关联模型及其与产生式模型的混合,徐枫,章毓晋,基于多模态数据的信息检索是一个具有挑战性的问题。在本文中,我们提出了一种关联图像和文本关键词的新方法。首先,两个独立的空
  • 在基于语义的视频检索系统中,为了弥补视频底层特征与高层用户需求之间的差异,提出了...标注过程中同时解决了已标注视频数据不足和多语义标注的问题。实验结果表明,该框架提高了标注的精确度,表现出了良好的性能。
  • 数据标注工具

    万次阅读 2018-03-23 16:12:47
    在我们学习深度学习的时候,经常阅读大牛的论文,并从网上下载对应的数据集和代码,在自己运行网络并调节网路结构或者超参数中理解网络的运作。  但是我们始终无法接触到数据本身是怎么制作的~  随着对深度学习...
  • 论文:Triggerner: Learning with entity triggers as explanations for named entity recognition原文链接:【ACL2020论文尝鲜】如何以低成本的数据构建高效NER模型?​mp.weixin.qq.com如何以低成本数据构建高效...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 925
精华内容 370
关键字:

数据标注的论文