精华内容
下载资源
问答
  • PyTorch源码

    2017-09-12 20:40:30
    近来由于网络的问题,从GitHub上下载的pytorch源码文件,可能缺少CMakeList.txt,导致源码安装不能成功。可在此处下载我于8月30日下载的可以成功编译的源码。
  • 编译pytorch源码

    2020-07-03 18:42:19
    编译pytorch源码 clone pytorch源码: (base) xueruini@nico2:~/onion_rain/pytorch/code$ git clone --recursive https://github.com/pytorch/pytorch Cloning into 'pytorch'... remote: Enumerating objects: 37,...

    编译pytorch源码

    clone pytorch源码:

    (base) xueruini@nico2:~/onion_rain/pytorch/code$ git clone --recursive https://github.com/pytorch/pytorch
    Cloning into 'pytorch'...
    remote: Enumerating objects: 37, done.
    remote: Counting objects: 100% (37/37), done.
    ...
    Resolving deltas: 100% (151/151), done.
    Submodule path 'third_party/tensorpipe/third_party/pybind11/tools/clang': checked out '6a00cbc4a9b8e68b71caf7f774b3f9c753ae84d5'
    Submodule path 'third_party/zstd': checked out 'aec56a52fbab207fc639a1937d1e708a282edca8'
    
    (base) xueruini@nico2:~/onion_rain/pytorch/code$ cd pytorch
    (base) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ ls
    android  aten.bzl    binaries     c10     CITATION  CMakeLists.txt      CODEOWNERS       docker      docker.Makefile  ios      Makefile  mypy.ini  README.md         scripts   submodules  third_party  torch       version.txt
    aten     benchmarks  BUILD.bazel  caffe2  cmake     CODE_OF_CONDUCT.md  CONTRIBUTING.md  Dockerfile  docs             LICENSE  modules   NOTICE    requirements.txt  setup.py  test        tools        ubsan.supp  WORKSPACE
    

    切换到release版本

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ git checkout v1.5.1
    Checking out files: 100% (3139/3139), done.
    Note: checking out 'v1.5.1'.
    
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.
    
    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -b with the checkout command again. Example:
    
      git checkout -b <new-branch-name>
    
    HEAD is now at 3c31d73c87 [ONNX] Fix pow op export [1.5.1] (#39791)
    

    更新一些第三方库

    (base) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ git submodule sync
    (base) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ git submodule update --init --recursive
    

    新建虚拟环境

    (base) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ conda create -n pytorch
    Collecting package metadata (current_repodata.json): done
    Solving environment: done
    
    ## Package Plan ##
    
      environment location: /home/xueruini/anaconda3/envs/pytorch
    
    
    
    Proceed ([y]/n)? y
    
    Preparing transaction: done
    Verifying transaction: done
    Executing transaction: done
    #
    # To activate this environment, use
    #
    #     $ conda activate pytorch
    #
    # To deactivate an active environment, use
    #
    #     $ conda deactivate
    
    (base) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ conda activate pytorch
    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$
    

    安装依赖

    通用依赖

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ conda install numpy ninja pyyaml mkl mkl-include setuptools cmake cffi
    Collecting package metadata (current_repodata.json): done
    Solving environment: done
    ...
    Preparing transaction: done
    Verifying transaction: done
    Executing transaction: done
    

    查一下cuda版本

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ nvcc -V
    nvcc: NVIDIA (R) Cuda compiler driver
    Copyright (c) 2005-2019 NVIDIA Corporation
    Built on Wed_Oct_23_19:24:38_PDT_2019
    Cuda compilation tools, release 10.2, V10.2.89
    

    安装cuda依赖

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ conda install -c pytorch magma-cuda102
    Collecting package metadata (current_repodata.json): done
    Solving environment: done
    ...
    Verifying transaction: done
    Executing transaction: done
    

    安装cudatoolkit

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ conda install cudatoolkit
    Collecting package metadata (current_repodata.json): done
    Solving environment: done
    ...
    Verifying transaction: done
    Executing transaction: done
    

    不装cudatoolkit,编译完import torch时会有如下报错:

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ python
    Python 3.8.3 (default, Jul  2 2020, 16:21:59)
    [GCC 7.3.0] :: Anaconda, Inc. on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import torch
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/xueruini/onion_rain/pytorch/code/pytorch/torch/__init__.py", line 1
    35, in <module>
        _load_global_deps()
      File "/home/xueruini/onion_rain/pytorch/code/pytorch/torch/__init__.py", line 9
    3, in _load_global_deps
        ctypes.CDLL(lib_path, mode=ctypes.RTLD_GLOBAL)
      File "/home/xueruini/anaconda3/envs/pytorch/lib/python3.8/ctypes/__init__.py",
     line 373, in __init__
        self._handle = _dlopen(self._name, mode)
    OSError: libcublasLt.so.10: cannot open shared object file: No such file or dire
    

    编译

    这里由于我是要对pytorch源码debug,所以DEBUG参数置为1

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ export CMAKE_PREFIX_PATH=${CONDA_PREFIX:-"$(dirname $(which conda))/../"}
    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ DEBUG=1 python setup.py install
    Building wheel torch-1.5.0a0+3c31d73
    -- Building version 1.5.0a0+3c31d73
    cmake -GNinja -DBUILD_PYTHON=True -DBUILD_TEST=True -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/home/xueruini/onion_rain/pytorch/code/pytorch/torch -DCMAKE_PREFIX_PATH=/home/xueruini/anaconda3/envs/pytorch -DNUMPY_INCLUDE_DIR=/home/xueruini/anaconda3/envs/pytorch/lib/python3.8/site-packages/numpy/core/include -DPYTHON_EXECUTABLE=/home/xueruini/anaconda3/envs/pytorch/bin/python -DPYTHON_INCLUDE_DIR=/home/xueruini/anaconda3/envs/pytorch/include/python3.8 -DPYTHON_LIBRARY=/home/xueruini/anaconda3/envs/pytorch/lib/libpython3.8.so.1.0 -DTORCH_BUILD_VERSION=1.5.0a0+3c31d73 -DUSE_NUMPY=True /home/xueruini/onion_rain/pytorch/code/pytorch
    ...
    Copying torch.egg-info to /home/xueruini/anaconda3/envs/pytorch/lib/python3.8/site-packages/torch-1.5.0a0+3c31d73-py3.8.egg-info
    running install_scripts
    Installing convert-caffe2-to-onnx script to /home/xueruini/anaconda3/envs/pytorch/bin
    Installing convert-onnx-to-caffe2 script to /home/xueruini/anaconda3/envs/pytorch/bin
    

    验证

    首先要退出pytorch目录

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ cd ..
    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code$ python
    Python 3.8.3 (default, Jul  2 2020, 16:21:59)
    [GCC 7.3.0] :: Anaconda, Inc. on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import torch
    >>> torch.__version__
    '1.5.0a0+3c31d73'
    >>>
    

    不退出会出现如下报错:

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ python
    Python 3.8.3 (default, Jul  2 2020, 16:21:59)
    [GCC 7.3.0] :: Anaconda, Inc. on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import torch
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/xueruini/onion_rain/pytorch/code/pytorch/torch/__init__.py", line 1
    36, in <module>
        from torch._C import *
    ModuleNotFoundError: No module named 'torch._C'
    >>>
    

    卸载

    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ pip uninstall torch
    Found existing installation: torch 1.7.0a0+6095808
    Uninstalling torch-1.7.0a0+6095808:
      Would remove:
        /home/xueruini/anaconda3/envs/pytorch/bin/convert-caffe2-to-onnx
        /home/xueruini/anaconda3/envs/pytorch/bin/convert-onnx-to-caffe2
        /home/xueruini/anaconda3/envs/pytorch/lib/python3.8/site-packages/caffe2
        /home/xueruini/anaconda3/envs/pytorch/lib/python3.8/site-packages/torch
        /home/xueruini/anaconda3/envs/pytorch/lib/python3.8/site-packages/torch-1.7.0a0+6095808-py3.8.egg-info
    Proceed (y/n)? Y
      Successfully uninstalled torch-1.7.0a0+6095808
    
    (pytorch) xueruini@nico2:~/onion_rain/pytorch/code/pytorch$ python setup.py clean
    Building wheel torch-1.7.0a0+6095808
    running clean
    

    其他

    用vscode f5进行debug时,import torch报错,但是终端命令行跑没问题:
    在这里插入图片描述
    解决办法:

    conda install openmpi
    

    好奇怪,如果是缺库那终端也不应该能运行才对呀

    展开全文
  • BN层pytorch源码,天气数据四分类问题BN层pytorch源码,天气数据四分类问题
  • 预训练网络RESNET pytorch源码,天气数据四分类问题预训练网络RESNET pytorch源码,天气数据四分类问题
  • 学习速率衰减.pytorch源码,天气数据四分类问题学习速率衰减.pytorch源码,天气数据四分类问题
  • 数据增强pytorch源码,天气数据四分类问题
  • 今天小编就为大家分享一篇关于PyTorch源码解读之torchvision.models,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 论文《Dilated Residual Networks》的pytorch源码,python3环境。
  • 人脸光照质量评价系统(附PyTorch源码)-附件资源
  • EAST结构分析+pytorch源码实现

    千次阅读 热门讨论 2019-06-23 17:51:37
    EAST结构分析+pytorch源码实现 文章目录EAST结构分析+pytorch源码实现@[toc]一. U-Net的前车之鉴1.1 FCN网络1.2 U-NET网络1.3 CTPN网络二. EAST结构分析三. EAST细节分析四. Pytorch源码分析五. 参考文献 一. U-Net...

    EAST结构分析+pytorch源码实现

    友情提示

    友情提示不针对第三方,为了给读者更好的体验

    一. U-Net的前车之鉴

    在介绍EAST网络之前我们先介绍一下前面的几个网络,看看这个EAST网络怎么来的?为什么来的?

    当然这里的介绍仅仅是引出EAST而不是详细的讲解其他网络,有需要的读者可以去看看这三个优秀网络。

    1.1 FCN网络结构

    ​ FCN网络,在之前FCN从原理到代码的理解已经详细分析了,有需要的可以去看看,顺便跑一跑代码。

    图1-1

    • 网络的由来

    不管是识别(传统机器学习、CNN)还是检测(SSD、YOLO等),都只是基于大块的特征进行的,检测之后都是以长方形去表示检测结果,由于这是其算法内部回归的结果导致,而且feature map经过卷积一直减小,如果强行进行256X256512X512的插值,那么结果可以想象,边界非常不好。

    那么如何实现图1-1所示的结果呢?把每个像素都进行分割?

    • 网络的成果

    FCN给出的方法是使用反卷积进行上采样操作,使得经过CNN之后减小的图能够恢复大小。

    当然作者还提出一个好方法,不同的feature map进行组合,使得感受野进行扩充。

    注释:笔者认为使用反卷积有两个作用,其一是使得计算LOSS比较方便,标签和结果可以直接进行计算。其二是可以进行参数的学习,更为智能化。

    1.2 U-NET网络

    U-net网络之前没怎么看过,现在也仅仅是大概看了论文和相关资料,内部实现不是很了解。

    图1-2

    • 网络的由来

    FCN完全可以做到基于像素点的分割,为什么还要这个U-net网络啊?

    FCN网络检测的效果还可以,但是其边缘的处理就特别的差。虽然说多个层进行合并,但是合并的内容杂乱无章,导致最后的信息没有完全得到。

    总的来说FCN分割的效果不够,精度也不够。

    • 网络的成果

    U-net提出了对称的网络结构,使得网络参数的学习效果更好(为什么对称网络学习更好,这个理解不透,如果是结果再放大一倍使得不对称不也一样吗?感觉还是网络结构设计的好,而不是对称)

    不同feature map合并的方式更加优化,使得在边缘分割(细节)上更加优秀。

    网络架构清晰明了,分割效果也很好,现在医学图像分割领域还能看见身影。

    1.3 CTPN网络

    刚开始准备使用CTPN进行文本的检测,所以看了一些相关资料,致命缺点是不能检测带角度文字和网络比较复杂。

    图1-3

    • 网络的由来

    文本检测和其他检测却别很大,比如用SSD检测文本就比较困难(边缘检测不好),如何针对文本进行检测?

    • 网络的成果

    CTPN网络有很多创造的想法–>>

    目标分割小块,然后一一进行检测,针对文本分割成height>width的方式,使得检测的边缘更为精确。

    使用BiLSTM对小块进行连接,针对文本之间的相关性。

    CTPN想法具有创造性,但是太过复杂。

    1. 首先样本的制作麻烦
    2. 每个小框进行回归,框的大小自己定义
    3. 边缘特意进行偏移处理
    4. 使用RNN进行连接

    检测水平效果还是不错的,但是对于倾斜的文本就不行了。

    为什么不加一个angle进行回归?

    本就很复杂的网络,如果再给每个小box加一个angle参数会更复杂,当然是可以实施的。

    二. EAST结构分析

    2.1 结构简述

    EAST原名为: An Efficient and Accurate Scene Text Detector

    结构:检测层(PVANet) + 合并层 + 输出层

    图2-1

    下图图2-2是检测效果,任意角度的文本都可以检测到。

    **注意:**EAST只是一个检测网络,如需识别害的使用CRNN等识别网络进行后续操作。

    图2-2

    具体网络在2-2节进行详细介绍=====>>>

    2.2 结构详解

    • 整体结构

    EAST根据他的名字,我们知道就是高效的文本检测方法。

    上面我们介绍了CTPN网络,其标签制作很麻烦,结构很复杂(分割成小方框然后回归还要RNN进行合并)

    看下图图2-3,只要进行类似FCN的结构,计算LOSS就可以进行训练。测试的时候走过网络,运行NMS就可以得出结果。太简单了是不是?

    图2-3

    • 特征提取层

    特征的提取可以任意网络(VGG、RES-NET等检测网络),本文以VGG为基础进行特征提取。这个比较简单,看一下源码就可以清楚,见第四章源码分析

    • 特征合并层

    在合并层中,首先在定义特征提取层的时候把需要的输出给保留下来,通过forward函数把结构进行输出。之后再合并层调用即可

    如下代码定义,其中合并的过程再下面介绍

    #提取VGG模型训练参数
    class extractor(nn.Module):
    	def __init__(self, pretrained):
    		super(extractor, self).__init__()
    		vgg16_bn = VGG(make_layers(cfg, batch_norm=True))
    		if pretrained:
    			vgg16_bn.load_state_dict(torch.load('./pths/vgg16_bn-6c64b313.pth'))
    		self.features = vgg16_bn.features
    	
    	def forward(self, x):
    		out = []
    		for m in self.features:
    			x = m(x)
    			#提取maxpool层为后续合并
    			if isinstance(m, nn.MaxPool2d):
    				out.append(x)
    		return out[1:]
    
    • 特征合并层

    合并特征提取层的输出,具体的定义如下代码所示,代码部分已经注释.

    其中x中存放的是特征提取层的四个输出

    	def forward(self, x):
    
    		y = F.interpolate(x[3], scale_factor=2, mode='bilinear', align_corners=True)
    		y = torch.cat((y, x[2]), 1)
    		y = self.relu1(self.bn1(self.conv1(y)))		
    		y = self.relu2(self.bn2(self.conv2(y)))
    		
    		y = F.interpolate(y, scale_factor=2, mode='bilinear', align_corners=True)
    		y = torch.cat((y, x[1]), 1)
    		y = self.relu3(self.bn3(self.conv3(y)))		
    		y = self.relu4(self.bn4(self.conv4(y)))
    		
    		y = F.interpolate(y, scale_factor=2, mode='bilinear', align_corners=True)
    		y = torch.cat((y, x[0]), 1)
    		y = self.relu5(self.bn5(self.conv5(y)))		
    		y = self.relu6(self.bn6(self.conv6(y)))
    		
    		y = self.relu7(self.bn7(self.conv7(y)))
    		return y
    
    • 输出层

    输出层包括三个部分,这里以RBOX为例子,发现网上都没有QUAN为例子的?

    首先QUAN的计算是为了防止透视变换的存在,正常情况下不存在这些问题,正常的斜框可以解决。

    因为QUAN的计算没啥好处,前者已经完全可以解决正常的检测问题,后者回归四个点相对来说较为困难(如果文本变化较大就更困难,所以SSD和YOLO无法检测文本的原因)。

    如果想得到特殊的文本,基本考虑别的网络了(比如弯曲文字的检测)

    	def forward(self, x):
    		score = self.sigmoid1(self.conv1(x))
    		loc   = self.sigmoid2(self.conv2(x)) * self.scope
    		angle = (self.sigmoid3(self.conv3(x)) - 0.5) * math.pi
    		geo   = torch.cat((loc, angle), 1) 
    		return score, geo
    

    三. EAST细节分析

    3.1 标签制作

    注意:这里是重点和难点!!!

    文章说要把标签向里缩进0.3

    笔者认为这样做的目的是提取到更为准确的信息,不论是人工标注的好与不好,我们按照0.3缩小之后提取的特征都是全部的文本信息。

    但是这样做也会丢失一些边缘信息,如果按照上述的推断,那么SSD或YOLO都可以这样设计标签了。

    作者肯定是经过测试的,有好处有坏处吧!

    图3-1

    标签格式为:5个geometry(4个location+1个angle) + 1个score ==6 × N × M

    其中(b)为score图 ,(d)为四个location图, (e)为angle图

    上图可能看的不清楚,下面以手绘图进行说明:

    图3-2

    上图可能看不清楚,下面再用文字大概说一下吧!

    1. 先进行0.3缩放,这个时候的图就是score
    2. 没缩放的图像为基准,画最小外接矩形,这个外接矩形的角度就是angle。这个大小是缩放的的图大小。感觉直接以score图做角度也一样的。
    3. score图的每个像素点到最小外接矩形的距离为四个location图。

    3.2 LOSS计算

    LOSS计算就比较简单的,直接回归location、angle、score即可。

    	def forward(self, gt_score, pred_score, gt_geo, pred_geo, ignored_map):
    		#图像中不存在目标直接返回0
    		if torch.sum(gt_score) < 1:
    			return torch.sum(pred_score + pred_geo) * 0
    		#score loss 采用Dice方式计算,没有采用log熵计算,为了防止样本不均衡问题
    		classify_loss = get_dice_loss(gt_score, pred_score*(1-ignored_map))
    		#geo loss采用Iou方式计算(计算每个像素点的loss)
    		iou_loss_map, angle_loss_map = get_geo_loss(gt_geo, pred_geo)
    		#计算一整张图的loss,angle_loss_map*gt_score去除不是目标点的像素(感觉这句话应该放在前面减少计算量,放在这里没有减少计算loss的计算量)
    		angle_loss = torch.sum(angle_loss_map*gt_score) / torch.sum(gt_score)
    		iou_loss = torch.sum(iou_loss_map*gt_score) / torch.sum(gt_score)
    		geo_loss = self.weight_angle * angle_loss + iou_loss#这里的权重设置为1
    		print('classify loss is {:.8f}, angle loss is {:.8f}, iou loss is {:.8f}'.format(classify_loss, angle_loss, iou_loss))
    		return geo_loss + classify_loss
    

    **注意:**这里score的LOSS使用Dice方式,因为普通的交叉熵无法解决样本不均衡问题!!!

    图3-3

    3.3 NMS计算

    NMS使用的是locality NMS,也就是为了针对EAST而提出来的。

    首先我们先来看看这个LANMS的原理和过程:

    import numpy as np
    from shapely.geometry import Polygon
    
    def intersection(g, p):
        #取g,p中的几何体信息组成多边形
        g = Polygon(g[:8].reshape((4, 2)))
        p = Polygon(p[:8].reshape((4, 2)))
    
        # 判断g,p是否为有效的多边形几何体
        if not g.is_valid or not p.is_valid:
            return 0
    
        # 取两个几何体的交集和并集
        inter = Polygon(g).intersection(Polygon(p)).area
        union = g.area + p.area - inter
        if union == 0:
            return 0
        else:
            return inter/union
    
    def weighted_merge(g, p):
        # 取g,p两个几何体的加权(权重根据对应的检测得分计算得到)
        g[:8] = (g[8] * g[:8] + p[8] * p[:8])/(g[8] + p[8])
        
        #合并后的几何体的得分为两个几何体得分的总和
        g[8] = (g[8] + p[8])
        return g
    
    def standard_nms(S, thres):
        #标准NMS
        order = np.argsort(S[:, 8])[::-1]
        keep = []
        while order.size > 0:
            i = order[0]
            keep.append(i)
            ovr = np.array([intersection(S[i], S[t]) for t in order[1:]])
            inds = np.where(ovr <= thres)[0]
            order = order[inds+1]
            
        return S[keep]
    
    def nms_locality(polys, thres=0.3):
        '''
        locality aware nms of EAST
        :param polys: a N*9 numpy array. first 8 coordinates, then prob
        :return: boxes after nms
        '''
        S = []    #合并后的几何体集合
        p = None   #合并后的几何体
        for g in polys:
            if p is not None and intersection(g, p) > thres:    #若两个几何体的相交面积大于指定的阈值,则进行合并
                p = weighted_merge(g, p)
            else:    #反之,则保留当前的几何体
                if p is not None:
                    S.append(p)
                p = g
        if p is not None:
            S.append(p)
        if len(S) == 0:
            return np.array([])
        return standard_nms(np.array(S), thres)
    
    if __name__ == '__main__':
        # 343,350,448,135,474,143,369,359
        print(Polygon(np.array([[343, 350], [448, 135],
                                [474, 143], [369, 359]])).area)
    

    别看那么多代码,讲的很玄乎,其实很简单:

    1. 遍历每个预测的框,然后按照交集大于某个值K就合并相邻的两个框。
    2. 合并完之后就按照正常NMS消除不合理的框就行了。

    注意: 为什么相邻的框合并?

    1. 因为每个像素预测一个框(不明白就自己去看上面LOSS计算),一个目标的几百上千个框基本都是重合的(如果预测的准的话),所以说相邻的框直接进行合并就行了。
    2. 其实竖直和横向都合并一次最好,反正原理一样的。

    四. Pytorch源码分析

    源码就不进行分析了,上面已经说得非常明白了,基本每个难点和重点都说到了。

    有一点小bug,现进行说明:

    1. 训练的时候出现孔样本跑死
    SampleNum = 3400 #定义样本数量,应对空标签的文本bug,临时处理方案
    class custom_dataset(data.Dataset):
    	def __init__(self, img_path, gt_path, scale=0.25, length=512):
    		super(custom_dataset, self).__init__()
    		self.img_files = [os.path.join(img_path, img_file) for img_file in sorted(os.listdir(img_path))]
    		self.gt_files  = [os.path.join(gt_path, gt_file) for gt_file in sorted(os.listdir(gt_path))]
    		self.scale = scale
    		self.length = length
    
    	def __len__(self):
    		return len(self.img_files)
    
    	def __getitem__(self, index):
    		with open(self.gt_files[index], 'r') as f:
    			lines = f.readlines()
    		while(len(lines)<1):
    			index = int(SampleNum*np.random.rand())
    			with open(self.gt_files[index], 'r') as f:
    				lines = f.readlines()
    		vertices, labels = extract_vertices(lines)
    		
    		img = Image.open(self.img_files[index])
    		img, vertices = adjust_height(img, vertices) 
    		img, vertices = rotate_img(img, vertices)
    		img, vertices = crop_img(img, vertices, labels, self.length,index)
    		transform = transforms.Compose([transforms.ColorJitter(0.5, 0.5, 0.5, 0.25), \
                                            transforms.ToTensor(), \
                                            transforms.Normalize(mean=(0.5,0.5,0.5),std=(0.5,0.5,0.5))])
    		
    		score_map, geo_map, ignored_map = get_score_geo(img, vertices, labels, self.scale, self.length)
    		return transform(img), score_map, geo_map, ignored_map
    
    1. 测试的时候读取PIL会出现RGBA情况
    	img_path    = './013.jpg'
    	model_path  = './pths/model_epoch_225.pth'
    	res_img     = './res.bmp'
    	img = Image.open(img_path)
    	img = np.array(img)[:,:,:3]
    	img = Image.fromarray(img)
    
    • 后续工作
    1. 这个代码感觉有点问题,训练速度很慢,猜测是数据处理部分。
    2. 原版EAST每个点都进行回归,太浪费时间了,后续参考AdvanceEAST进行修改,同时加个人理解优化
    3. 网络太大了,只适合服务器或者PC上跑,当前网络已经修改到15MB,感觉还是有点大。
    4. 后续还要加识别部分,困难重重。。。。。。

    这里的代码都是github上的,笔者只是搬运工而已!!!

    原作者下载地址

    五. 第一次更新内容

    • 2019-6-30更新

    之前提到这个工程的代码有几个缺陷,在这里进行详细的解决

    1. 训练速度很慢

    这是由于源代码的数据处理部分编写有问题导致,随机crop中对于边界问题处理
    以下给出解决方案,具体修改请读者对比源代码即可:

    def crop_img(img, vertices, labels, length, index):
    	'''crop img patches to obtain batch and augment
    	Input:
    		img         : PIL Image
    		vertices    : vertices of text regions <numpy.ndarray, (n,8)>
    		labels      : 1->valid, 0->ignore, <numpy.ndarray, (n,)>
    		length      : length of cropped image region
    	Output:
    		region      : cropped image region
    		new_vertices: new vertices in cropped region
    	'''
    	try:
    		h, w = img.height, img.width
    		# confirm the shortest side of image >= length
    		if h >= w and w < length:
    			img = img.resize((length, int(h * length / w)), Image.BILINEAR)
    		elif h < w and h < length:
    			img = img.resize((int(w * length / h), length), Image.BILINEAR)
    		ratio_w = img.width / w
    		ratio_h = img.height / h
    		assert(ratio_w >= 1 and ratio_h >= 1)
    
    		new_vertices = np.zeros(vertices.shape)
    		if vertices.size > 0:
    			new_vertices[:,[0,2,4,6]] = vertices[:,[0,2,4,6]] * ratio_w
    			new_vertices[:,[1,3,5,7]] = vertices[:,[1,3,5,7]] * ratio_h
    		#find four limitate point by vertices
    		vertice_x = [np.min(new_vertices[:, [0, 2, 4, 6]]), np.max(new_vertices[:, [0, 2, 4, 6]])]
    		vertice_y = [np.min(new_vertices[:, [1, 3, 5, 7]]), np.max(new_vertices[:, [1, 3, 5, 7]])]
    		# find random position
    		remain_w = [0,img.width - length]
    		remain_h = [0,img.height - length]
    		if vertice_x[1]>length:
    			remain_w[0] = vertice_x[1] - length
    		if vertice_x[0]<remain_w[1]:
    			remain_w[1] = vertice_x[0]
    		if vertice_y[1]>length:
    			remain_h[0] = vertice_y[1] - length
    		if vertice_y[0]<remain_h[1]:
    			remain_h[1] = vertice_y[0]
    
    		start_w = int(np.random.rand() * (remain_w[1]-remain_w[0]))+remain_w[0]
    		start_h = int(np.random.rand() * (remain_h[1]-remain_h[0]))+remain_h[0]
    		box = (start_w, start_h, start_w + length, start_h + length)
    		region = img.crop(box)
    		if new_vertices.size == 0:
    			return region, new_vertices
    
    		new_vertices[:,[0,2,4,6]] -= start_w
    		new_vertices[:,[1,3,5,7]] -= start_h
    	except IndexError:
    		print("\n crop_img function index error!!!\n,imge is %d"%(index))
    	else:
    		pass
    	return region, new_vertices
    
    1. LOSS刚开始收敛下降,到后面就呈现抖动(像过拟合现象),检测效果角度很差

    由于Angle Loss角度计算错误导致,请读者阅读作者原文进行对比

    def find_min_rect_angle(vertices):
    	'''find the best angle to rotate poly and obtain min rectangle
    	Input:
    		vertices: vertices of text region <numpy.ndarray, (8,)>
    	Output:
    		the best angle <radian measure>
    	'''
    	angle_interval = 1
    	angle_list = list(range(-90, 90, angle_interval))
    	area_list = []
    	for theta in angle_list: 
    		rotated = rotate_vertices(vertices, theta / 180 * math.pi)
    		x1, y1, x2, y2, x3, y3, x4, y4 = rotated
    		temp_area = (max(x1, x2, x3, x4) - min(x1, x2, x3, x4)) * \
                        (max(y1, y2, y3, y4) - min(y1, y2, y3, y4))
    		area_list.append(temp_area)
    	
    	sorted_area_index = sorted(list(range(len(area_list))), key=lambda k : area_list[k])
    	min_error = float('inf')
    	best_index = -1
    	rank_num = 10
    	# find the best angle with correct orientation
    	for index in sorted_area_index[:rank_num]:
    		rotated = rotate_vertices(vertices, angle_list[index] / 180 * math.pi)
    		temp_error = cal_error(rotated)
    		if temp_error < min_error:
    			min_error = temp_error
    			best_index = index
    
    	if angle_list[best_index]>0:
    		return (angle_list[best_index] - 90) / 180 * math.pi
    
    	return (angle_list[best_index]+90) / 180 * math.pi
    
    1. 修改网络从50MB到15MB,对于小样本训练效果很好

    这里比较简单,直接修改VGG和U-NET网络feature map即可

    cfg = [32, 32, 'M', 64, 64, 'M', 128, 128, 128, 'M', 256, 256, 256, 'M', 256, 256, 256, 'M']
    #合并不同的feature map
    class merge(nn.Module):
    	def __init__(self):
    		super(merge, self).__init__()
    
    		self.conv1 = nn.Conv2d(512, 128, 1)
    		self.bn1 = nn.BatchNorm2d(128)
    		self.relu1 = nn.ReLU()
    		self.conv2 = nn.Conv2d(128, 128, 3, padding=1)
    		self.bn2 = nn.BatchNorm2d(128)
    		self.relu2 = nn.ReLU()
    
    		self.conv3 = nn.Conv2d(256, 64, 1)
    		self.bn3 = nn.BatchNorm2d(64)
    		self.relu3 = nn.ReLU()
    		self.conv4 = nn.Conv2d(64, 64, 3, padding=1)
    		self.bn4 = nn.BatchNorm2d(64)
    		self.relu4 = nn.ReLU()
    
    		self.conv5 = nn.Conv2d(128, 32, 1)
    		self.bn5 = nn.BatchNorm2d(32)
    		self.relu5 = nn.ReLU()
    		self.conv6 = nn.Conv2d(32, 32, 3, padding=1)
    		self.bn6 = nn.BatchNorm2d(32)
    		self.relu6 = nn.ReLU()
    
    		self.conv7 = nn.Conv2d(32, 32, 3, padding=1)
    		self.bn7 = nn.BatchNorm2d(32)
    		self.relu7 = nn.ReLU()
    		#初始化网络参数
    		for m in self.modules():
    			if isinstance(m, nn.Conv2d):
    				nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
    				if m.bias is not None:
    					nn.init.constant_(m.bias, 0)
    			elif isinstance(m, nn.BatchNorm2d):
    				nn.init.constant_(m.weight, 1)
    				nn.init.constant_(m.bias, 0)
    
    1. 小的字体检测很好,大的字体检测不到(部分检测不到)情况

    这里是模仿AdvanceEAST的方法进行训练,先在小图像进行训练,然后迁移到大图像即可。

    意思就是先将图像缩小到254254训练得到modeul_254.pth
    然后在将图像resize到384
    384,网络参数使用modeul_254.pth,训练得到modeul_384.pth
    。。。一次进行512或者更大的图像即可

    1. 针对图像训练和检测的慢(相对于其他检测网络)

    这里需要根据原理来说了,是因为全部的像素都需要预测和计算loss,可以看看AdvanceEAST的网络进行处理即可

    1. 修改网络说明

    训练样本3000
    测试样本100
    检测精度85%,IOU准确度80%
    5个epoch收敛结束(这些都是这里测试的)
    两块1080TI,训练时间10分钟左右

    这里是我完整的工程


    五. 参考文献

    展开全文
  • PyTorch源码浅析:简介

    2021-01-14 11:24:47
    PyTorch源码浅析:简介 这个系列文章自底向上针对PyTorch核心源码进行解析,从Tensor库→​神经网络算符→​自动微分引擎→​Python扩展,一共五篇。代码较多,理解有限,如发现理解不当或表达不妥的地方,还请在...

    PyTorch源码浅析:简介

    这个系列文章自底向上针对PyTorch核心源码进行解析,从Tensor库→​神经网络算符→​自动微分引擎→​Python扩展,一共五篇。代码较多,理解有限,如发现理解不当或表达不妥的地方,还请在评论区指出。

    目录

    1. THTensor

    PyTorch中Tensor的存储和表示分开,多个THTensor可能共享一个THStorage,每个THTensor可能拥有不同的view(e.g. size, stride)。这样设计的好处是,有时看起来不一样的数据底层是共享的,比如矩阵与矩阵的转置、二维矩阵与二维矩阵变成一维时的矩阵。这部分的主要实现在pytorch/aten文件夹中,这里面既实现了底层的Tensor操作库,也封装了名为 ATen 的 C++11接口。

    2. THC

    这篇主要看 Torch CUDA 部分,对应源码目录aten/src/THC,里面包含了许多C++和CUDA代码。这部分实现了操作 THCTensor 和 THCStorage 的接口,不过底层用的数据结构还是TensorImpl和StorageImpl。THC里的接口也是通过C语言范式实现的,但是Apply系列操作不再由宏来实现,而是使用了C++模板。其他的区别还有allocator不同,以及多了 THCState 结构。

    3. NN

    THNN是一个用C语言实现的神经网络模块的库,提供的功能非常底层。它实现了许多基础的神经网络模块,包括线性层,卷积层,Sigmoid等各种激活层,一些基本的loss函数,这些API都声明在THNN/generic/THNN.h中。每个模块都实现了前向传导(forward)和后向传导(backward)的功能。THCUNN则是对应模块的CUDA实现。

    4. Autograd

    这篇博客介绍 PyTorch 中自动微分引擎的实现,主要分为三部分:首先简要介绍一下计算图的原理;然后介绍 PyTorch 中与 autograd 的相关数据结构和backward()函数的实现,数据结构包括torch::autograd::Variable,torch::autograd::Function等;最后讲一下动态建立计算图的实现,这部分代码涉及到动态派发机制,而且都是用脚本生成的,不太容易理解。

    5. Python扩展

    这篇是本系列最后一篇博客了,介绍一下前面的C++代码怎么与Python交互,或者说Python里怎么调用C++代码进行高效的计算。首先简单介绍一下预备知识,既Python的C扩展通常怎么写;然后以比较核心的数据结构 Tensor 和 Storage 为例看一下它们怎么转换为Python类型的;最后稍带点儿Python自微分函数的实现。

    源码目录结构

    pytorch
    ├── aten                    # ATen: C++ Tensor库
    │   ├── CMakeLists.txt
    │   ├── conda
    │   ├── src
    │   │   ├── ATen            # C++ bindings
    │   │   ├── README.md
    │   │   ├── TH              # torch tensor
    │   │   ├── THC             # torch cuda
    │   │   ├── THCUNN          # torch cuda nn
    │   │   └── THNN            # torch nn
    │   └── tools
    ├── c10                     # 这里面也包含一些Tensor实现
    │   ├── CMakeLists.txt
    │   ├── core
    │   ├── cuda
    │   ├── hip
    │   ├── macros
    │   ├── test
    │   └── util
    ├── caffe2                  # caffe2
    ├── tools
    │   ├── autograd            # 生成自微分相关函数的工具
    │   ├── ...
    │   └── shared
    ├── torch                   # Python模块
    │   ├── autograd
    │   ├── csrc                # C++相关源码
    │   │   ├── autograd        # 自动微分引擎实现
    │   │   ├── cuda
    │   │   ├── distributed
    │   │   ├── generic
    │   │   ├── jit
    │   │   ├── multiprocessing
    │   │   ├── nn
    │   │   ├── tensor
    │   │   ├── utils
    │   │   ├── ...
    │   │   └── utils.h
    │   ├── cuda
    │   ├── nn
    │   ├── ...
    │   ├── storage.py
    │   └── tensor.py
    ├── ...
    └── ubsan.supp
    

    代码统计

    注:仅统计了torch和aten两个核心文件夹。

    感受

    一开始只是心血来潮觉得这学期反正不是很忙就立了个flag决定学期内把PyTorch源码看一遍,看的过程很受苦,庆幸最终还是坚持下来了,收获也很大。除了理解了PyTorch是如何运行的、输出这五篇博客之外,我对C++的理解也有显著提升,因为PyTorch大部分代码是用C++写的,各种新特性简直刷新了我对这门语言的认识,由此也专门记了一篇关于C++的笔记。

    简单说一下我的阅读方法。面对这么多的代码和文件,一下子肯定不知所措,尤其是阅读新模块的时候,我首先会尝试找到该模块的说明,通过README.md或前人的博客或API文档了解下该模块大概功能和结构,然后整体(粗略)浏览一遍该模块的代码,对每个文件里的代码是做什么的有个大致概念,最后再根据自己的理解选择性地进行精读。

    展开全文
  • 添加链接描述PyTorch源码解读之torchvision.transforms
    展开全文
  • 5. 网络 微调预训练网络RESNET pytorch源码,天气数据四分类问题
  • Pytorch 源码编译 Windows GPU编译工具和第三方库1.1 Visual studio 20191.2 Cuda toolkit1.3 cudnn1.4 mkl1.5 magma1.6 sccache1.7 安装Ananconda 或者 miniconda1.8 安装python 包设置环境变量开始编译编译Pytorch...
  • Pytorch源码解析

    2020-11-14 20:44:50
    PyTorch源码浅析(目录) https://zhuanlan.zhihu.com/p/34629243 pytorch源码解析:Tensor的生成过程 https://blog.csdn.net/tanmx219/article/details/86762506
  • 深度学习pytorch源码

    2019-04-16 09:55:57
    这是深度学习pytorch中涉及到的源码,大多都能跑通,跑不通的可以自行上网搜索解决办法。
  • PyTorch源码解读之torchvision.models

    万次阅读 多人点赞 2018-01-21 13:28:35
    PyTorch框架中有一个非常重要且好用的包:torchvision,该包主要由3个子包组成,分别是:torchvision.datasets、torchvision.models、torchvision.transforms。这3个子包的具体介绍可以参考官网:...
  • Pytorch源码之RNN理解

    千次阅读 2018-01-24 22:33:36
    Pytorch源码之RNN理解  我用的pytorch0.2,除了API的解释外,部分容易混淆。因此我依次整理了一下。下面是rnn.py的structure, RNN类  该类实现了RNN, math公式如下: (1)ht=tanh⁡(wih∗xt...
  • (5) PyTorch源码修改之增加ConvLSTM层 (6) 梯度反向传递(BackPropogate)的理解 (7) 模型的训练和测试、保存和加载 (8) pyTorch-To-Caffe (总) PyTorch遇到令人迷人的BUG 通过扩展torch.nn的方式...
  • pytorch源码编译遇到的问题

    千次阅读 2018-09-25 11:37:13
    1. 编译到大概33%处,出现Failed to run 'bash ../tools/build_pytorch_libs.sh --use-cuda ...解决:最新的pytorch源码编译要求CUDNN&gt;5,升级CUDNN到6.0以上的版本即可。 不需要更改/usr/local/cuda下边的c...
  • pytorch源码地址:https://github.com/fxia22/pointnet.pytorch.git 个人详细注释源码地址:https://github.com/Dir-b/PointNet.git 前言 point_base方法的开山之作,本篇主要对PointNet论文谈谈个人理解,并详细...
  • PyTorch源码解读之torch.utils.data.DataLoader

    万次阅读 多人点赞 2018-01-14 19:28:33
    PyTorch中数据读取的一个重要接口是torch.utils.data.DataLoader,该接口定义在dataloader.py脚本中,只要是用PyTorch来训练模型基本都会用到该接口,该接口主要用来将自定义的数据读取接口的输出或者PyTorch已有的...
  • pdb:简单的python debug (调试pytorch源码) #准备工作conda create -n pytorch python=3.7 conda activate pytorch #准备工作conda install pytorch torchvision cpuonly -c pytorch conda install pdb 调试的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,237
精华内容 3,694
关键字:

pytorch源码