Faster-RCNN_TF代码解读7:VGGnet_train.py

本文介绍了一种基于VGG网络的训练模型VGGnet_train,详细解释了其构建过程,包括输入设置、网络结构搭建及损失函数计算等关键步骤,并针对区域提议网络(RPN)和候选区域选择进行了重点讲解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import tensorflow as tf
from networks.network import Network


#define

n_classes = 21
_feat_stride = [16,]
anchor_scales = [8, 16, 32]

class VGGnet_train(Network):
    def __init__(self, trainable=True):
        self.inputs = []
        self.data = tf.placeholder(tf.float32, shape=[None, None, None, 3])
        self.im_info = tf.placeholder(tf.float32, shape=[None, 3])
        self.gt_boxes = tf.placeholder(tf.float32, shape=[None, 5])
        #该参数定义dropout比例
        self.keep_prob = tf.placeholder(tf.float32)
        self.layers = dict({'data':self.data, 'im_info':self.im_info, 'gt_boxes':self.gt_boxes})
        self.trainable = trainable
        self.setup()

        # create ops and placeholders for bbox normalization process
        #建立weights,biases变量,用tf.assign来更新
        with tf.variable_scope('bbox_pred', reuse=True):
            weights = tf.get_variable("weights")
            biases = tf.get_variable("biases")

            self.bbox_weights = tf.placeholder(weights.dtype, shape=weights.get_shape())
            self.bbox_biases = tf.placeholder(biases.dtype, shape=biases.get_shape())
            #tf.assign用来更新参数值
            self.bbox_weights_assign = weights.assign(self.bbox_weights)
            self.bbox_bias_assign = biases.assign(self.bbox_biases)

    def setup(self):
        #feed就是从self.layers中的信息提取出来(包括slef.daya,self.im_info,self.gt_boxes)存入self.input
        #feed返回的是self,为conv第一个参数,conv参数(self,卷积核高,宽,深度,stride高,宽)
        #return self 用法:
        #class human(object)
        #   def __init__(self,weight):
        #       self.weight=weight
        #   def get_weight(self):
        #       return self.weight
        #想要调用get_weight,直接用human.get_weight(45)会告知调用之前要先实例化,weight为未绑定函数
        #而   human.get_weight(human(45))就可以正常输出,说明human(45)将get_weight绑定了
        #其实human(45)作为一个self传给get_weight()
        #conv:卷积高、宽、输出深度、步长高、宽
        (self.feed('data')
             .conv(3, 3, 64, 1, 1, name='conv1_1', trainable=False)
             .conv(3, 3, 64, 1, 1, name='conv1_2', trainable=False)
             .max_pool(2, 2, 2, 2, padding='VALID', name='pool1')
             .conv(3, 3, 128, 1, 1, name='conv2_1', trainable=False)
             .conv(3, 3, 128, 1, 1, name='conv2_2', trainable=False)
             .max_pool(2, 2, 2, 2, padding='VALID', name='pool2')
             .conv(3, 3, 256, 1, 1, name='conv3_1')
             .conv(3, 3, 256, 1, 1, name='conv3_2')
             .conv(3, 3, 256, 1, 1, name='conv3_3')
             .max_pool(2, 2, 2, 2, padding='VALID', name='pool3')
             .conv(3, 3, 512, 1, 1, name='conv4_1')
             .conv(3, 3, 512, 1, 1, name='conv4_2')
             .conv(3, 3, 512, 1, 1, name='conv4_3')
             .max_pool(2, 2, 2, 2, padding='VALID', name='pool4')
             .conv(3, 3, 512, 1, 1, name='conv5_1')
             .conv(3, 3, 512, 1, 1, name='conv5_2')
             .conv(3, 3, 512, 1, 1, name='conv5_3'))
        #========= RPN ============
        #feed操作就是保证self.inputs中只存有下一步操作所需要的上一层的输出数据,每一个op操作都会包含一个feed操作(定义在layer函数里)
        #在初始化feed时候可能需要好几种数据,如feed('rpn_cls_score','gt_boxes','im_info','data')
        (self.feed('conv5_3')
             .conv(3,3,512,1,1,name='rpn_conv/3x3')
            #anchor_scales为3个尺度,又有3个比例1:1,1:2,2:1,所以*3,又score为2个得分,所以*2
             .conv(1,1,len(anchor_scales)*3*2 ,1 , 1, padding='VALID', relu = False, name='rpn_cls_score'))
        #feed的返回值为参数层的输出,都是从self.layers这个字典中取的,layer函数中有将各层的输出存进self.layers的操作
        #'rpn-data'层给出了rpn中的所有信息,包括图片anchor(标签-1,0,1),回归值(dx,dy,dw,dh),两个权重
        #data:为图片像素信息,info:im_info[0]存的是图片像素行数即高,im_info[1]存的是图片像素列数即宽
        #gt_boxes:GT信息,为5维度,前四个为(xmin,ymin)(xmax,ymax),最后一个为标签
        #rpn_cls_score就把他看成一个简单的feature-map,深度为3*3*2,对应3比例*3尺度*2分类值
        (self.feed('rpn_cls_score','gt_boxes','im_info','data')
             .anchor_target_layer(_feat_stride, anchor_scales, name = 'rpn-data' ))

        # Loss of rpn_cls & rpn_boxes
        #回归bbox,存的是(dx,dy,dw,dh)
        (self.feed('rpn_conv/3x3')
             .conv(1,1,len(anchor_scales)*3*4, 1, 1, padding='VALID', relu = False, name='rpn_bbox_pred'))

        #========= RoI Proposal ============
        #先reshape后softmax激活
        (self.feed('rpn_cls_score')
             .reshape_layer(2,name = 'rpn_cls_score_reshape')#形状shape(1,9n,n,2)
             .softmax(name='rpn_cls_prob'))#形状shape(1,9n,n,2)
        #再reshape
        (self.feed('rpn_cls_prob')#形状shape(1,9n,n,2)
             .reshape_layer(len(anchor_scales)*3*2,name = 'rpn_cls_prob_reshape'))#形状shape(1,n,n,18),信息还原成'rpn_cls_score',刚才两步reshape_layer操作:1、修改为softmax格式。2、还原rpn_cls_score信息位置格式,只不过内容变为sotfmax得分

        (self.feed('rpn_cls_prob_reshape','rpn_bbox_pred','im_info')
            # 初始得到blob,内容为[proposal引索(全0),proposal],shape(proposals.shape[0](即暂存的proposals个数),5)
             .proposal_layer(_feat_stride, anchor_scales, 'TRAIN',name = 'rpn_rois'))
        #产生筛选后的roi,对应labels,三个(len(rois),4*21)大小的矩阵,其中一个对fg-roi对应引索行的对应类别的4个位置填上(dx,dy,dw,dh),另两个对fg-roi对应引索行的对应类别的4个位置填上(1,1,1,1)
        (self.feed('rpn_rois','gt_boxes')
             .proposal_target_layer(n_classes,name = 'roi-data'))


        #========= RCNN ============
        (self.feed('conv5_3', 'roi-data')
             .roi_pool(7, 7, 1.0/16, name='pool_5')
             .fc(4096, name='fc6')
             .dropout(0.5, name='drop6')
             .fc(4096, name='fc7')
             .dropout(0.5, name='drop7')
             .fc(n_classes, relu=False, name='cls_score')
             .softmax(name='cls_prob'))

        (self.feed('drop7')
             .fc(n_classes*4, relu=False, name='bbox_pred'))

