Faster RCNN generate.py

本文详细解析了如何使用OpenCV和PIL加载图像,并转换为适用于Caffe的格式。核心内容包括从图像生成RPN(区域提议网络)提案的具体步骤,涵盖了图像预处理、网络前向传播以及提案输出的全过程。
部署运行你感兴趣的模型镜像

该模块的功能主要是生成rpn proposals。
+ cv2.imread读取的图像的存储格式为H W K,且三通道的顺序为BGR
+ PIL.Image.open读取图片的存储格式为:W H (此时的数据为PIL库的某种对象),且三通道顺序为RGB
但是,当转换为np.array的时候,存储格式将H W K,常用的代码段为:

def load_image(self, idx):
        """
        Load input image and preprocess for Caffe:
        - cast to float
        - switch channels RGB -> BGR
        - subtract mean
        - transpose to channel x height x width order
        """
        im = Image.open('xxx.jpg')
        in_ = np.array(im, dtype=np.float32)
        in_ = in_[:,:,::-1]
        in_ -= self.mean
        in_ = in_.transpose((2,0,1))
        return in_

这里写图片描述

def imdb_proposals(net, imdb):

def imdb_proposals(net, imdb):
    """Generate RPN proposals on all images in an imdb."""

    _t = Timer()
    imdb_boxes = [[] for _ in xrange(imdb.num_images)]
    for i in xrange(imdb.num_images):
        # cv2.imread读取的图像的存储格式为H W K,且三通道的顺序为BGR
        # PIL.Image.open读取图片的存储格式为:W H K ,且三通道顺序为RGB
        im = cv2.imread(imdb.image_path_at(i))
        _t.tic()
        #调用 im_proposals生成单张图片的rpn proposals, 以及得分
        imdb_boxes[i], scores = im_proposals(net, im)
        _t.toc()
        print 'im_proposals: {:d}/{:d} {:.3f}s' \
              .format(i + 1, imdb.num_images, _t.average_time)
        if 0:
            dets = np.hstack((imdb_boxes[i], scores))
            # from IPython import embed; embed()
            _vis_proposals(im, dets[:3, :], thresh=0.9)
            plt.show()

    return imdb_boxes

def im_proposals(net, im):该方法中会调用网络的forwad,从而得到想要的boxes和scores

def im_proposals(net, im):
    """Generate RPN proposals on a single image."""
    blobs = {}
    #调用_get_image_blob函数将图像转换为caffe所支持的输入数据结构即四维blob
    blobs['data'], blobs['im_info'] = _get_image_blob(im)
    # *(blobs['data'].shape 中的 ‘*’涉及到了python中函数的参数收集及逆操作
    net.blobs['data'].reshape(*(blobs['data'].shape))
    net.blobs['im_info'].reshape(*(blobs['im_info'].shape))
    blobs_out = net.forward(
            data=blobs['data'].astype(np.float32, copy=False),
            im_info=blobs['im_info'].astype(np.float32, copy=False))
    #返回im_info这个blob中存储的scale,等价于blobs['im_info'][0][2]
    scale = blobs['im_info'][0, 2]
    # 通过net的前向传播得到boxes, scores,注意,将boxes返回之前,需要将其缩放会原来的size
    # blobs_out['rois'][:]的第一位为类别,后四位才是坐标
    boxes = blobs_out['rois'][:, 1:].copy() / scale
    scores = blobs_out['scores'].copy()
    return boxes, scores

下面重点讲一下blobs_out = net.forward(data=blobs['data'].astype(np.float32, copy=False), im_info=blobs['im_info'].astype(np.float32, copy=False)), 当然纯属个人观点:

