CODE:基于深度神经网络的鱼的分割

目标:完成水下鱼类分割

使用的网络:

mpnet:Learning Motion Patterns in Videos 

paper & code: http://thoth.inrialpes.fr/research/mpnet

DeepLabV2(ResNet-101):code: https://github.com/DrSleep/tensorflow-deeplab-resnet

前言:使用了一款记笔记的软件,幕布,风格极简,但保存代码还是差了一点。

另外这几天的鼓捣,经常上网上查资料,发现将自己遇到的问题和解决方法记录下来,

以后再遇到好解决,还可以帮助别人。

正文:

首先是mpnet的实现

一 torch的安装

网址:百度下torch就出来了,itorch也是,安装之前先看看为下边这两段话。

预训练使用的数据集非常大,论文使用的显卡计算能力非常强大,我这里资源有限,所以使用预训练好的模型就可以了。

整个代码都是用lua语言写的,所以先安装torch,为方便调试使用了itorch;刚开始显卡不给力,出现以下的错误

THCudaCheck FAIL file=/home/nvidia/torch/extra/cunn/lib/THCUNN/generic/SpatialUpSamplingBilinear.cu line=63 error=7 : too many resources requested for launch
/home/nvidia/torch/install/bin/luajit: ...e/nvidia/torch/install/share/lua/5.1/threads/threads.lua:179: [thread 1 endcallback] /home/nvidia/torch/install/share/lua/5.1/nn/Container.lua:67:

好像是显卡的线程数不够了,

参考:https://stackoverflow.com/questions/26201172/cuda-too-many-resources-requested-for-launch

就换了一款自带牛x显卡(TITAN Black,作图像处理,还没听说有人用这个。。。。)的电脑,重新安装了torch,导入模型时发现了一个问题,模型导入过程中,出现out of memory,使用itorch一句一句的排查才发现是模型导入的问题,之前以为是数据的batch太大,后来为把batch设置成1,还是out of memory(其实不需要一句一句的查,看错误位置就可以了,但是不敢相信模型还能大到这种程度),就去网上查了查。

网址http://blog.csdn.net/ycz28/article/details/52300267

关于luaJIT内存限制的说法很多,很多人说lutJIT不如lua5.2好用,所以就卸载了luaJIT,使用了lua5.2,如何将当前JIT替换为lua网址:https://github.com/torch/distro 

注意clean.sh后要重新安装依赖,即install-deps

网慢的话,OpenBLAS装不上

二 修改部分程序

首先是训练集的输入路径

修改mpnet/from_batch_angle.lua文件下的load_dataset 函数