<think>嗯,用户遇到了FileNotFoundError,错误信息显示找不到某个文件或目录。首先,我需要了解这个错误发生的上下文。根据引用[1]和[2],用户是在使用faster-RCNNPyTorch版本训练PASCAL VOC数据集时遇到了问题。具体来说,一个是找不到某个.txt文件,另一个是找不到.xml文件。用户现在想知道如何配置文件路径,特别是关于VOC2007train.txt文件的路径设置。 首先,我应该回忆一下faster-RCNN框架的数据集结构。PASCAL VOC数据集通常有特定的目录结构,比如VOCdevkit/VOC2007/Annotations存放XML文件,ImageSets/Main里有train.txt、test.txt等。用户可能在代码中配置的路径与实际存放的位置不一致,导致文件找不到。 接下来,我需要检查常见的路径配置错误。比如,是否在训练脚本中正确设置了数据集的根目录?是否在生成train.txt时路径有误?用户提到的错误中涉及到了VOC2007/Main下的.txt文件和000001.xml,可能是在生成图像列表或读取标注文件时路径拼接错误。 另外,用户可能没有正确生成train.txt文件,或者该文件中的图像名称与实际图像文件不对应。例如,train.txt中的每一行应该对应一个图像ID,而代码会根据这个ID去寻找对应的XML文件和JPEG图像。如果路径配置不正确,就会导致FileNotFoundError。 然后,我应该考虑如何指导用户逐步排查问题。首先确认数据集目录结构是否正确,然后检查配置文件中的路径变量是否正确指向数据集根目录。接着,查看生成train.txt的脚本是否正确处理了路径,是否使用了绝对路径或正确的相对路径。此外,权限问题也可能导致文件无法访问,但可能性较低,尤其是在用户自己的开发环境中。 还有,用户可能混淆了不同版本的数据集结构,例如VOC2007和VOC2012的差异,或者是否将数据集放置在正确的子目录下。例如,Annotations文件夹是否包含所有XML文件,Images文件夹是否有对应的JPEG文件。 最后,可能需要建议用户使用绝对路径进行测试,以确定是否是相对路径的问题,或者在代码中添加打印语句,输出当前尝试访问的路径,以便与实际存在的路径进行对比。这可以帮助用户快速定位路径配置错误的具体位置。</think>### 解决Python FileNotFoundError (Errno 2) 的路径配置教程 在训练`faster-rcnn-pytorch`时,`FileNotFoundError`通常由**文件路径配置错误**或**缺失必要文件**引起。以下是分步排查和解决方法: --- #### **步骤1:确认数据集目录结构** PASCAL VOC数据集的标准结构如下(以`VOC2007`为例): ``` VOCdevkit2007/ └── VOC2007/ ├── Annotations/ # 存放所有XML标注文件(如000001.xml) ├── ImageSets/ │ └── Main/ # 存放train.txt、test.txt等 └── JPEGImages/ # 存放所有训练图像 ``` 需检查: 1. `Annotations/`目录下是否包含所有XML文件(如用户报错中的`000001.xml`)[^2]。 2. `ImageSets/Main/`目录下是否生成`train.txt`,且内容为图像ID(如`000001`、`000002`等)。 --- #### **步骤2:配置代码中的路径变量** 在`faster-rcnn-pytorch`项目中,需修改以下关键路径(以`pascal_voc.py`或`train_net.py`为例): ```python # 示例路径配置 data_dir = '/home/user/data/VOCdevkit2007' # 数据集根目录 ann_dir = os.path.join(data_dir, 'VOC2007', 'Annotations') # XML文件路径 img_dir = os.path.join(data_dir, 'VOC2007', 'JPEGImages') # 图像路径 split_file = os.path.join(data_dir, 'VOC2007', 'ImageSets', 'Main', 'train.txt') # train.txt路径 ``` 需确保: - `data_dir`与实际数据集路径完全一致。 - 使用`os.path.join`避免操作系统路径分隔符差异。 --- #### **步骤3:生成train.txt的正确方法** 如果`train.txt`缺失或格式错误,可通过以下脚本生成: ```python import os data_root = '/home/heisenberg/tf-faster-rcnn/data/VOCdevkit2007/VOC2007' image_ids = sorted([f.split('.')[0] for f in os.listdir(os.path.join(data_root, 'Annotations'))]) with open(os.path.join(data_root, 'ImageSets/Main/train.txt'), 'w') as f: for img_id in image_ids: f.write(img_id + '\n') ``` 需验证生成的文件路径是否与代码中`split_file`的路径匹配[^1]。 --- #### **步骤4:检查文件权限和绝对路径** 1. **权限问题**:确保用户对数据集目录有读写权限: ```bash chmod -R 755 /home/heisenberg/tf-faster-rcnn/data/VOCdevkit2007 ``` 2. **绝对路径调试**:临时将代码中的路径改为绝对路径,验证是否解决问题。 --- #### **常见错误场景** - **错误1**:`FileNotFoundError: '000001.xml'` **原因**:`train.txt`中的ID在`Annotations/`目录下无对应XML文件。 **解决**:检查XML文件名是否与ID一致,或重新生成`train.txt`。 - **错误2**:`No such file or directory: 'train.txt'` **原因**:`ImageSets/Main/`目录下缺少`train.txt`。 **解决**:运行步骤3的脚本生成文件。 --- #### **扩展建议** - 使用`os.path.exists()`在代码中添加路径检查: ```python if not os.path.exists(split_file): raise ValueError(f"{split_file} 不存在,请检查路径配置") ``` - 参考官方文档:[faster-rcnn.pytorch数据准备指南](https://github.com/jwyang/faster-rcnn.pytorch) ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值