【问题标题】:Tensorflow: what are "input_mean" and "input_std" in label_image.py in tensorflow exampleTensorflow:张量流示例中 label_image.py 中的“input_mean”和“input_std”是什么
【发布时间】:2018-04-27 11:06:50
【问题描述】:

我使用的是 Windows 7。 我已经使用官方再训练示例训练了一个移动网络。

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/image_retraining

我有这样的运行命令:

python ../tensorflow-master/tensorflow/examples/image_retraining/retrain.py --image_dir test/ --learning_rate=0.0001 --testing_percentage=20 --validation_percentage=20 --train_batch_size=32 --validation_batch_size=-1 --flip_left_right True --random_scale=30 --random_brightness=30 --eval_step_interval=100 --how_many_training_steps=2000 --architecture mobilenet_0.25_128

我得到了训练好的图形和标签文件“output_graph.pb”和“output_labels.txt”。

现在,我想使用上面生成的图进行分类,所以我使用了tensorflow github中提供的label_image.py。

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/label_image

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import sys

import numpy as np
import tensorflow as tf

def load_graph(model_file):
  graph = tf.Graph()
  graph_def = tf.GraphDef()

  with open(model_file, "rb") as f:
    graph_def.ParseFromString(f.read())
  with graph.as_default():
    tf.import_graph_def(graph_def)

  return graph

def read_tensor_from_image_file(file_name, input_height=299, input_width=299,
                input_mean=0, input_std=255):
  input_name = "file_reader"
  output_name = "normalized"
  file_reader = tf.read_file(file_name, input_name)
  if file_name.endswith(".png"):
    image_reader = tf.image.decode_png(file_reader, channels = 3,
                                       name='png_reader')
  elif file_name.endswith(".gif"):
    image_reader = tf.squeeze(tf.image.decode_gif(file_reader,
                                                  name='gif_reader'))
  elif file_name.endswith(".bmp"):
    image_reader = tf.image.decode_bmp(file_reader, name='bmp_reader')
  else:
    image_reader = tf.image.decode_jpeg(file_reader, channels = 3,
                                        name='jpeg_reader')
  float_caster = tf.cast(image_reader, tf.float32)
  dims_expander = tf.expand_dims(float_caster, 0);
  resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
  normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
  sess = tf.Session()
  result = sess.run(normalized)

  return result

def load_labels(label_file):
  label = []
  proto_as_ascii_lines = tf.gfile.GFile(label_file).readlines()
  for l in proto_as_ascii_lines:
    label.append(l.rstrip())
  return label

if __name__ == "__main__":
  file_name = "tensorflow/examples/label_image/data/grace_hopper.jpg"
  model_file = \
    "tensorflow/examples/label_image/data/inception_v3_2016_08_28_frozen.pb"
  label_file = "tensorflow/examples/label_image/data/imagenet_slim_labels.txt"
  input_height = 299
  input_width = 299
  input_mean = 0
  input_std = 255
  input_layer = "input"
  output_layer = "InceptionV3/Predictions/Reshape_1"

  parser = argparse.ArgumentParser()
  parser.add_argument("--image", help="image to be processed")
  parser.add_argument("--graph", help="graph/model to be executed")
  parser.add_argument("--labels", help="name of file containing labels")
  parser.add_argument("--input_height", type=int, help="input height")
  parser.add_argument("--input_width", type=int, help="input width")
  parser.add_argument("--input_mean", type=int, help="input mean")
  parser.add_argument("--input_std", type=int, help="input std")
  parser.add_argument("--input_layer", help="name of input layer")
  parser.add_argument("--output_layer", help="name of output layer")
  args = parser.parse_args()

  if args.graph:
    model_file = args.graph
  if args.image:
    file_name = args.image
  if args.labels:
    label_file = args.labels
  if args.input_height:
    input_height = args.input_height
  if args.input_width:
    input_width = args.input_width
  if args.input_mean:
    input_mean = args.input_mean
  if args.input_std:
    input_std = args.input_std
  if args.input_layer:
    input_layer = args.input_layer
  if args.output_layer:
    output_layer = args.output_layer

  graph = load_graph(model_file)
  t = read_tensor_from_image_file(file_name,
                                  input_height=input_height,
                                  input_width=input_width,
                                  input_mean=input_mean,
                                  input_std=input_std)

  input_name = "import/" + input_layer
  output_name = "import/" + output_layer
  input_operation = graph.get_operation_by_name(input_name);
  output_operation = graph.get_operation_by_name(output_name);

  with tf.Session(graph=graph) as sess:
    results = sess.run(output_operation.outputs[0],
                      {input_operation.outputs[0]: t})
  results = np.squeeze(results)

  top_k = results.argsort()[-5:][::-1]
  labels = load_labels(label_file)
  for i in top_k:
    print(labels[i], results[i])