def _Net_forward(self, blobs=None, start=None, end=None, **kwargs):
    """
    Forward pass: prepare inputs and run the net forward.

    Parameters
    ----------
    blobs : list of blobs to return in addition to output blobs.
    kwargs : Keys are input blob names and values are blob ndarrays.
             For formatting inputs for Caffe, see Net.preprocess().
             If None, input is taken from data layers.
    start : optional name of layer at which to begin the forward pass
    end : optional name of layer at which to finish the forward pass
          (inclusive)

    Returns
    -------
    outs : {blob name: blob ndarray} dict.
    """
    if blobs is None:
        blobs = []
        # 返回name为start的layer的id,作为start_ind
        start_ind = list(self._layer_names).index(start)
    else:
        start_ind = 0

    if end is not None:
        end_ind = list(self._layer_names).index(end)
        outputs = set([end] + blobs)
    else:
        end_ind = len(self.layers) - 1
        outputs = set(self.outputs + blobs)

    if kwargs:
        if set(kwargs.keys()) != set(self.inputs):
            raise Exception('Input blob arguments do not match net inputs.')
        # Set input according to defined shapes and make arrays single and
        # C-contiguous as Caffe expects.
        # in_为blob name, blob为 blob ndarray
        for in_, blob in kwargs.iteritems():
            if blob.shape[0] != self.blobs[in_].num:
                raise Exception('Input is not batch sized')
            self.blobs[in_].data[...] = blob
    # 对应_caffe.cpp中的.def("_forward", &Net<Dtype>::ForwardFromTo),可以猜想应该是调用底层的Net<Dtype>::ForwardFromTo方法,进行前向传播
    self._forward(start_ind, end_ind)

    # Unpack blobs to extract
    #rpn_test.pt所定义的网络的output为:rois blob 和 scores blob 两行log可以说明:
    #I0429 03:42:10.559293  9520 net.cpp:270] This network produces output rois
    #I0429 03:42:10.559300  9520 net.cpp:270] This network produces output scores

    #outputs为以列表,其元素为网络所有输出blob的name
    return {out: self.blobs[out].data for out in outputs}
  1. net.forwar() 调用的是Pycaffe.py中的_Net_forward函数,代码如上:(关于pycaffe.py —-> Wrap the internal caffe C++ module (_caffe.so) with a clean, Pythonic interface.
  2. 在Pycaffe.py中,方法中带有self参数,个人觉得这应该表示一个Net对象,_Net_forward返回一个字典,{blob name: blob ndarray},
  3. start, end为可选的 layer name,注意是name
  4. kwargs : Keys are input *blob names and values are blob ndarrays.*
  5. self._layer_names:对应_caffe.cpp中的.add_property("_layer_names", bp::make_function(&Net<Dtype>::layer_names,bp::return_value_policy<bp::copy_const_reference>())),可以猜想应该是调用底层的Net::layer_names,返回网络中所有层的name
  6. self._forward(start_ind, end_ind):对应_caffe.cpp中的.def("_forward", &Net<Dtype>::ForwardFromTo),可以猜想应该是调用底层的Net<Dtype>::ForwardFromTo方法,进行前向传播
  7. outputs = set(self.outputs + blobs):对应pycaffe.py中

    @property
    def _Net_outputs(self):
    return [list(self.blobs.keys())[i] for i in self._outputs]
    

    a) self._outputs(_caffe.cpp)调用底层的Net::output_blob_indices方法,返回网络所有输出blob的id ;
    b) self.blobs.keys():
    self.blobs对应pycaffe.py中的

    def _Net_blobs(self):
    """
    An OrderedDict (bottom to top, i.e., input to output) of network
    blobs indexed by name
    """
    return OrderedDict(zip(self._blob_names, self._blobs))

    返回{blob name : blob ndarray} dict
    所以self.outputs返回的应该是网络输出blob的name

总之, _caffe.cpp 和 pycaffe.py这两个文件要好好研究一下


def _get_image_blob(im)

