• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #include "tensorflow/core/example/feature_util.h"
16 
17 #include <vector>
18 
19 #include "tensorflow/core/example/example.pb.h"
20 #include "tensorflow/core/platform/test.h"
21 #include "tensorflow/core/platform/types.h"
22 
23 namespace tensorflow {
24 namespace {
25 
26 const float kTolerance = 1e-5;
27 
TEST(GetFeatureValuesInt64Test,ReadsASingleValue)28 TEST(GetFeatureValuesInt64Test, ReadsASingleValue) {
29   Example example;
30   (*example.mutable_features()->mutable_feature())["tag"]
31       .mutable_int64_list()
32       ->add_value(42);
33 
34   auto tag = GetFeatureValues<protobuf_int64>("tag", example);
35 
36   ASSERT_EQ(1, tag.size());
37   EXPECT_EQ(42, tag.Get(0));
38 }
39 
TEST(GetFeatureValuesInt64Test,ReadsASingleValueFromFeature)40 TEST(GetFeatureValuesInt64Test, ReadsASingleValueFromFeature) {
41   Feature feature;
42   feature.mutable_int64_list()->add_value(42);
43 
44   auto values = GetFeatureValues<protobuf_int64>(feature);
45 
46   ASSERT_EQ(1, values.size());
47   EXPECT_EQ(42, values.Get(0));
48 }
49 
TEST(GetFeatureValuesInt64Test,WritesASingleValue)50 TEST(GetFeatureValuesInt64Test, WritesASingleValue) {
51   Example example;
52 
53   GetFeatureValues<protobuf_int64>("tag", &example)->Add(42);
54 
55   ASSERT_EQ(1,
56             example.features().feature().at("tag").int64_list().value_size());
57   EXPECT_EQ(42, example.features().feature().at("tag").int64_list().value(0));
58 }
59 
TEST(GetFeatureValuesInt64Test,WritesASingleValueToFeature)60 TEST(GetFeatureValuesInt64Test, WritesASingleValueToFeature) {
61   Feature feature;
62 
63   GetFeatureValues<protobuf_int64>(&feature)->Add(42);
64 
65   ASSERT_EQ(1, feature.int64_list().value_size());
66   EXPECT_EQ(42, feature.int64_list().value(0));
67 }
68 
TEST(GetFeatureValuesInt64Test,CheckUntypedFieldExistence)69 TEST(GetFeatureValuesInt64Test, CheckUntypedFieldExistence) {
70   Example example;
71   ASSERT_FALSE(HasFeature("tag", example));
72 
73   GetFeatureValues<protobuf_int64>("tag", &example)->Add(0);
74 
75   EXPECT_TRUE(HasFeature("tag", example));
76 }
77 
TEST(GetFeatureValuesInt64Test,CheckTypedFieldExistence)78 TEST(GetFeatureValuesInt64Test, CheckTypedFieldExistence) {
79   Example example;
80 
81   GetFeatureValues<float>("tag", &example)->Add(3.14);
82   ASSERT_FALSE(HasFeature<protobuf_int64>("tag", example));
83 
84   GetFeatureValues<protobuf_int64>("tag", &example)->Add(42);
85 
86   EXPECT_TRUE(HasFeature<protobuf_int64>("tag", example));
87   auto tag_ro = GetFeatureValues<protobuf_int64>("tag", example);
88   ASSERT_EQ(1, tag_ro.size());
89   EXPECT_EQ(42, tag_ro.Get(0));
90 }
91 
TEST(GetFeatureValuesInt64Test,CopyIterableToAField)92 TEST(GetFeatureValuesInt64Test, CopyIterableToAField) {
93   Example example;
94   std::vector<int> values{1, 2, 3};
95 
96   std::copy(values.begin(), values.end(),
97             protobuf::RepeatedFieldBackInserter(
98                 GetFeatureValues<protobuf_int64>("tag", &example)));
99 
100   auto tag_ro = GetFeatureValues<protobuf_int64>("tag", example);
101   ASSERT_EQ(3, tag_ro.size());
102   EXPECT_EQ(1, tag_ro.Get(0));
103   EXPECT_EQ(2, tag_ro.Get(1));
104   EXPECT_EQ(3, tag_ro.Get(2));
105 }
106 
TEST(GetFeatureValuesFloatTest,ReadsASingleValueFromFeature)107 TEST(GetFeatureValuesFloatTest, ReadsASingleValueFromFeature) {
108   Feature feature;
109   feature.mutable_float_list()->add_value(3.14);
110 
111   auto values = GetFeatureValues<float>(feature);
112 
113   ASSERT_EQ(1, values.size());
114   EXPECT_NEAR(3.14, values.Get(0), kTolerance);
115 }
116 
TEST(GetFeatureValuesFloatTest,ReadsASingleValue)117 TEST(GetFeatureValuesFloatTest, ReadsASingleValue) {
118   Example example;
119   (*example.mutable_features()->mutable_feature())["tag"]
120       .mutable_float_list()
121       ->add_value(3.14);
122 
123   auto tag = GetFeatureValues<float>("tag", example);
124 
125   ASSERT_EQ(1, tag.size());
126   EXPECT_NEAR(3.14, tag.Get(0), kTolerance);
127 }
128 
TEST(GetFeatureValuesFloatTest,WritesASingleValueToFeature)129 TEST(GetFeatureValuesFloatTest, WritesASingleValueToFeature) {
130   Feature feature;
131 
132   GetFeatureValues<float>(&feature)->Add(3.14);
133 
134   ASSERT_EQ(1, feature.float_list().value_size());
135   EXPECT_NEAR(3.14, feature.float_list().value(0), kTolerance);
136 }
137 
TEST(GetFeatureValuesFloatTest,WritesASingleValue)138 TEST(GetFeatureValuesFloatTest, WritesASingleValue) {
139   Example example;
140 
141   GetFeatureValues<float>("tag", &example)->Add(3.14);
142 
143   ASSERT_EQ(1,
144             example.features().feature().at("tag").float_list().value_size());
145   EXPECT_NEAR(3.14,
146               example.features().feature().at("tag").float_list().value(0),
147               kTolerance);
148 }
149 
TEST(GetFeatureValuesFloatTest,CheckTypedFieldExistence)150 TEST(GetFeatureValuesFloatTest, CheckTypedFieldExistence) {
151   Example example;
152 
153   GetFeatureValues<protobuf_int64>("tag", &example)->Add(42);
154   ASSERT_FALSE(HasFeature<float>("tag", example));
155 
156   GetFeatureValues<float>("tag", &example)->Add(3.14);
157 
158   EXPECT_TRUE(HasFeature<float>("tag", example));
159   auto tag_ro = GetFeatureValues<float>("tag", example);
160   ASSERT_EQ(1, tag_ro.size());
161   EXPECT_NEAR(3.14, tag_ro.Get(0), kTolerance);
162 }
163 
TEST(GetFeatureValuesFloatTest,CheckTypedFieldExistenceForDeprecatedMethod)164 TEST(GetFeatureValuesFloatTest, CheckTypedFieldExistenceForDeprecatedMethod) {
165   Example example;
166 
167   GetFeatureValues<protobuf_int64>("tag", &example)->Add(42);
168   ASSERT_FALSE(ExampleHasFeature<float>("tag", example));
169 
170   GetFeatureValues<float>("tag", &example)->Add(3.14);
171 
172   EXPECT_TRUE(ExampleHasFeature<float>("tag", example));
173   auto tag_ro = GetFeatureValues<float>("tag", example);
174   ASSERT_EQ(1, tag_ro.size());
175   EXPECT_NEAR(3.14, tag_ro.Get(0), kTolerance);
176 }
177 
TEST(GetFeatureValuesStringTest,ReadsASingleValueFromFeature)178 TEST(GetFeatureValuesStringTest, ReadsASingleValueFromFeature) {
179   Feature feature;
180   feature.mutable_bytes_list()->add_value("FOO");
181 
182   auto values = GetFeatureValues<string>(feature);
183 
184   ASSERT_EQ(1, values.size());
185   EXPECT_EQ("FOO", values.Get(0));
186 }
187 
TEST(GetFeatureValuesStringTest,ReadsASingleValue)188 TEST(GetFeatureValuesStringTest, ReadsASingleValue) {
189   Example example;
190   (*example.mutable_features()->mutable_feature())["tag"]
191       .mutable_bytes_list()
192       ->add_value("FOO");
193 
194   auto tag = GetFeatureValues<string>("tag", example);
195 
196   ASSERT_EQ(1, tag.size());
197   EXPECT_EQ("FOO", tag.Get(0));
198 }
199 
TEST(GetFeatureValuesStringTest,WritesASingleValueToFeature)200 TEST(GetFeatureValuesStringTest, WritesASingleValueToFeature) {
201   Feature feature;
202 
203   *GetFeatureValues<string>(&feature)->Add() = "FOO";
204 
205   ASSERT_EQ(1, feature.bytes_list().value_size());
206   EXPECT_EQ("FOO", feature.bytes_list().value(0));
207 }
208 
TEST(GetFeatureValuesStringTest,WritesASingleValue)209 TEST(GetFeatureValuesStringTest, WritesASingleValue) {
210   Example example;
211 
212   *GetFeatureValues<string>("tag", &example)->Add() = "FOO";
213 
214   ASSERT_EQ(1,
215             example.features().feature().at("tag").bytes_list().value_size());
216   EXPECT_EQ("FOO",
217             example.features().feature().at("tag").bytes_list().value(0));
218 }
219 
TEST(GetFeatureValuesStringTest,CheckTypedFieldExistence)220 TEST(GetFeatureValuesStringTest, CheckTypedFieldExistence) {
221   Example example;
222 
223   GetFeatureValues<protobuf_int64>("tag", &example)->Add(42);
224   ASSERT_FALSE(HasFeature<string>("tag", example));
225 
226   *GetFeatureValues<string>("tag", &example)->Add() = "FOO";
227 
228   EXPECT_TRUE(HasFeature<string>("tag", example));
229   auto tag_ro = GetFeatureValues<string>("tag", example);
230   ASSERT_EQ(1, tag_ro.size());
231   EXPECT_EQ("FOO", tag_ro.Get(0));
232 }
233 
TEST(AppendFeatureValuesTest,FloatValuesFromContainer)234 TEST(AppendFeatureValuesTest, FloatValuesFromContainer) {
235   Example example;
236 
237   std::vector<double> values{1.1, 2.2, 3.3};
238   AppendFeatureValues(values, "tag", &example);
239 
240   auto tag_ro = GetFeatureValues<float>("tag", example);
241   ASSERT_EQ(3, tag_ro.size());
242   EXPECT_NEAR(1.1, tag_ro.Get(0), kTolerance);
243   EXPECT_NEAR(2.2, tag_ro.Get(1), kTolerance);
244   EXPECT_NEAR(3.3, tag_ro.Get(2), kTolerance);
245 }
246 
TEST(AppendFeatureValuesTest,FloatValuesUsingInitializerList)247 TEST(AppendFeatureValuesTest, FloatValuesUsingInitializerList) {
248   Example example;
249 
250   AppendFeatureValues({1.1, 2.2, 3.3}, "tag", &example);
251 
252   auto tag_ro = GetFeatureValues<float>("tag", example);
253   ASSERT_EQ(3, tag_ro.size());
254   EXPECT_NEAR(1.1, tag_ro.Get(0), kTolerance);
255   EXPECT_NEAR(2.2, tag_ro.Get(1), kTolerance);
256   EXPECT_NEAR(3.3, tag_ro.Get(2), kTolerance);
257 }
258 
TEST(SetFeatureValuesTest,FloatValuesUsingInitializerList)259 TEST(SetFeatureValuesTest, FloatValuesUsingInitializerList) {
260   Example example;
261 
262   // The first set of values should be overwritten by the second.
263   AppendFeatureValues({1.1, 2.2, 3.3}, "tag", &example);
264   SetFeatureValues({10.1, 20.2, 30.3}, "tag", &example);
265 
266   auto tag_ro = GetFeatureValues<float>("tag", example);
267   ASSERT_EQ(3, tag_ro.size());
268   EXPECT_NEAR(10.1, tag_ro.Get(0), kTolerance);
269   EXPECT_NEAR(20.2, tag_ro.Get(1), kTolerance);
270   EXPECT_NEAR(30.3, tag_ro.Get(2), kTolerance);
271 }
272 
TEST(AppendFeatureValuesTest,Int64ValuesUsingInitializerList)273 TEST(AppendFeatureValuesTest, Int64ValuesUsingInitializerList) {
274   Example example;
275 
276   std::vector<protobuf_int64> values{1, 2, 3};
277   AppendFeatureValues(values, "tag", &example);
278 
279   auto tag_ro = GetFeatureValues<protobuf_int64>("tag", example);
280   ASSERT_EQ(3, tag_ro.size());
281   EXPECT_EQ(1, tag_ro.Get(0));
282   EXPECT_EQ(2, tag_ro.Get(1));
283   EXPECT_EQ(3, tag_ro.Get(2));
284 }
285 
TEST(AppendFeatureValuesTest,StringValuesUsingInitializerList)286 TEST(AppendFeatureValuesTest, StringValuesUsingInitializerList) {
287   Example example;
288 
289   AppendFeatureValues({"FOO", "BAR", "BAZ"}, "tag", &example);
290 
291   auto tag_ro = GetFeatureValues<string>("tag", example);
292   ASSERT_EQ(3, tag_ro.size());
293   EXPECT_EQ("FOO", tag_ro.Get(0));
294   EXPECT_EQ("BAR", tag_ro.Get(1));
295   EXPECT_EQ("BAZ", tag_ro.Get(2));
296 }
297 
TEST(AppendFeatureValuesTest,StringVariablesUsingInitializerList)298 TEST(AppendFeatureValuesTest, StringVariablesUsingInitializerList) {
299   Example example;
300 
301   string string1("FOO");
302   string string2("BAR");
303   string string3("BAZ");
304 
305   AppendFeatureValues({string1, string2, string3}, "tag", &example);
306 
307   auto tag_ro = GetFeatureValues<string>("tag", example);
308   ASSERT_EQ(3, tag_ro.size());
309   EXPECT_EQ("FOO", tag_ro.Get(0));
310   EXPECT_EQ("BAR", tag_ro.Get(1));
311   EXPECT_EQ("BAZ", tag_ro.Get(2));
312 }
313 
TEST(GetFeatureTest,WritesAVectorToFeature)314 TEST(GetFeatureTest, WritesAVectorToFeature) {
315   Example example;
316 
317   Feature* feature = GetFeature("tag", &example);
318   AppendFeatureValues<float>({1.1, 2.2, 3.3}, feature);
319 
320   auto tag_ro = GetFeatureValues<float>("tag", example);
321 
322   ASSERT_EQ(3, tag_ro.size());
323   EXPECT_NEAR(1.1, tag_ro.Get(0), kTolerance);
324   EXPECT_NEAR(2.2, tag_ro.Get(1), kTolerance);
325   EXPECT_NEAR(3.3, tag_ro.Get(2), kTolerance);
326 }
327 
TEST(GetFeatureTest,ReadsAVectorFromFeature)328 TEST(GetFeatureTest, ReadsAVectorFromFeature) {
329   Example example;
330 
331   AppendFeatureValues<float>({1.1, 2.2, 3.3}, "tag", &example);
332 
333   const Feature& feature = GetFeature("tag", example);
334   auto tag_ro = GetFeatureValues<float>(feature);
335 
336   ASSERT_EQ(3, tag_ro.size());
337   EXPECT_NEAR(1.1, tag_ro.Get(0), kTolerance);
338   EXPECT_NEAR(2.2, tag_ro.Get(1), kTolerance);
339   EXPECT_NEAR(3.3, tag_ro.Get(2), kTolerance);
340 }
341 
TEST(SequenceExampleTest,ReadsASingleValueFromContext)342 TEST(SequenceExampleTest, ReadsASingleValueFromContext) {
343   SequenceExample se;
344   (*se.mutable_context()->mutable_feature())["tag"]
345       .mutable_int64_list()
346       ->add_value(42);
347 
348   auto values = GetFeatureValues<protobuf_int64>("tag", se.context());
349 
350   ASSERT_EQ(1, values.size());
351   EXPECT_EQ(42, values.Get(0));
352 }
353 
TEST(SequenceExampleTest,WritesASingleValueToContext)354 TEST(SequenceExampleTest, WritesASingleValueToContext) {
355   SequenceExample se;
356 
357   GetFeatureValues<protobuf_int64>("tag", se.mutable_context())->Add(42);
358 
359   ASSERT_EQ(1, se.context().feature().at("tag").int64_list().value_size());
360   EXPECT_EQ(42, se.context().feature().at("tag").int64_list().value(0));
361 }
362 
TEST(SequenceExampleTest,AppendFeatureValuesToContextSingleArg)363 TEST(SequenceExampleTest, AppendFeatureValuesToContextSingleArg) {
364   SequenceExample se;
365 
366   AppendFeatureValues({1.1, 2.2, 3.3}, "tag", se.mutable_context());
367 
368   auto tag_ro = GetFeatureValues<float>("tag", se.context());
369   ASSERT_EQ(3, tag_ro.size());
370   EXPECT_NEAR(1.1, tag_ro.Get(0), kTolerance);
371   EXPECT_NEAR(2.2, tag_ro.Get(1), kTolerance);
372   EXPECT_NEAR(3.3, tag_ro.Get(2), kTolerance);
373 }
374 
TEST(SequenceExampleTest,CheckTypedFieldExistence)375 TEST(SequenceExampleTest, CheckTypedFieldExistence) {
376   SequenceExample se;
377 
378   GetFeatureValues<float>("tag", se.mutable_context())->Add(3.14);
379   ASSERT_FALSE(HasFeature<protobuf_int64>("tag", se.context()));
380 
381   GetFeatureValues<protobuf_int64>("tag", se.mutable_context())->Add(42);
382 
383   EXPECT_TRUE(HasFeature<protobuf_int64>("tag", se.context()));
384   auto tag_ro = GetFeatureValues<protobuf_int64>("tag", se.context());
385   ASSERT_EQ(1, tag_ro.size());
386   EXPECT_EQ(42, tag_ro.Get(0));
387 }
388 
TEST(SequenceExampleTest,ReturnsExistingFeatureLists)389 TEST(SequenceExampleTest, ReturnsExistingFeatureLists) {
390   SequenceExample se;
391   (*se.mutable_feature_lists()->mutable_feature_list())["tag"]
392       .mutable_feature()
393       ->Add();
394 
395   auto feature = GetFeatureList("tag", se);
396 
397   ASSERT_EQ(1, feature.size());
398 }
399 
TEST(SequenceExampleTest,CreatesNewFeatureLists)400 TEST(SequenceExampleTest, CreatesNewFeatureLists) {
401   SequenceExample se;
402 
403   GetFeatureList("tag", &se)->Add();
404 
405   EXPECT_EQ(1, se.feature_lists().feature_list().at("tag").feature_size());
406 }
407 
TEST(SequenceExampleTest,CheckFeatureListExistence)408 TEST(SequenceExampleTest, CheckFeatureListExistence) {
409   SequenceExample se;
410   ASSERT_FALSE(HasFeatureList("tag", se));
411 
412   GetFeatureList("tag", &se)->Add();
413 
414   ASSERT_TRUE(HasFeatureList("tag", se));
415 }
416 
TEST(SequenceExampleTest,AppendFeatureValuesWithInitializerList)417 TEST(SequenceExampleTest, AppendFeatureValuesWithInitializerList) {
418   SequenceExample se;
419 
420   AppendFeatureValues({1, 2, 3}, "ids", se.mutable_context());
421   AppendFeatureValues({"cam1-0", "cam2-0"},
422                       GetFeatureList("images", &se)->Add());
423   AppendFeatureValues({"cam1-1", "cam2-2"},
424                       GetFeatureList("images", &se)->Add());
425 
426   EXPECT_EQ(se.DebugString(),
427             "context {\n"
428             "  feature {\n"
429             "    key: \"ids\"\n"
430             "    value {\n"
431             "      int64_list {\n"
432             "        value: 1\n"
433             "        value: 2\n"
434             "        value: 3\n"
435             "      }\n"
436             "    }\n"
437             "  }\n"
438             "}\n"
439             "feature_lists {\n"
440             "  feature_list {\n"
441             "    key: \"images\"\n"
442             "    value {\n"
443             "      feature {\n"
444             "        bytes_list {\n"
445             "          value: \"cam1-0\"\n"
446             "          value: \"cam2-0\"\n"
447             "        }\n"
448             "      }\n"
449             "      feature {\n"
450             "        bytes_list {\n"
451             "          value: \"cam1-1\"\n"
452             "          value: \"cam2-2\"\n"
453             "        }\n"
454             "      }\n"
455             "    }\n"
456             "  }\n"
457             "}\n");
458 }
459 
TEST(SequenceExampleTest,AppendFeatureValuesWithVectors)460 TEST(SequenceExampleTest, AppendFeatureValuesWithVectors) {
461   SequenceExample se;
462 
463   std::vector<float> readings{1.0, 2.5, 5.0};
464   AppendFeatureValues(readings, GetFeatureList("movie_ratings", &se)->Add());
465 
466   EXPECT_EQ(se.DebugString(),
467             "feature_lists {\n"
468             "  feature_list {\n"
469             "    key: \"movie_ratings\"\n"
470             "    value {\n"
471             "      feature {\n"
472             "        float_list {\n"
473             "          value: 1\n"
474             "          value: 2.5\n"
475             "          value: 5\n"
476             "        }\n"
477             "      }\n"
478             "    }\n"
479             "  }\n"
480             "}\n");
481 }
482 
TEST(SequenceExampleTest,SetContextFeatureValuesWithInitializerList)483 TEST(SequenceExampleTest, SetContextFeatureValuesWithInitializerList) {
484   SequenceExample se;
485 
486   // The first set of values should be overwritten by the second.
487   SetFeatureValues({101, 102, 103}, "ids", se.mutable_context());
488   SetFeatureValues({1, 2, 3}, "ids", se.mutable_context());
489 
490   // These values should be appended without overwriting.
491   AppendFeatureValues({4, 5, 6}, "ids", se.mutable_context());
492 
493   EXPECT_EQ(se.DebugString(),
494             "context {\n"
495             "  feature {\n"
496             "    key: \"ids\"\n"
497             "    value {\n"
498             "      int64_list {\n"
499             "        value: 1\n"
500             "        value: 2\n"
501             "        value: 3\n"
502             "        value: 4\n"
503             "        value: 5\n"
504             "        value: 6\n"
505             "      }\n"
506             "    }\n"
507             "  }\n"
508             "}\n");
509 }
510 
TEST(SequenceExampleTest,SetFeatureValuesWithInitializerList)511 TEST(SequenceExampleTest, SetFeatureValuesWithInitializerList) {
512   SequenceExample se;
513 
514   // The first set of values should be overwritten by the second.
515   AppendFeatureValues({1, 2, 3}, "ids", se.mutable_context());
516   SetFeatureValues({4, 5, 6}, "ids", se.mutable_context());
517 
518   // Two distinct features are added to the same feature list, so both will
519   // coexist in the output.
520   AppendFeatureValues({"cam1-0", "cam2-0"},
521                       GetFeatureList("images", &se)->Add());
522   SetFeatureValues({"cam1-1", "cam2-1"}, GetFeatureList("images", &se)->Add());
523 
524   // The first set of values should be overwritten by the second.
525   AppendFeatureValues({"cam1-0", "cam2-0"},
526                       GetFeatureList("more-images", &se)->Add());
527   SetFeatureValues({"cam1-1", "cam2-1"},
528                    GetFeatureList("more-images", &se)->Mutable(0));
529 
530   EXPECT_EQ(se.DebugString(),
531             "context {\n"
532             "  feature {\n"
533             "    key: \"ids\"\n"
534             "    value {\n"
535             "      int64_list {\n"
536             "        value: 4\n"
537             "        value: 5\n"
538             "        value: 6\n"
539             "      }\n"
540             "    }\n"
541             "  }\n"
542             "}\n"
543             "feature_lists {\n"
544             "  feature_list {\n"
545             "    key: \"images\"\n"
546             "    value {\n"
547             "      feature {\n"
548             "        bytes_list {\n"
549             "          value: \"cam1-0\"\n"
550             "          value: \"cam2-0\"\n"
551             "        }\n"
552             "      }\n"
553             "      feature {\n"
554             "        bytes_list {\n"
555             "          value: \"cam1-1\"\n"
556             "          value: \"cam2-1\"\n"
557             "        }\n"
558             "      }\n"
559             "    }\n"
560             "  }\n"
561             "  feature_list {\n"
562             "    key: \"more-images\"\n"
563             "    value {\n"
564             "      feature {\n"
565             "        bytes_list {\n"
566             "          value: \"cam1-1\"\n"
567             "          value: \"cam2-1\"\n"
568             "        }\n"
569             "      }\n"
570             "    }\n"
571             "  }\n"
572             "}\n");
573 }
574 
575 }  // namespace
576 }  // namespace tensorflow
577