然后我运行以下命令:

python ../tensorflow-master/tensorflow/examples/label_image/label_image.py --graph=output_graph.pb --labels=output_labels.txt --image=test.jpg --input_layer=input --output_layer=final_result --input_mean=128 --input_std=128 --input_width=128 --input_height=128

并且可以对图片“test.jpg”进行分类。

但是,当我对“input_mean”和“input_std”使用不同的值时,结果会发生变化。

“input_mean”和“input_std”是干什么用的?我怎样才能得到这两个参数的正确值?

【问题讨论】:

  • 请提供您正在使用的代码。
  • @Lescurel 我添加了包含我使用过的 .py 文件的相关链接
  • 您应该将代码嵌入到您的问题中,因为该链接将来可能会更改。
  • @Lescure 我已经添加了label_image.py的代码,但是我没有复制retrain.py的代码,因为有字数限制
  • 它们是训练中--architecture参数选择的参数。看起来他们应该都是127.5,但我没有任何解释为什么

标签: python tensorflow deep-learning classification


【解决方案1】:

这两个变量用于规范化数据集,因为我们观察到这样做的结果有所改善。
input_mean 是数据集每个通道的平均值,input_std 是相关的标准差。当您控制在网络中传递的数据集时,您应该能够计算均值和标准。

标准化意味着两件事:

  • 将数据放在相同的比例(缩放)
  • 围绕一个点平衡数据(居中(在我们的例子中为 0 左右))

至于我们为什么这样做,您可以在这个交叉验证的答案中了解它:https://stats.stackexchange.com/a/220970

“减去数据集均值用于“居中”数据。 此外,理想情况下,您希望除以 sttdev 如果要标准化每个特征值,也可以使用特征或像素 到 z 分数。

我们做这两件事的原因是因为在这个过程中 训练我们的网络,我们将乘以(权重)和 添加(偏置)这些初始输入以引起激活 然后我们用梯度反向传播来训练模型。

我们希望在此过程中,每个功能都具有相似的范围,因此 我们的梯度不会失控(而且我们只需要一个 全局学习率乘数)。 "

编辑:举个例子 想象一下你的图像是一个非常简单的 3 像素图像:

img = [[[1,2,3],[4,5,6],[7,8,9]]]

您可以轻松计算每个通道的平均值

mean = [4,5,6]

每个通道的标准也很容易:

std = [2.45,2.45,2.45]

由于 tensorflow 会先进行元素减法,然后再进行元素除法,因此您将分别对图像的每个通道进行归一化。

在代码中,他们似乎添加了一个维度以符合 tf.image 函数。由于第一个维度是批处理维度,因此您应该在数组前面加上 0。([0,4,5,6])

【讨论】:

  • 这意味着我必须在这个案例中计算所有通道的图像颜色的平均值和标准?
  • 每个通道的平均值选项将为您提供最佳结果。传递一个均值和标准差数组,而不是一个 int。我将更新我的答案以提供一个示例。
猜你喜欢
  • 1970-01-01
  • 2020-04-29
  • 2023-03-19
  • 2019-03-27
  • 2016-10-20
  • 2018-11-10
  • 2017-11-22
  • 2017-12-23
  • 1970-01-01
相关资源
最近更新 更多