function load_dataset(frameListFile)--输入应该是'trainList.txt',类似训练集图片索引的文件
    local file = io.open("/trainList.txt的上级路径/" .. frameListFile)

    local trainList = {}
    if file then
        for line in file:lines() do
            table.insert(trainList, line)
        end
    else
        print('File not found')
    end

    order = torch.randperm(#trainList)--打乱训练集中数据的顺序

    return trainList
end

修改同一文件下的get_batch函数

count = 1;
order = 0;

function get_batch(batch_size)
    local batch_ims = torch.Tensor(batch_size, 2, 200, 360)--通道数是2,因为光流计算会输出一个角度图,和一个幅度图
    local batch_labels = torch.Tensor(batch_size, 1, 100, 180)

    for i = 1, batch_size do

        local flowPath, path;
        local f = io.open(trainList[count], "r")
        repeat--删掉了repeat这段代码,没啥用,浪费时间
            path = trainList[order[count]]

            flowPath = string.gsub(path, 'motion_labels', 'flow_angles_no_artifacts');
            flowPath = string.gsub(flowPath, 'png', 'jpg');
            local flowAnglePath = string.gsub(flowPath, 'left/', 'left/angleField_')
            flowAnglePath = string.gsub(flowAnglePath, 'right/', 'right/angleField_')

            if f then
                io.close(f)
            end
            f = io.open(flowAnglePath, "r")

            count = count + 1;
            if count > #trainList then
                count = 1
                order = torch.randperm(#trainList)
            end
        until f
        io.close(f)
--以下代码中的路径只要保证和自己数据集下路径一致就可以了,不了解的地方可以参考test_DAVIS.lua
        local labels = image.load(path)
        local flowAnglePath = string.gsub(flowPath, 'left/', 'left/angleField_')
        flowAnglePath = string.gsub(flowAnglePath, 'right/', 'right/angleField_')
        local flowAngle = image.load(flowAnglePath)
        local flowMagPath = string.gsub(flowPath, 'left/', 'left/magField_')
        flowMagPath = string.gsub(flowMagPath, 'right/', 'right/magField_')
        local flowMag = image.load(flowMagPath)

        local flow = torch.cat(flowAngle, flowMag, 1)

        local minMaxPath = string.gsub(flowPath, '%d+.jpg', 'minmax.txt')

        local file = io.open(minMaxPath)
        local minmaxes = {}
        local ind = 1
        if file then
            for line in file:lines() do
                local min_x, max_x, min_y, max_y = unpack(line:split(" "))
                minmaxes[ind]  = {min_x, max_x, min_y, max_y}
                ind = ind + 1
            end
        else
            print('File not found!!!!!!!!')
        end
        io.close(file)

        local frameIndStart, frameIndEnd = string.find(path, '%d+.png')
        local frameInd = tonumber(path:sub(frameIndStart, frameIndEnd - 4)) - 5

        local mm = minmaxes[frameInd]
        if not mm then
            print(path)
        end

        flow = image.scale(flow, 480, 270, 'simple')
        labels = image.scale(labels, 480, 270, 'simple')

        flow[{{1}, {}, {}}] = flow[{{1}, {}, {}}] * (mm[2] - mm[1]) + mm[1]
        flow[{{2}, {}, {}}] = flow[{{2}, {}, {}}] * (mm[4] - mm[3]) + mm[3]

        flow[{{2}, {}, {}}]:div(math.sqrt(math.pow(960, 2) + math.pow(540, 2)) / 6)--图像的维度


        local h1 = math.ceil(torch.uniform(1e-2, 270 - 200))
        local w1 = math.ceil(torch.uniform(1e-2, 480 - 360))
        flow = flow[{{}, {h1, h1 + 200 - 1}, {w1, w1 + 360 - 1}}]
        labels = labels[{{}, {h1, h1 + 200 - 1}, {w1, w1 + 360 - 1}}]

        if math.random() > 0.5 then
            flow = image.flip(flow:contiguous(), 3);
            labels = image.flip(labels:contiguous(), 3);
        end

        labels = image.scale(labels, 180, 100, 'simple')

        batch_ims[i] = flow
        batch_labels[i] = labels
    end

    return batch_ims, batch_labels

end

修改segment_FT3D_angle.lua及test_DAVIS.lua函数里的路径
require 'image'
require 'lfs'
require 'cunn'
require 'nngraph'

function segment(model, rgbPath, setting)
    local flowPath = string.gsub(rgbPath, 'JPEGImages', 'OpticalFlow');--修改路径

    local fileName = string.gsub(flowPath, '%d+.jpg', 'minmax.txt')
    local file = io.open(fileName)
    local minmaxes = {}
    local ind = 1;
    if file then
        for line in file:lines() do
            local min_x, max_x, min_y, max_y = unpack(line:split(" "))
            minmaxes[ind]  = {min_x, max_x, min_y, max_y}
            ind = ind + 1
        end
    else
        print('File not found!!!!!!!!')
    end
    io.close(file)

    local resized_width = 424
    local resized_height = 232
    local batch = torch.Tensor(1, 2, resized_height, resized_width);

    local frameNum = tonumber(flowPath:match('(%d+).jpg')) + 1
    local mm = minmaxes[frameNum]
    local angleFileName = string.gsub(flowPath, '(%d+).jpg', 'angleField_%1.jpg');
    local magFileName = string.gsub(flowPath, '(%d+).jpg', 'magField_%1.jpg');

    local f = io.open(angleFileName, "r")
    if not f then
        return nil
    end
    io.close(f)

    local flowAngle = image.load(angleFileName)
    local flowMag = image.load(magFileName)

    local flowFrame = torch.cat(flowAngle, flowMag, 1)
    flowFrame = image.scale(flowFrame, resized_width, resized_height, 'simple');

    flowFrame[{{1}, {}, {}}] = flowFrame[{{1}, {}, {}}] * (mm[2] - mm[1]) + mm[1]
    flowFrame[{{2}, {}, {}}] = flowFrame[{{2}, {}, {}}] * (mm[4] - mm[3]) + mm[3]

    flowFrame[{{1}, {}, {}}]:cmul(flowFrame[{{2}, {}, {}}]:gt(1):double())

    flowFrame[{{2}, {}, {}}]:div(math.sqrt(math.pow(854, 2) + math.pow(480, 2)) / 6)

    batch[1] = flowFrame;

    batch = batch:float():cuda()

    local outputs = model:forward(batch)

    local objPath = string.gsub(rgbPath, 'JPEGImages', 'Objectness100');
    objPath = string.gsub(objPath, '(%d+).jpg', '%1.png');
    local objectness = image.load(objPath)

    local preds
    preds = torch.Tensor(1, 480, 854)
    local pred = outputs[1];
    pred = nn.utils.recursiveType(pred, 'torch.DoubleTensor')
    pred = image.scale(pred, 854, 480)

    local predRaw = pred
    objectness:div(objectness:max()):add(0.5)
    pred:cmul(objectness)
    pred:clamp(0, 1)

    preds[1] = pred

    local resultPath = string.gsub(rgbPath, 'JPEGImages', 'Results/Segmentations');
    local resultPath = string.gsub(resultPath, '480p', '480p/' .. setting);
    local resultPath = string.gsub(resultPath, 'jpg', 'png');
    local resultDir = string.gsub(resultPath, '%d+.png', '');
    if not path.exists(resultDir) then
        os.execute("mkdir " .. resultDir)
    end
    image.save(resultPath, torch.round(preds));
    local resultPathRaw = string.gsub(resultPath, '(%d+).png', 'raw_%1.png');
    image.save(resultPathRaw, predRaw);
end


猜你喜欢

转载自blog.csdn.net/biulibiuli/article/details/79581105