2017-12-27 28 views
5

softmax_cross_entropy_with_logits_v2()이 어떻게 구현되는지보고자합니다. 전화는 _softmax_cross_entropy_with_logits()입니다. 그러나 나는 후자가 정의 된 곳을 보지 못했다. 아무도 그 정의를 찾는 방법을 알고 있습니까?`_softmax_cross_entropy_with_logits`는 tensorflow에 정의되어 있습니까?

$ ack '\b_softmax_cross_entropy_with_logits\b' 
tensorflow/compiler/tests/binary_ops_test.py 
176:   gen_nn_ops._softmax_cross_entropy_with_logits, 

tensorflow/python/kernel_tests/xent_op_test.py 
52:  loss, backprop = gen_nn_ops._softmax_cross_entropy_with_logits(
75:  loss, backprop = gen_nn_ops._softmax_cross_entropy_with_logits(
93:        gen_nn_ops._softmax_cross_entropy_with_logits, 
135:  gen_nn_ops._softmax_cross_entropy_with_logits(
141:  gen_nn_ops._softmax_cross_entropy_with_logits([0., 1., 2., 3.], 

tensorflow/python/ops/nn_ops.py 
1803: cost, unused_backprop = gen_nn_ops._softmax_cross_entropy_with_logits(

답변

3

kmario23의 답변은 정확합니다. 기본적으로 gen_* 패키지에 대한 참조를 볼 때 자동으로 생성 된 Python 코드를 의미합니다.

def _softmax_cross_entropy_with_logits(features, labels, name=None): 
    r"""Computes softmax cross entropy cost and gradients to backpropagate. 

    Inputs are the logits, not probabilities. 

    Args: 
    features: A `Tensor`. Must be one of the following types: `half`, `float32`, `float64`. 
     batch_size x num_classes matrix 
    labels: A `Tensor`. Must have the same type as `features`. 
     batch_size x num_classes matrix 
     The caller must ensure that each batch of labels represents a valid 
     probability distribution. 
    name: A name for the operation (optional). 

    Returns: 
    A tuple of `Tensor` objects (loss, backprop). 

    loss: A `Tensor`. Has the same type as `features`. Per example loss (batch_size vector). 
    backprop: A `Tensor`. Has the same type as `features`. backpropagated gradients (batch_size x num_classes matrix). 
    """ 
    _ctx = _context.context() 
    if _ctx.in_graph_mode(): 
    _, _, _op = _op_def_lib._apply_op_helper(
     "SoftmaxCrossEntropyWithLogits", features=features, labels=labels, 
     name=name) 
    _result = _op.outputs[:] 
    _inputs_flat = _op.inputs 
    _attrs = ("T", _op.get_attr("T")) 
    else: 
    _attr_T, _inputs_T = _execute.args_to_matching_eager([features, labels], _ctx) 
    (features, labels) = _inputs_T 
    _attr_T = _attr_T.as_datatype_enum 
    _inputs_flat = [features, labels] 
    _attrs = ("T", _attr_T) 
    _result = _execute.execute(b"SoftmaxCrossEntropyWithLogits", 2, 
           inputs=_inputs_flat, attrs=_attrs, ctx=_ctx, 
           name=name) 
    _execute.record_gradient(
     "SoftmaxCrossEntropyWithLogits", _inputs_flat, _attrs, _result, name) 
    _result = _SoftmaxCrossEntropyWithLogitsOutput._make(_result) 
    return _result 

을하지만이 기능은 네이티브 C에 대한 래퍼 ++ 구현이기 때문에, 당신은 실제 C++ 코드를보고 관심이있을 수 있습니다이 경우

, 그것은 gen_nn_ops.py입니다. 그것은 CPU와 GPU 모두, tensorflow/core/kernels/xent_op.cc에 있어요 :

template <typename Device, typename T> 
class SoftmaxXentWithLogitsOp : public OpKernel { 
public: 
    explicit SoftmaxXentWithLogitsOp(OpKernelConstruction* context) 
     : OpKernel(context) {} 

    void Compute(OpKernelContext* context) override { 
    const Tensor& logits_in = context->input(0); 
    const Tensor& labels_in = context->input(1); 
    OP_REQUIRES(context, logits_in.IsSameSize(labels_in), 
       errors::InvalidArgument(
        "logits and labels must be same size: logits_size=", 
        logits_in.shape().DebugString(), " labels_size=", 
        labels_in.shape().DebugString())); 
    OP_REQUIRES(context, TensorShapeUtils::IsMatrix(logits_in.shape()), 
       errors::InvalidArgument("logits must be 2-dimensional")); 
    // As we already tested that both inputs have the same shape no need to 
    // check that "labels" is a matrix too. 

    // loss is 1-D (one per example), and size is batch_size. 

    Tensor scratch; 
    OP_REQUIRES_OK(
     context, context->allocate_temp(DataTypeToEnum<T>::value, 
             TensorShape({logits_in.dim_size(0), 1}), 
             &scratch)); 

    Tensor* loss_out = nullptr; 
    OP_REQUIRES_OK(context, 
        context->allocate_output(
         0, TensorShape({logits_in.dim_size(0)}), &loss_out)); 
    Tensor* back_out = nullptr; 
    // Try to reuse the logits_in buffer for the backprop output. 
    OP_REQUIRES_OK(context, context->forward_input_or_allocate_output(
           {0}, 1, logits_in.shape(), &back_out)); 
    functor::XentFunctor<Device, T> functor; 
    functor(context->eigen_device<Device>(), logits_in.matrix<T>(), 
      labels_in.matrix<T>(), scratch.matrix<T>(), loss_out->vec<T>(), 
      back_out->matrix<T>()); 
    } 
}; 

당신이 깊은 다이빙 관심이 있다면, 주요 통화가 마지막 줄에 있습니다 functor(...), functorXentFunctor<Device, T>입니다. 실제 논리는 타사 Eigen 라이브러리로 전달됩니다. this very similar question을 참조하십시오. 끝 부분에 얼마나 깊은지를 보여줍니다.

2

TensorFlow 설치 중에 소스 코드가 bazel 빌드에 의해 자동 생성되므로 구현이 github에서 발견되지 않습니다. 설치 디렉토리에서 다음 소스 코드를 찾을 수 있습니다.

tensorflow/python/ops/gen_nn_ops.py 

실제 구현은 C++입니다. 참조 : source code for gen_nn_ops