【问题标题】:Pure Java/Scala code for writing Tensorflow TFRecords data file用于编写 Tensorflow TFRecords 数据文件的纯 Java/Scala 代码
【发布时间】:2016-01-10 21:58:55
【问题描述】:

我正在尝试编写 Tensorflow RecordWriter 类的纯 Java/Scala 实现,以便将 Spark DataFrame 转换为 TFRecords 文件。根据文档,在 TFRecords 中,每条记录的格式如下:

uint64 length
uint32 masked_crc32_of_length
byte   data[length]
uint32 masked_crc32_of_data

还有 CRC 掩码

masked_crc = ((crc >> 15) | (crc << 17)) + 0xa282ead8ul

目前,我使用以下代码使用番石榴实现计算 CRC:

import com.google.common.hash.Hashing

object CRC32 {
  val kMaskDelta = 0xa282ead8

  def hash(in: Array[Byte]): Int = {
    val hashing = Hashing.crc32c()
    hashing.hashBytes(in).asInt()
  }

  def mask(crc: Int): Int ={
    ((crc >> 15) | (crc << 17)) + kMaskDelta
  }
}

我的其余代码是:

数据编码部分由以下代码完成:

  object LittleEndianEncoding {
   def encodeLong(in: Long): Array[Byte] = {
    val baos = new ByteArrayOutputStream()
    val out = new LittleEndianDataOutputStream(baos)
    out.writeLong(in)
    baos.toByteArray
  }

  def encodeInt(in: Int): Array[Byte] = {
    val baos = new ByteArrayOutputStream()
    val out = new LittleEndianDataOutputStream(baos)

    out.writeInt(in)
    baos.toByteArray
  }
}

记录是使用协议缓冲区生成的:

import com.google.protobuf.ByteString
import org.tensorflow.example._

import collection.JavaConversions._
import collection.mutable._

object TFRecord {

  def int64Feature(in: Long): Feature = {

    val valueBuilder = Int64List.newBuilder()
    valueBuilder.addValue(in)

    Feature.newBuilder()
      .setInt64List(valueBuilder.build())
      .build()
  }


  def floatFeature(in: Float): Feature = {
    val valueBuilder = FloatList.newBuilder()
    valueBuilder.addValue(in)
    Feature.newBuilder()
      .setFloatList(valueBuilder.build())
      .build()
  }

  def floatVectorFeature(in: Array[Float]): Feature = {
    val valueBuilder = FloatList.newBuilder()
    in.foreach(valueBuilder.addValue)

    Feature.newBuilder()
      .setFloatList(valueBuilder.build())
      .build()
  }

  def bytesFeature(in: Array[Byte]): Feature = {
    val valueBuilder = BytesList.newBuilder()
    valueBuilder.addValue(ByteString.copyFrom(in))
    Feature.newBuilder()
      .setBytesList(valueBuilder.build())
      .build()
  }

  def makeFeatures(features: HashMap[String, Feature]): Features = {
    Features.newBuilder().putAllFeature(features).build()
  }


  def makeExample(features: Features): Example = {
    Example.newBuilder().setFeatures(features).build()
  }

}

下面是一个示例,说明我如何一起使用这些东西来生成我的 TFRecords 文件:

val label = TFRecord.int64Feature(1)
val feature = TFRecord.floatVectorFeature(Array[Float](1, 2, 3, 4))
val features = TFRecord.makeFeatures(HashMap[String, Feature]  ("feature"->feature, "label"-> label))
val ex = TFRecord.makeExample(features)
val exSerialized = ex.toByteArray()
val length = LittleEndianEncoding.encodeLong(exSerialized.length)
val crcLength =  LittleEndianEncoding.encodeInt(CRC32.mask(CRC32.hash(length)))
val crcEx = LittleEndianEncoding.encodeInt(CRC32.mask(CRC32.hash(exSerialized)))

val out = new FileOutputStream(new File("test.tfrecords"))
out.write(length)
out.write(crcLength)
out.write(exSerialized)
out.write(crcEx)
out.close()

当我尝试使用 TFRecordReader 读取我在 Tensorflow 中获得的文件时,我收到以下错误:

W tensorflow/core/common_runtime/executor.cc:1076] 0x24cc430 Compute status: Data loss: corrupted record at 0

我怀疑 CRC 掩码计算不正确或字节序不正确 java和c++生成的文件不一样。

【问题讨论】:

  • 您收到的错误消息在哪里?
  • 当我在 tensorflow 中读取文件时,出现数据损坏错误。
  • masked_crc = ((crc &gt;&gt; 15) | (crc &lt;&lt; 17)) + 0xa282ead8ul得到的结果相比,掩码函数不正确
  • 您需要发布更多详细信息以便我们为您提供帮助。请编辑您的问题并发布错误消息以及允许我们重新生成相同错误的代码部分。我相信这里的一些人可以直接回答这个问题,但如果他们从你的情况中吸取教训,这将对其他人有所帮助。
  • 我设法解决了这个问题。错误在掩码函数中。正确的掩码函数是 masked_crc = ((crc &gt;&gt;&gt; 15) | (crc &lt;&lt; 17)) + 0xa282ead8 即使用 &gt;&gt;&gt; 无符号运算符而不是 &gt;&gt;

标签: java scala apache-spark guava tensorflow


【解决方案1】:

FWIW,Tensorflow 团队提供了用于读写 TFRecords 的实用代码,可以是found in the ecosystem repo

【讨论】:

    【解决方案2】:

    我的实现的问题是 CRC 掩码的计算。这是修复我发现的问题:

    def mask(crc: Int): Int ={
        ((crc >>> 15) | (crc << 17)) + kMaskDelta
    }
    

    关键是使用无符号移位按位运算符&gt;&gt;&gt;而不是&gt;&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 2012-05-09
      • 1970-01-01
      • 2016-06-21
      • 2018-09-28
      • 2012-07-07
      相关资源
      最近更新 更多