首页 Paddle框架 帖子详情
自定义图片训练集,2万张图片可以正常运行,但是4万张图片就会报OOM错误,求提供自定义数据集的官方demo
收藏
快速回复
Paddle框架 问答深度学习模型训练 1065 2
自定义图片训练集,2万张图片可以正常运行,但是4万张图片就会报OOM错误,求提供自定义数据集的官方demo
收藏
快速回复
Paddle框架 问答深度学习模型训练 1065 2

为使您的问题得到快速解决,在建立Issues前,请您先通过如下方式搜索是否有相似问题:【搜索issue关键字】【使用labels筛选】【官方文档】

如果您没有查询到相似问题,为快速解决您的提问,建立issue时请提供如下细节信息:

  • 标题:简洁、精准概括您的问题,例如“Insufficient Memory xxx" ”
  • 版本、环境信息:
       1)PaddlePaddle版本:1.6
       2)CPU:
       3)GPU:NVIDIA Tesla P100 16GB
       4)系统环境:Centos7.6,Python 3.6.6
  • 训练信息
       1)单机单卡
       2)显存信息
       3)Operator信息
  • 复现信息:如为报错,请给出复现环境、复现步骤
  • 问题描述:请详细描述您的问题,同步贴出报错信息、日志、可复现的代码片段
    我们研发用2万张图片作为训练集,训练代码正常访问,但是用4万张图片作为训练集,同样的训练代码就会报内存溢出的错误,这个是我们数据读取的方法有什么问题吗,有没有相应的文档可以解决这个问题呢?

获取自定义数据的代码段

mydatareader = reader.train_reader('images/train.list', crop_size, resize_size)
train_reader = paddle.batch(reader=paddle.reader.shuffle(reader=mydatareader,buf_size=50000),batch_size=64)

test_datareader = reader.train_reader('images/test.list', crop_size, resize_size)
test_reader = paddle.batch(reader=paddle.reader.shuffle(reader=test_datareader,buf_size=50000),batch_size=64)

尝试过将buf_size改为更小的,但是仅仅能多训练几轮,然后依旧会报内存溢出错误。

#train关键代码

# 获取损失函数和准确率函数
cost = fluid.layers.cross_entropy(input=model, label=label)
avg_cost = fluid.layers.mean(cost)
acc = fluid.layers.accuracy(input=model, label=label)

# 获取训练和测试程序
test_program = fluid.default_main_program().clone(for_test=True)

# 定义优化方法
optimizer = fluid.optimizer.AdamOptimizer(learning_rate=1e-3,
                                          regularization=fluid.regularizer.L2DecayRegularizer(1e-4))
opts = optimizer.minimize(avg_cost)

# 获取自定义数据
# train_reader = paddle.batch(reader=reader.train_reader('images/train.list', crop_size, resize_size), batch_size=32)
# test_reader = paddle.batch(reader=reader.test_reader('images/test.list', crop_size), batch_size=32)

train_datareader = reader.train_reader('images/train.list', crop_size, resize_size)
train_reader = paddle.batch(reader=paddle.reader.shuffle(reader=train_datareader,buf_size=50000),batch_size=64)

test_datareader = reader.train_reader('images/test.list', crop_size, resize_size)
test_reader = paddle.batch(reader=paddle.reader.shuffle(reader=test_datareader,buf_size=50000),batch_size=64)


# 定义一个使用GPU的执行器
place = fluid.CUDAPlace(0)
# place = fluid.CPUPlace()

exe = fluid.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())

# 定义输入数据维度
feeder = fluid.DataFeeder(place=place, feed_list=[image, label])

# 训练10次
for pass_id in range(10):
    # 进行训练
    for batch_id, data in enumerate(train_reader()):
        train_cost, train_acc = exe.run(program=fluid.default_main_program(),
                                        feed=feeder.feed(data),
                                        fetch_list=[avg_cost, acc])

        # 每100个batch打印一次信息
        if batch_id % 100 == 0:
            print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' %
                  (pass_id, batch_id, train_cost[0], train_acc[0]))

    # 进行测试
    test_accs = []
    test_costs = []
    for batch_id, data in enumerate(test_reader()):
        test_cost, test_acc = exe.run(program=test_program,
                                      feed=feeder.feed(data),
                                      fetch_list=[avg_cost, acc])
        test_accs.append(test_acc[0])
        test_costs.append(test_cost[0])
    # 求测试结果的平均值
    test_cost = (sum(test_costs) / len(test_costs))
    test_acc = (sum(test_accs) / len(test_accs))
    print('Test:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, test_cost, test_acc))

    # 保存预测模型
    save_path = 'infer_model/'
    # 删除旧的模型文件
    shutil.rmtree(save_path, ignore_errors=True)
    # 创建保持模型文件目录
    os.makedirs(save_path)
    # 保存预测模型
    fluid.io.save_inference_model(save_path, feeded_var_names=[image.name], target_vars=[model], executor=exe)

#reader关键代码

# 训练图片的预处理
def train_mapper(sample):
    img_path, label, crop_size, resize_size = sample
    try:
        img = Image.open(img_path)
        # 统一图片大小
        img = img.resize((resize_size, resize_size), Image.ANTIALIAS)
        # 随机水平翻转
        r1 = random.random()
        if r1 > 0.5:
            img = img.transpose(Image.FLIP_LEFT_RIGHT)
        # 随机垂直翻转
        r2 = random.random()
        if r2 > 0.5:
            img = img.transpose(Image.FLIP_TOP_BOTTOM)
        # 随机角度翻转
        r3 = random.randint(-3, 3)
        img = img.rotate(r3, expand=False)
        # 随机裁剪
        r4 = random.randint(0, int(resize_size - crop_size))
        r5 = random.randint(0, int(resize_size - crop_size))
        box = (r4, r5, r4 + crop_size, r5 + crop_size)
        img = img.crop(box)
        # 把图片转换成numpy值
        img = np.array(img).astype(np.float32)
        # 转换成CHW
        img = img.transpose((2, 0, 1))
        # 转换成BGR
        img = img[(2, 1, 0), :, :] / 255.0
        return img, int(label)
    except:
        print("%s 该图片错误,请删除该图片并重新创建图像数据列表" % img_path)


# 获取训练的reader
def train_reader(train_list_path, crop_size, resize_size):
    father_path = os.path.dirname(train_list_path)

    def reader():
        with open(train_list_path, 'r') as f:
            lines = f.readlines()
            # 打乱图像列表
            np.random.shuffle(lines)
            # 开始获取每张图像和标签
            for line in lines:
                img, label = line.split('\t')
                img = os.path.join(father_path, img)
                yield img, label, crop_size, resize_size

    return paddle.reader.xmap_readers(train_mapper, reader, cpu_count(), 102400)
0
收藏
回复
全部评论(2)
时间顺序
AIStudio783231
#2 回复于2019-12

你好,
return paddle.reader.xmap_readers(train_mapper, reader, cpu_count(), 102400)
这里102400的buffer_size是否设置太大了呢,这样无论是2w还是4w图片都需要全部装入内存。
建议尝试减小buffer_size,比如设置1000

0
回复
AIStudio790026
#3 回复于2019-12

已经解决了,谢谢

0
回复
需求/bug反馈?一键提issue告诉我们
发现bug?如果您知道修复办法,欢迎提pr直接参与建设飞桨~
在@后输入用户全名并按空格结束,可艾特全站任一用户