def _get_image_blob(im):
    """Converts an image into a network input.也就是将图像转换为caffe所支持的输入数据结构即blob

    Arguments:
        im (ndarray): a color image in BGR order

    Returns:
        blob (ndarray): a data blob holding an image pyramid
        im_scale_factors (list): list of image scales (relative to im) used
            in the image pyramid
    """
    im_orig = im.astype(np.float32, copy=True)
    im_orig -= cfg.PIXEL_MEANS

    im_shape = im_orig.shape
    im_size_min = np.min(im_shape[0:2])
    im_size_max = np.max(im_shape[0:2])

    processed_ims = []

    assert len(cfg.TEST.SCALES) == 1
    target_size = cfg.TEST.SCALES[0]

    im_scale = float(target_size) / float(im_size_min)
    # Prevent the biggest axis from being more than MAX_SIZE
    if np.round(im_scale * im_size_max) > cfg.TEST.MAX_SIZE:
        im_scale = float(cfg.TEST.MAX_SIZE) / float(im_size_max)
    im = cv2.resize(im_orig, None, None, fx=im_scale, fy=im_scale,
                    interpolation=cv2.INTER_LINEAR)

    # im_info,一些图像信息:H W scale, 而且数据结构为[[H, W, scale]]
    #np.newaxis添加了一个新轴,但是,新坐标轴上没有元素
    im_info = np.hstack((im.shape[:2], im_scale))[np.newaxis, :]
    processed_ims.append(im)

    # Create a blob to hold the input images
    #调用blob.py中的im_list_to_blob将图像转换为caffe所支持的数据结构blob,所做的工作就是复制数据,调整通道顺序,im_list_to_blob返回的其实是np.ndarray
    blob = im_list_to_blob(processed_ims)
    #返回的blob, im_info其实都是np.ndarray
    return blob, im_info

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>好的,我现在需要帮助用户解决在PyTorch项目中加载模型文件时遇到的FileNotFoundError问题,具体是找不到'voc_weights_resnet.pth'文件。首先,我得理解这个问题的背景。用户可能在运行一个基于Faster R-CNN的项目,比如目标检测,使用预训练的权重文件,但程序找不到该文件。 首先,我应该考虑这个文件是否存在。用户可能没有正确下载或放置这个权重文件。常见的解决步骤可能包括检查文件路径是否正确,确认文件是否存在于指定位置。如果文件不存在,可能需要下载或生成该文件。 然后,我需要参考用户提供的引用内容。引用[1]提到了从Kaggle下载数据集使用的命令,包括安装kaggle和unzip工具,这可能暗示用户需要类似的方法下载权重文件。但用户的问题是关于.pth文件,而不是数据集,所以可能需要不同的途径获取。 引用[2]提到Fast R-CNN的改进,但用户的问题更偏向于文件路径错误,而不是模型结构问题。不过,可能需要确认用户是否正确安装了相关库,或者是否在代码中正确指定了预训练模型的路径。 接下来,我应该列出可能的解决方案。首先,检查文件路径是否正确,绝对路径还是相对路径的问题。然后,确认文件是否存在,如果不存在,可能需要下载。例如,PyTorch官方提供的预训练模型可能通过torchvision.models.detection.faster_rcnn来加载,而不需要手动下载权重文件。用户可能在代码中错误地引用了手动下载的权重文件路径,而不是使用预训练参数。 另一个可能性是用户使用的代码库需要特定的权重文件,例如VOC数据集训练的权重,而用户没有正确下载。这时候可能需要指导用户从正确的来源下载该文件,并放置在正确的位置。 此外,用户可能混淆了不同的预训练模型名称,导致路径错误。例如,是否应该是'fasterrcnn_resnet50_fpn.pth'而不是'voc_weights_resnet.pth'?需要确认文件名是否正确。 最后,可能涉及到环境问题,比如当前工作目录与代码中的路径不一致,导致文件找不到。这时候建议用户使用绝对路径,或者在代码中调整路径设置。 总结下来,可能的解决步骤包括: 1. 确认文件路径是否正确,相对路径是否相对于当前工作目录。 2. 检查文件是否确实存在,如果不存在,指导用户下载或生成。 3. 如果使用预训练模型,建议使用PyTorch内置的加载方式,而不是手动指定文件。 4. 确认是否有拼写错误或文件名不匹配的情况。 5. 修改代码以正确加载预训练模型,可能不需要手动加载权重文件。 另外,需要考虑到用户可能对PyTorch的模型加载机制不太熟悉,因此需要给出具体的代码示例,比如使用torchvision提供的预训练模型,或者正确加载自定义权重的方法。 可能还需要提醒用户关于路径中的斜杠方向,特别是在不同操作系统下的差异,比如Windows使用反斜杠,而Linux/macOS使用正斜杠,但在Python中应统一处理为反斜杠转义或使用原始字符串。 最后,生成相关问题需要考虑用户可能的后续疑问,比如如何下载预训练权重、如何设置正确的路径、如何处理其他类似的FileNotFoundError等。</think>### 解决PyTorch加载模型文件时的FileNotFoundError问题 #### 1. 检查文件路径与名称 - **问题分析**:`FileNotFoundError`通常由路径错误或文件名拼写错误导致。首先确认以下几点: - `voc_weights_resnet.pth`是否存在于代码指定的路径中? - **绝对路径 vs 相对路径**:如果代码中使用相对路径(如`./voc_weights_resnet.pth`),需确保文件位于当前工作目录下。可通过以下代码检查当前工作目录: ```python import os print(os.getcwd()) # 输出当前工作目录 ``` - **路径分隔符**:在Windows中需注意反斜杠`\`的转义问题,建议使用原始字符串或正斜杠: ```python model_path = r"C:\models\voc_weights_resnet.pth" # 原始字符串 # 或 model_path = "C:/models/voc_weights_resnet.pth" # 正斜杠 ``` #### 2. 确认文件来源 - **预训练模型加载方式**:PyTorch的`torchvision`库内置了Faster R-CNN的预训练模型,无需手动下载权重文件。例如: ```python import torchvision model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True) ``` 若需自定义训练(如VOC数据集),可能需要单独下载权重文件。建议从官方仓库或可靠来源获取`voc_weights_resnet.pth`[^1]。 #### 3. 替代解决方案:使用内置预训练模型 若项目无特殊需求,直接加载PyTorch提供的预训练模型: ```python # 加载预训练Faster R-CNN模型(基于COCO数据集) model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True) model.eval() ``` 若需适配VOC数据集,需在预训练模型基础上微调,而非直接加载权重[^2]。 #### 4. 手动下载并指定权重文件 若必须使用`voc_weights_resnet.pth`: 1. **下载文件**:从官方来源(如GitHub仓库或Kaggle)下载文件。 2. **指定绝对路径**: ```python model_path = "/path/to/voc_weights_resnet.pth" model = torch.load(model_path) ``` #### 5. 代码示例(完整流程) ```python import torch import torchvision # 方案1:使用PyTorch内置预训练模型 model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True) # 方案2:手动加载权重文件(需确保路径正确) try: model = torch.load("voc_weights_resnet.pth") except FileNotFoundError: print("错误:文件不存在,请检查路径或下载权重文件") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值