在spark 2.3中从多个分区中的hdfs读取图像

r8xiu3jd  于 2021-05-27  发布在  Spark
关注(0)|答案(0)|浏览(289)

我正在尝试阅读成千上万的小图片来实现一个机器学习项目,这个项目在一个hdfs上运行spark2.3.3。我不能使用内置的图像数据源,因为它是从2.4版本引入的,而且考虑到提取特征向量所需的内存总权重,我不希望所有内容都由单个执行器读取,但是在转移到训练和测试部分之前,我想在所有可用的执行器之间划分工作。
所以我在本地机器上尝试的方法是:
这个 binaryFiles(path, numPartitions) 方法,但正如这里在stackoverflow上所讨论的 numPartitions 参数在代码中被忽略,仅在版本2.4中修复。很明显,这意味着大量的阅读时间
这个 readImages 方法,但也似乎忽视了这一点 numPartitions 争论。在查看其代码实现之后,它调用 binaryFiles 方法,所以在本例中,我最终只有一个分区,并使用 repartition 函数总是以某个垃圾收集器异常结束
最有效的是 wholeTextFiles(path, numPartitions) ,它甚至按我的要求在分区中分发图像,但显然它返回成对的字符串,其中第一个是文件名,第二个是内容。如果我能转换内容就太好了 String 回到bufferedimage。我也试过了 String.getBytes 但既然我不知道怎么做 wholeTextFiles 处理“非文本”文件以及它如何以字符串的方式转换它们,实际上我无法反转整个操作
另外,改变 spark.default.parallelism 设置没有帮助。
最后,我尝试的(仍然是本地)是这样的:

//List images paths from the given directory
val files = new File(args(0)).list.toList

val rdd = sparkcontext.parallelize(files)
    //Distribute the list to the executors (currently just for testing they are 4)
    .repartition(4)
    //Map the image name to a BufferedImage, and then return a LabeledPoint containing the feature vector
    .map{
        case (fileName: String) => {
            var label = getLabel(fileName)
            //getFeatures extracts the feature vector from the pixels of the BufferedImage
            new LabeledPoint(label, getFeatures(ImageIO.read(new File(fileName))))
        }
    }

//...

实际上效果很好,我甚至可以继续机器学习部分。但在集群方面,这是行不通的,因为它使用了hadoop fs,所以 java.io.File 上课不合适。
因为这是我第一次使用spark,所以我现在被卡住了,我不知道我的方法是否正确。你有什么建议吗?有没有更好的内置方法我错过了?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题