3D体素分割的损失函数和准确度度量

时间:2018-07-25 03:30:32

标签: python tensorflow deep-learning conv-neural-network

我正在尝试使用tf.Estimator()构建初步的概念验证3D体素分割CNN。我正在遵循cnn_mnist.py示例,但是我陷入了损失函数和准确性度量的定义中。我的数据是64x64x64多维数据集,每个体素被标记为0、1、2或3,并且它们是互斥的。

您如何定义按体素分类的损失函数?要使用哪些适当的损失函数?如何将这些常用损失函数中的任何一个应用于我的数据,哪一个最合适?

tf.losses.sparse_softmax_cross_entropy
tf.losses.softmax_cross_entropy
tf.losses.sigmoid_cross_entropy

此外,我有兴趣跟踪每个标签的准确性以及所有正确预测的体素的整体准确性度量。 tf.Estimator()有可能吗?如何定义这些功能并可能在张量板上报告它们?

下面是我的代码正在进行中。它实际上还没有用,因为我收到了OOM和其他奇怪的错误,例如TypeError:索引元素必须按升序排列。堆栈令人生畏,没有指向我的代码中的一行。

如果您有任何帮助或建议,我将不胜感激。谢谢!

"""Convolutional Neural Network Estimator for Voxel Segmentation, built with tf.estimator."""

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

import numpy as np
import tensorflow as tf
from datetime import datetime
import os

tf.logging.set_verbosity(tf.logging.INFO)


def cnn_model_fn(features, labels, mode):
  """Model function for CNN."""
  # Input Layer
  # Reshape X to 5-D tensor: [batch_size, width, height, length, channels]
  # Protein maps are 64x64x64 voxels, and have one channel
  input_layer = tf.reshape(features["x"], [-1, 64, 64, 64, 1])

  print("input_layer Shape&dtype=", input_layer.get_shape(), input_layer.dtype)
  print("labels Shape&dtype=", labels.get_shape(), labels.dtype)
  #input_layer Shape&dtype= (50, 64, 64, 64, 1) <dtype: 'float32'>
  #labels Shape&dtype= (50, 64, 64, 64) <dtype: 'int32'>

  #Get a weight for the loss function
  weight = tf.to_int32(input_layer > 0)
  print("Weight Shape&dtype=", weight.get_shape(), weight.dtype)
  #Weight Shape&dtype= (50, 64, 64, 64, 1) <dtype: 'int32'>

  conv1 = tf.layers.conv3d(inputs=input_layer...)
  print("Conv1 Shape&dtype=", conv1.get_shape(), conv1.dtype)
  #Conv1 Shape&dtype= (50, 64, 64, 64, 32) <dtype: 'float32'>

  conv2 = tf.layers.conv3d(inputs=conv1...)
  conv3 = tf.layers.conv3d(inputs=conv2...)

  logits = tf.layers.conv3d(inputs=conv3...)
  print("Logits Shape&dtype=", logits.get_shape(), logits.dtype)
  #Logits Shape&dtype= (50, 64, 64, 64, 4) <dtype: 'float32'>

  predictions = {
    # Generate predictions (for PREDICT and EVAL mode)
    "classes": tf.argmax(input=logits, axis=4),
    # Add `softmax_tensor` to the graph.  It is used for PREDICT and by the`logging_hook`.
    "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
  }
  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  # Calculate Loss (for both TRAIN and EVAL modes)
  loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits, weights=weight)

  # Configure the Training Op (for TRAIN mode)
  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
    train_op = optimizer.minimize(loss=loss,global_step=tf.train.get_global_step())
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

  # Add evaluation metrics (for EVAL mode)
  eval_metric_ops = {"accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}
  return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

def main(unused_argv):
  # Load training and eval data
  train_data = ReadFromFile
  train_labels = np.asarray(ReadFromFile, dtype=np.int32)
  eval_data = ReadFromFile
  eval_labels = np.asarray(ReadFromFile, dtype=np.int32)

  print(train_data.shape) #(2735, 64, 64, 64)  
  print(train_labels.shape) #(2735, 64, 64, 64)
  print(eval_data.shape)   #(1173, 64, 64, 64) 
  print(eval_labels.shape) #(1173, 64, 64, 64)

  model_dir = os.path.join(os.getcwd(), "tmp", datetime.now().strftime("%Y%m%d-%H%M%S"))

  # Create the Estimator
  voxel_classifier = tf.estimator.Estimator(model_fn=cnn_model_fn, model_dir=model_dir)

  # Set up logging for predictions
  # Log the values in the "Softmax" tensor with label "probabilities"
  tensors_to_log = {"probabilities": "softmax_tensor"}
  logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)

  # Train the model
  train_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={"x": train_data},
      y=train_labels,
      batch_size=50,
      num_epochs=None,
      shuffle=True)
  voxel_classifier.train(input_fn=train_input_fn, steps=20000, hooks=[logging_hook])

  # Evaluate the model and print results
  eval_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={"x": eval_data},
      y=eval_labels,
      num_epochs=1,
      shuffle=False)
  eval_results = voxel_classifier.evaluate(input_fn=eval_input_fn)
  print(eval_results)

if __name__ == "__main__":
    tf.app.run()

0 个答案:

没有答案