开始使用我自己的数据集启动 google-cloud-ml
Get started to launch google-cloud-ml with my own dataset
我成功执行了所有步骤of the online tutorial for google cloud ml。
但是由于本教程中使用的数据集已经是 TFRecord,所以我不太了解如何将我的 numpy 数据集转换为 TFRecord。
然后,我尝试使用 this a little bit modified code compared to the official convert_to_records.py 创建我的 TFRecord。我的理解是我们只能将原始变量转换为 TFRecord,这就是为什么使用将浮点列表转换为字节的技巧。
然后我必须在某个地方将我的字符串转换回浮点数列表。因此,我尝试使用第 97 行或第 98 行 in my modified script model.py.
来执行此任务
不幸的是,none 这些尝试都奏效了。我总是收到以下错误消息:
ValueError: rank of shape must be at least 2 not: 1
这是因为我的变量 features 的形状是 (batch_size,) 而不是 (batch_size, IMAGE_PIXELS)。但是我不明白为什么。
我是否尝试以错误的方式启动 google-cloud-ml,或者是否有更多参数需要调整?
在您的 model.py
中分析 read_data_sets.py 和 parse_example 操作的输出可能会有所帮助
read_data_sets 产生什么
read_data_sets, as you point out, creates numpy arrays for each image. They have shape [28, 28, 1] for height x width x channels (the images are monochrome) and in your original call to read_data_sets, you were specifying that you wanted the image data as uint8 arrays. When you call tostring 在 uint8 numpy 数组上,形状信息被丢弃,因为每个 uint8 都是一个字节,你最终得到一个长度为 784 的字节字符串,原始 28x28x1 中的每个像素都有一个条目行优先顺序的 numpy 数组。然后将其作为 bytes_list
存储在结果 tf.train.Example
.
中
回顾一下,features
键下的特征映射中的每个条目都有一个字节列表,其中只有一个条目。该条目是一个长度为 784 的字符串,其中字符串中的每个 'character' 都是 0-255 之间的值,表示原始 28x28 图像中某个点的单色像素值。以下是 Python 打印的 tf.train.Example
的示例实例:
features {
feature {
key: "features"
value {
bytes_list {
value: "[=10=]0[=10=]07..."
}
}
}
feature {
key: "labels"
value {
int64_list {
value: 10
}
}
}
}
parse_example 期望和 returns
tf.parse_example 接受 tf.string
个对象的向量作为输入。这些对象是序列化的 tf.train.Example
个对象。在您的代码中,util.read_examples
产生的正是那个。
tf.parse_example
的另一个参数是示例的架构。如前所述,示例中的 features
条目是上面定义的 tf.string
。作为参考,您的代码具有:
def parse_examples(examples):
feature_map = {
'labels': tf.FixedLenFeature(
shape=[], dtype=tf.int64, default_value=[-1]),
'features': tf.FixedLenFeature(
shape=[], dtype=tf.string),
}
return tf.parse_example(examples, features=feature_map)
与您收到的错误消息相关的有趣的事情是形状参数。该形状参数指定 单个实例 的形状,在这种情况下,通过指定 shape=[]
你是说每个图像都是一个 rank-0 字符串,也就是说,一个普通的字符串(即,不是向量,不是矩阵等)。这要求 bytes_list
恰好有一个元素。这正是您在 tf.train.Example
.
的每个 features
字段中存储的内容
即使 shape
属性 指的是单个实例的形状, tf.parse_example
对于 features
字段的输出将是整个 batch 个示例。这可能有点令人困惑。因此,虽然每个单独的示例都有一个字符串 (shape=[]
),但批处理是一个字符串向量 (shape=[batch_size]
)。
使用图像
将图像数据保存在字符串中不是很有用;我们需要将其转换回数字数据。执行此操作的 TensorFlow 操作是 tf.decode_raw (Jeremy Lewi 为什么 tf.string_to_number
在这里不起作用):
image_bytes = tf.decode_raw(parsed['features'], out_type=tf.uint8)
image_data = tf.cast(image_bytes, tf.float32)
(请务必设置 out_type=tf.uint8
,因为那是 read_data_sets
中输出的数据类型)。通常,您会希望将结果转换为 tf.float32
。有时重塑张量以恢复原始形状甚至很有用,例如
# New shape is [batch_size, height, width, channels]. We use
# -1 as the first dimension in case batches are variable size.
image_data = tf.reshape(image_data, [-1, 28, 28, 1])
(注意:您的代码中可能不需要它)。
或者,您可以通过使用 dtype=tf.float32
(默认设置)调用 read_data_sets
将数据存储为 tf.float32。然后你可以将你的 tf.train.Example
构造为 Jeremy Lewi 的 ,他还提供了解析此类示例的代码。然而,在那种情况下形状将不同。每个实例的形状(如 FixedLenFeature 中的形状所示)现在为 IMAGE_PIXELS
,tf.parsed_example
输出中 features
条目的形状为 [batch_size, IMAGE_PIXELS]
。
当然,uint8
和 float32
之间的权衡是磁盘上的数据大约是后者的四倍,但是您避免了前者所需的额外转换.在没有太多数据的 MNIST 的情况下,直接处理浮点数据的额外清晰度可能值得额外 space.
该错误表明应为等级 2(矩阵),但该值实际上为等级 1(向量)。我怀疑这是因为 np.tostring() returns 是单个字符串而不是字符串列表。
我认为这有点离题,因为我认为您的浮点数到字符串和字符串到浮点数的转换不一致。您可以使用 numpy 的内置 tostring() 方法将浮点数转换为字符串。即returns数据的字节表示:即
import numpy as np
x = np.array([1.0, 2.0])
print x.tostring()
Returns
�?@
而不是
['1.0', '2.0']
后者是tf.string_to_number所期望的。
您可以使浮点到字符串和字符串到浮点的转换保持一致,但我认为更好的解决方案是只将数据表示为浮点数。例如:
def _int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=value))
def _float_feature(value):
return tf.train.Feature(float_list=tf.train.FloatList(value=value))
e = tf.train.Example(features=tf.train.Features(feature={
'labels': _int64_feature([10]),
'features': _float_feature([100.0, 200, ....])}))
feature_map = {
'labels': tf.FixedLenFeature(
shape=[1], dtype=tf.int64, default_value=[-1]),
'features': tf.FixedLenFeature(
shape=[NUM_PIXELS], dtype=tf.float32),
}
result = tf.parse_example([e.SerializeToString()], features=feature_map)
A Feature proto 允许将 float32 存储在 float_list 中。如果您使用的是 float64,则只需将浮点数转换为字节。您的数据是 float32,所以这是不必要的。
我成功执行了所有步骤of the online tutorial for google cloud ml。
但是由于本教程中使用的数据集已经是 TFRecord,所以我不太了解如何将我的 numpy 数据集转换为 TFRecord。
然后,我尝试使用 this a little bit modified code compared to the official convert_to_records.py 创建我的 TFRecord。我的理解是我们只能将原始变量转换为 TFRecord,这就是为什么使用将浮点列表转换为字节的技巧。 然后我必须在某个地方将我的字符串转换回浮点数列表。因此,我尝试使用第 97 行或第 98 行 in my modified script model.py.
来执行此任务不幸的是,none 这些尝试都奏效了。我总是收到以下错误消息:
ValueError: rank of shape must be at least 2 not: 1
这是因为我的变量 features 的形状是 (batch_size,) 而不是 (batch_size, IMAGE_PIXELS)。但是我不明白为什么。
我是否尝试以错误的方式启动 google-cloud-ml,或者是否有更多参数需要调整?
在您的 model.py
中分析 read_data_sets.py 和 parse_example 操作的输出可能会有所帮助read_data_sets 产生什么
read_data_sets, as you point out, creates numpy arrays for each image. They have shape [28, 28, 1] for height x width x channels (the images are monochrome) and in your original call to read_data_sets, you were specifying that you wanted the image data as uint8 arrays. When you call tostring 在 uint8 numpy 数组上,形状信息被丢弃,因为每个 uint8 都是一个字节,你最终得到一个长度为 784 的字节字符串,原始 28x28x1 中的每个像素都有一个条目行优先顺序的 numpy 数组。然后将其作为 bytes_list
存储在结果 tf.train.Example
.
回顾一下,features
键下的特征映射中的每个条目都有一个字节列表,其中只有一个条目。该条目是一个长度为 784 的字符串,其中字符串中的每个 'character' 都是 0-255 之间的值,表示原始 28x28 图像中某个点的单色像素值。以下是 Python 打印的 tf.train.Example
的示例实例:
features {
feature {
key: "features"
value {
bytes_list {
value: "[=10=]0[=10=]07..."
}
}
}
feature {
key: "labels"
value {
int64_list {
value: 10
}
}
}
}
parse_example 期望和 returns
tf.parse_example 接受 tf.string
个对象的向量作为输入。这些对象是序列化的 tf.train.Example
个对象。在您的代码中,util.read_examples
产生的正是那个。
tf.parse_example
的另一个参数是示例的架构。如前所述,示例中的 features
条目是上面定义的 tf.string
。作为参考,您的代码具有:
def parse_examples(examples):
feature_map = {
'labels': tf.FixedLenFeature(
shape=[], dtype=tf.int64, default_value=[-1]),
'features': tf.FixedLenFeature(
shape=[], dtype=tf.string),
}
return tf.parse_example(examples, features=feature_map)
与您收到的错误消息相关的有趣的事情是形状参数。该形状参数指定 单个实例 的形状,在这种情况下,通过指定 shape=[]
你是说每个图像都是一个 rank-0 字符串,也就是说,一个普通的字符串(即,不是向量,不是矩阵等)。这要求 bytes_list
恰好有一个元素。这正是您在 tf.train.Example
.
features
字段中存储的内容
即使 shape
属性 指的是单个实例的形状, tf.parse_example
对于 features
字段的输出将是整个 batch 个示例。这可能有点令人困惑。因此,虽然每个单独的示例都有一个字符串 (shape=[]
),但批处理是一个字符串向量 (shape=[batch_size]
)。
使用图像
将图像数据保存在字符串中不是很有用;我们需要将其转换回数字数据。执行此操作的 TensorFlow 操作是 tf.decode_raw (Jeremy Lewi tf.string_to_number
在这里不起作用):
image_bytes = tf.decode_raw(parsed['features'], out_type=tf.uint8)
image_data = tf.cast(image_bytes, tf.float32)
(请务必设置 out_type=tf.uint8
,因为那是 read_data_sets
中输出的数据类型)。通常,您会希望将结果转换为 tf.float32
。有时重塑张量以恢复原始形状甚至很有用,例如
# New shape is [batch_size, height, width, channels]. We use
# -1 as the first dimension in case batches are variable size.
image_data = tf.reshape(image_data, [-1, 28, 28, 1])
(注意:您的代码中可能不需要它)。
或者,您可以通过使用 dtype=tf.float32
(默认设置)调用 read_data_sets
将数据存储为 tf.float32。然后你可以将你的 tf.train.Example
构造为 Jeremy Lewi 的 IMAGE_PIXELS
,tf.parsed_example
输出中 features
条目的形状为 [batch_size, IMAGE_PIXELS]
。
当然,uint8
和 float32
之间的权衡是磁盘上的数据大约是后者的四倍,但是您避免了前者所需的额外转换.在没有太多数据的 MNIST 的情况下,直接处理浮点数据的额外清晰度可能值得额外 space.
该错误表明应为等级 2(矩阵),但该值实际上为等级 1(向量)。我怀疑这是因为 np.tostring() returns 是单个字符串而不是字符串列表。
我认为这有点离题,因为我认为您的浮点数到字符串和字符串到浮点数的转换不一致。您可以使用 numpy 的内置 tostring() 方法将浮点数转换为字符串。即returns数据的字节表示:即
import numpy as np
x = np.array([1.0, 2.0])
print x.tostring()
Returns
�?@
而不是
['1.0', '2.0']
后者是tf.string_to_number所期望的。
您可以使浮点到字符串和字符串到浮点的转换保持一致,但我认为更好的解决方案是只将数据表示为浮点数。例如:
def _int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=value))
def _float_feature(value):
return tf.train.Feature(float_list=tf.train.FloatList(value=value))
e = tf.train.Example(features=tf.train.Features(feature={
'labels': _int64_feature([10]),
'features': _float_feature([100.0, 200, ....])}))
feature_map = {
'labels': tf.FixedLenFeature(
shape=[1], dtype=tf.int64, default_value=[-1]),
'features': tf.FixedLenFeature(
shape=[NUM_PIXELS], dtype=tf.float32),
}
result = tf.parse_example([e.SerializeToString()], features=feature_map)
A Feature proto 允许将 float32 存储在 float_list 中。如果您使用的是 float64,则只需将浮点数转换为字节。您的数据是 float32,所以这是不必要的。