diff --git a/tensorflow/cc/BUILD b/tensorflow/cc/BUILD index 7b8cfc56edf68e92ce9a2f1c977bc7cead6892f9..48fbaa479a62ee587a3fd745231a829cb637a66b 100644 --- a/tensorflow/cc/BUILD +++ b/tensorflow/cc/BUILD @@ -2,7 +2,9 @@ # TensorFlow is a computational framework, primarily for use in machine # learning applications. -package(default_visibility = ["//tensorflow:internal"]) +package( + default_visibility = ["//tensorflow:internal"], +) licenses(["notice"]) # Apache 2.0 diff --git a/tensorflow/core/BUILD b/tensorflow/core/BUILD index 72bd33dab553ef42ab086b691448f2b8a12493f4..cb26384ebe53a39cfcbc07e4e4ddbff0eb574e94 100644 --- a/tensorflow/core/BUILD +++ b/tensorflow/core/BUILD @@ -2,7 +2,9 @@ # TensorFlow is a computational framework, primarily for use in machine # learning applications. -package(default_visibility = ["//tensorflow:internal"]) +package( + default_visibility = ["//tensorflow:internal"], +) package_group(name = "friends") diff --git a/tensorflow/core/common_runtime/gpu/gpu_event_mgr.cc b/tensorflow/core/common_runtime/gpu/gpu_event_mgr.cc index 32109157aa505d0bd559915e8db38d6dcaa59f53..1821289f4b6b26ce9fad4987bfe457bca19f8e16 100644 --- a/tensorflow/core/common_runtime/gpu/gpu_event_mgr.cc +++ b/tensorflow/core/common_runtime/gpu/gpu_event_mgr.cc @@ -40,13 +40,13 @@ EventMgr::~EventMgr() { delete e; } while (!used_events_.empty()) { - InUse* ue = &used_events_[0]; - delete ue->event; - delete ue->mem; - if (ue->bufrec.buf) { - ue->bufrec.alloc->DeallocateRaw(ue->bufrec.buf); + delete used_events_[0].event; + delete used_events_[0].mem; + if (used_events_[0].bufrec.buf) { + used_events_[0].bufrec.alloc->DeallocateRaw(used_events_[0].bufrec.buf); } - if (ue->func != nullptr) threadpool_.Schedule(ue->func); + if (used_events_[0].func != nullptr) + threadpool_.Schedule(used_events_[0].func); used_events_.pop_front(); } } @@ -60,17 +60,15 @@ EventMgr::~EventMgr() { void EventMgr::PollLoop() { while (!stop_polling_.HasBeenNotified()) { Env::Default()->SleepForMicroseconds(1 * 1000); - ToFreeVector to_free; { mutex_lock l(mu_); - PollEvents(true, &to_free); + PollEvents(true); } - FreeMemory(to_free); } polling_stopped_.Notify(); } -void EventMgr::QueueInUse(gpu::Stream* stream, InUse iu, gpu::Event** e) { +void EventMgr::QueueInUse(gpu::Stream* stream, InUse iu) { VLOG(2) << "QueueInUse free_events_ " << free_events_.size() << " used_events_ " << used_events_.size(); // Events are created on demand, and repeatedly reused. There is no @@ -79,9 +77,10 @@ void EventMgr::QueueInUse(gpu::Stream* stream, InUse iu, gpu::Event** e) { free_events_.push_back(new gpu::Event(exec_)); free_events_.back()->Init(); } - *e = free_events_.back(); + gpu::Event* e = free_events_.back(); free_events_.pop_back(); - iu.event = *e; + stream->ThenRecordEvent(e); + iu.event = e; used_events_.push_back(iu); } @@ -104,8 +103,7 @@ void EventMgr::QueueInUse(gpu::Stream* stream, InUse iu, gpu::Event** e) { // GPU memory use to spike needlessly. An alternative strategy would // be to throttle new Op execution until the pending event queue // clears. -void EventMgr::PollEvents(bool is_dedicated_poller, - gtl::InlinedVector* to_free) { +void EventMgr::PollEvents(bool is_dedicated_poller) { VLOG(2) << "PollEvents free_events_ " << free_events_.size() << " used_events_ " << used_events_.size(); // Sweep the remaining events in order. If this is the dedicated @@ -125,9 +123,11 @@ void EventMgr::PollEvents(bool is_dedicated_poller, if (!is_dedicated_poller) return; // quit processing queue break; case gpu::Event::Status::kComplete: - // Make a copy of the InUse record so we can free it after releasing - // the lock - to_free->push_back(iu); + delete iu.mem; + if (iu.bufrec.buf) iu.bufrec.alloc->DeallocateRaw(iu.bufrec.buf); + // The function must be called in another thread, outside of + // the mutex held here. + if (iu.func != nullptr) threadpool_.Schedule(iu.func); free_events_.push_back(iu.event); // Mark this InUse record as completed. iu.event = nullptr; diff --git a/tensorflow/core/common_runtime/gpu/gpu_event_mgr.h b/tensorflow/core/common_runtime/gpu/gpu_event_mgr.h index f2a1ea2603149b515a85a06a30c1650f2af767f0..5fe9fd782db526b9b3c06b2c5ff22d086fe2037d 100644 --- a/tensorflow/core/common_runtime/gpu/gpu_event_mgr.h +++ b/tensorflow/core/common_runtime/gpu/gpu_event_mgr.h @@ -18,10 +18,8 @@ limitations under the License. #include #include -#include "tensorflow/stream_executor/stream.h" #include "tensorflow/core/lib/core/notification.h" #include "tensorflow/core/lib/core/threadpool.h" -#include "tensorflow/core/lib/gtl/inlined_vector.h" #include "tensorflow/core/platform/port.h" #include "tensorflow/core/platform/thread_annotations.h" #include "tensorflow/core/public/tensor.h" @@ -49,15 +47,9 @@ class EventMgr { // currently enqueued on *stream have completed. inline void ThenDeleteTensors(perftools::gputools::Stream* stream, std::vector* tensors) { - ToFreeVector to_free; - ::perftools::gputools::Event* e; - { - mutex_lock l(mu_); - QueueTensors(stream, tensors, &e); - PollEvents(false, &to_free); - } - stream->ThenRecordEvent(e); - FreeMemory(to_free); + mutex_lock l(mu_); + QueueTensors(stream, tensors); + PollEvents(false); } struct BufRec { @@ -69,28 +61,16 @@ class EventMgr { // on it as soon as all events currently enqueued on *stream have completed. inline void ThenDeleteBuffer(perftools::gputools::Stream* stream, BufRec bufrec) { - ToFreeVector to_free; - ::perftools::gputools::Event* e; - { - mutex_lock l(mu_); - QueueBuffer(stream, bufrec, &e); - PollEvents(false, &to_free); - } - stream->ThenRecordEvent(e); - FreeMemory(to_free); + mutex_lock l(mu_); + QueueBuffer(stream, bufrec); + PollEvents(false); } inline void ThenExecute(perftools::gputools::Stream* stream, std::function func) { - ToFreeVector to_free; - ::perftools::gputools::Event* e; - { - mutex_lock l(mu_); - QueueFunc(stream, func, &e); - PollEvents(false, &to_free); - } - stream->ThenRecordEvent(e); - FreeMemory(to_free); + mutex_lock l(mu_); + QueueFunc(stream, func); + PollEvents(false); } private: @@ -105,50 +85,32 @@ class EventMgr { std::function func; }; - typedef gtl::InlinedVector ToFreeVector; - - void FreeMemory(const ToFreeVector& to_free) { - for (const auto& iu : to_free) { - delete iu.mem; - if (iu.bufrec.buf) iu.bufrec.alloc->DeallocateRaw(iu.bufrec.buf); - // The function must be called in another thread. - if (iu.func != nullptr) threadpool_.Schedule(iu.func); - } - } - // Stream-enqueue an unused Event and save with it a collection of // Tensors and/or a BufRec to be deleted only after the Event // records. - void QueueInUse(perftools::gputools::Stream* stream, InUse in_use, - ::perftools::gputools::Event** e) + void QueueInUse(perftools::gputools::Stream* stream, InUse in_use) EXCLUSIVE_LOCKS_REQUIRED(mu_); void QueueTensors(perftools::gputools::Stream* stream, - std::vector* tensors, - ::perftools::gputools::Event** e) + std::vector* tensors) EXCLUSIVE_LOCKS_REQUIRED(mu_) { - QueueInUse(stream, {nullptr, tensors, BufRec(), nullptr}, e); + QueueInUse(stream, {nullptr, tensors, BufRec(), nullptr}); } - void QueueBuffer(perftools::gputools::Stream* stream, BufRec bufrec, - ::perftools::gputools::Event** e) + void QueueBuffer(perftools::gputools::Stream* stream, BufRec bufrec) EXCLUSIVE_LOCKS_REQUIRED(mu_) { - QueueInUse(stream, {nullptr, nullptr, bufrec, nullptr}, e); + QueueInUse(stream, {nullptr, nullptr, bufrec, nullptr}); } void QueueFunc(perftools::gputools::Stream* stream, - std::function func, ::perftools::gputools::Event** e) - EXCLUSIVE_LOCKS_REQUIRED(mu_) { - QueueInUse(stream, {nullptr, nullptr, BufRec(), func}, e); + std::function func) EXCLUSIVE_LOCKS_REQUIRED(mu_) { + QueueInUse(stream, {nullptr, nullptr, BufRec(), func}); } // This function should be called at roughly the same tempo as // QueueTensors() to check whether pending events have recorded, - // and then retire them. It appends InUse elements that need cleanup - // to "*to_free". The caller should call FreeMemory(to_free) - // when this returns. - void PollEvents(bool is_dedicated_poller, ToFreeVector* to_free) - EXCLUSIVE_LOCKS_REQUIRED(mu_); + // and then retire them. + void PollEvents(bool is_dedicated_poller) EXCLUSIVE_LOCKS_REQUIRED(mu_); // An internal polling loop that runs at a low frequency to clear // straggler Events. diff --git a/tensorflow/core/common_runtime/gpu/gpu_event_mgr_test.cc b/tensorflow/core/common_runtime/gpu/gpu_event_mgr_test.cc index c6893c91e7e446b43b33b8a934e2627ca5890f51..6956ead643e6c2eaefcc132324a34a74aaf39cf1 100644 --- a/tensorflow/core/common_runtime/gpu/gpu_event_mgr_test.cc +++ b/tensorflow/core/common_runtime/gpu/gpu_event_mgr_test.cc @@ -42,21 +42,13 @@ class TEST_EventMgrHelper { void QueueTensors(perftools::gputools::Stream* stream, std::vector* tensors) { - ::perftools::gputools::Event* e; - { - mutex_lock l(em_->mu_); - em_->QueueTensors(stream, tensors, &e); - } - stream->ThenRecordEvent(e); + mutex_lock l(em_->mu_); + em_->QueueTensors(stream, tensors); } void PollEvents(bool is_dedicated_poller) { - EventMgr::ToFreeVector to_free; - { - mutex_lock l(em_->mu_); - em_->PollEvents(is_dedicated_poller, &to_free); - } - em_->FreeMemory(to_free); + mutex_lock l(em_->mu_); + em_->PollEvents(is_dedicated_poller); } private: diff --git a/tensorflow/core/framework/node_def_util.cc b/tensorflow/core/framework/node_def_util.cc index c40acac6ff2956763e179cc89b8395d5ff17773b..6e4eab8c05ed6ba8d5058707d81b12b51f5a90d2 100644 --- a/tensorflow/core/framework/node_def_util.cc +++ b/tensorflow/core/framework/node_def_util.cc @@ -79,7 +79,10 @@ Status AttrSlice::Find(const string& attr_name, return Status::OK(); } Status s = errors::NotFound("No attr named '", attr_name, "' in NodeDef:"); - if (ndef_) { + // Skip AttachDef for internal attrs since it is a little bit + // expensive and it is common for them to correctly not be included + // in a NodeDef. + if (!StringPiece(attr_name).starts_with("_") && ndef_) { s = AttachDef(s, *ndef_); } return s; diff --git a/tensorflow/core/kernels/cholesky_op.cc b/tensorflow/core/kernels/cholesky_op.cc index 1a06b124c753ace60d264bc850f0481206e662c1..2f6ad43cc21311b8d5c7dc0bbd3117c8d5242c8d 100644 --- a/tensorflow/core/kernels/cholesky_op.cc +++ b/tensorflow/core/kernels/cholesky_op.cc @@ -46,7 +46,7 @@ class CholeskyOp const int64 rows = input_matrix_shape.dim_size(0); if (rows > (1LL << 20)) { // A big number to cap the cost in case overflow. - return kint32max; + return kint64max; } else { return rows * rows * rows; } @@ -69,8 +69,9 @@ class CholeskyOp // Perform the actual LL^T Cholesky decomposition. This will only use // the lower triangular part of data_in by default. The upper triangular // part of the matrix will not be read. - Eigen::LLT> llt_decomposition(input); + Eigen::LLT< + Eigen::Matrix> + llt_decomposition(input); // Output the lower triangular in a dense form. *output = llt_decomposition.matrixL(); diff --git a/tensorflow/core/kernels/determinant_op.cc b/tensorflow/core/kernels/determinant_op.cc index 20988b5830307bf63cf968234acb2fd0344866cc..852a36bcd4bf1ddfcd2c04d4a95bb1ee06b7752d 100644 --- a/tensorflow/core/kernels/determinant_op.cc +++ b/tensorflow/core/kernels/determinant_op.cc @@ -44,7 +44,7 @@ class DeterminantOp const int64 rows = input_matrix_shape.dim_size(0); if (rows > (1LL << 20)) { // A big number to cap the cost in case overflow. - return kint32max; + return kint64max; } else { return rows * rows * rows; } diff --git a/tensorflow/core/kernels/matrix_inverse_op.cc b/tensorflow/core/kernels/matrix_inverse_op.cc index 3d7ade4b5194dd54152d92023934527ccdc82515..d7c8149cebcaffc75922a45334ae3474127e2a52 100644 --- a/tensorflow/core/kernels/matrix_inverse_op.cc +++ b/tensorflow/core/kernels/matrix_inverse_op.cc @@ -45,7 +45,7 @@ class MatrixInverseOp const int64 rows = input_matrix_shape.dim_size(0); if (rows > (1LL << 20)) { // A big number to cap the cost in case overflow. - return kint32max; + return kint64max; } else { return rows * rows * rows; } diff --git a/tensorflow/core/kernels/reduction_ops_sum.cc b/tensorflow/core/kernels/reduction_ops_sum.cc index ecd9c1a56bba4538528146f851e133e7d5d894e2..e715ca66642e84fad6cf5399d72a5224eb513e91 100644 --- a/tensorflow/core/kernels/reduction_ops_sum.cc +++ b/tensorflow/core/kernels/reduction_ops_sum.cc @@ -44,7 +44,10 @@ REGISTER_GPU_KERNELS(float); #undef REGISTER_GPU_KERNELS REGISTER_KERNEL_BUILDER( - Name("Sum").Device(DEVICE_GPU).TypeConstraint("T"), + Name("Sum") + .Device(DEVICE_GPU) + .TypeConstraint("T") + .HostMemory("reduction_indices"), ReductionOp>); #endif diff --git a/tensorflow/core/kernels/self_adjoint_eig_op.cc b/tensorflow/core/kernels/self_adjoint_eig_op.cc new file mode 100644 index 0000000000000000000000000000000000000000..9db1a5c51891d84107fb18594ba1d29f464a3381 --- /dev/null +++ b/tensorflow/core/kernels/self_adjoint_eig_op.cc @@ -0,0 +1,89 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// See docs in ../ops/linalg_ops.cc. + +#include + +#include "third_party/eigen3/Eigen/Core" +#include "third_party/eigen3/Eigen/Eigenvalues" + +#include "tensorflow/core/framework/kernel_def_builder.h" +#include "tensorflow/core/framework/op_kernel.h" +#include "tensorflow/core/kernels/linalg_ops_common.h" +#include "tensorflow/core/lib/core/errors.h" +#include "tensorflow/core/platform/logging.h" +#include "tensorflow/core/platform/port.h" +#include "tensorflow/core/public/tensor_shape.h" + +namespace tensorflow { + +template +class SelfAdjointEigOp + : public UnaryLinearAlgebraOp { + public: + explicit SelfAdjointEigOp(OpKernelConstruction* context) + : UnaryLinearAlgebraOp(context) {} + + TensorShape GetOutputMatrixShape( + const TensorShape& input_matrix_shape) override { + int64 d = input_matrix_shape.dim_size(0); + return TensorShape({d + 1, d}); + } + + int64 GetCostPerUnit(const TensorShape& input_matrix_shape) override { + const int64 rows = input_matrix_shape.dim_size(0); + if (rows > (1LL << 20)) { + // A big number to cap the cost in case overflow. + return kint64max; + } else { + return rows * rows * rows; + } + } + + using + typename UnaryLinearAlgebraOp::MatrixMap; + using typename UnaryLinearAlgebraOp::ConstMatrixMap; + + void ComputeMatrix(OpKernelContext* context, const ConstMatrixMap& input, + MatrixMap* output) override { + OP_REQUIRES(context, input.rows() == input.cols(), + errors::InvalidArgument("Input matrix must be square.")); + if (input.rows() == 0) { + // If X is an empty matrix (0 rows, 0 col), X * X' == X. + // Therefore, we return X. + return; + } + + Eigen::SelfAdjointEigenSolver< + Eigen::Matrix> + es(input); + output->row(0) = es.eigenvalues().transpose(); + output->bottomRows(input.rows()) = es.eigenvectors(); + OP_REQUIRES(context, es.info() == Eigen::Success, + errors::InvalidArgument("Self Adjoint Eigen decomposition was" + "not successful. " + "The input might not be valid.")); + } +}; + +REGISTER_LINALG_OP("SelfAdjointEig", (SelfAdjointEigOp), float); +REGISTER_LINALG_OP("SelfAdjointEig", (SelfAdjointEigOp), double); +REGISTER_LINALG_OP("BatchSelfAdjointEig", (SelfAdjointEigOp), + float); +REGISTER_LINALG_OP("BatchSelfAdjointEig", (SelfAdjointEigOp), + double); +} // namespace tensorflow diff --git a/tensorflow/core/ops/array_ops.cc b/tensorflow/core/ops/array_ops.cc index 8287d758f0b643180582d50c65841a3e0ede1034..99cd3e61ce4ee50411ad4b96d90dc2988580b434 100644 --- a/tensorflow/core/ops/array_ops.cc +++ b/tensorflow/core/ops/array_ops.cc @@ -326,7 +326,7 @@ If `indices` is a permutation and `len(indices) == params.shape[0]` then this operation will permute `params` accordingly.
- +
)doc"); diff --git a/tensorflow/core/ops/data_flow_ops.cc b/tensorflow/core/ops/data_flow_ops.cc index 59a787628995b7a219d5df5b21f299cbf2511ba5..c9d782f1c55610441980384537f3466884723dee 100644 --- a/tensorflow/core/ops/data_flow_ops.cc +++ b/tensorflow/core/ops/data_flow_ops.cc @@ -57,7 +57,7 @@ For example: outputs[1] = [30, 40]
- +
partitions: Any shape. Indices in the range `[0, num_partitions)`. @@ -108,7 +108,7 @@ For example: [51, 52], [61, 62]]
- +
)doc"); diff --git a/tensorflow/core/ops/linalg_ops.cc b/tensorflow/core/ops/linalg_ops.cc index 9b577e75622c5c7d6a5610034949ababeae24de5..a4b0b0aebf68a720e1f9620815078740a3d8078f 100644 --- a/tensorflow/core/ops/linalg_ops.cc +++ b/tensorflow/core/ops/linalg_ops.cc @@ -123,4 +123,41 @@ output: Shape is `[..., M, M]`. T: The type of values in the input and output. )doc"); +REGISTER_OP("SelfAdjointEig") + .Input("input: T") + .Output("output: T") + .Attr("T: {double, float}") + .Doc(R"doc( +Calculates the Eigen Decomposition of a square Self-Adjoint matrix. + +Only the lower-triangular part of the input will be used in this case. The +upper-triangular part will not be read. + +The result is a M+1 x M matrix whose first row is the eigenvalues, and +subsequent rows are eigenvectors. + +input: Shape is `[M, M]`. +output: Shape is `[M+1, M]`. +T: The type of values in the input and output. +)doc"); + +REGISTER_OP("BatchSelfAdjointEig") + .Input("input: T") + .Output("output: T") + .Attr("T: {double, float}") + .Doc(R"doc( +Calculates the Eigen Decomposition of a batch of square self-adjoint matrices. + +The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions +form square matrices, with the same constraints as the single matrix +SelfAdjointEig. + +The result is a '[..., M+1, M] matrix with [..., 0,:] containing the +eigenvalues, and subsequent [...,1:, :] containing the eigenvectors. + +input: Shape is `[..., M, M]`. +output: Shape is `[..., M+1, M]`. +T: The type of values in the input and output. +)doc"); + } // namespace tensorflow diff --git a/tensorflow/core/ops/math_ops.cc b/tensorflow/core/ops/math_ops.cc index a1f1db5f7f19eb0cb00b0461dcab4c71d4e578c4..61080bc763295f03ebe249d0de7247979361544c 100644 --- a/tensorflow/core/ops/math_ops.cc +++ b/tensorflow/core/ops/math_ops.cc @@ -649,7 +649,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s @@ -678,7 +678,7 @@ over `j` such that `segment_ids[j] == i` and `N` is the total number of values summed.
- +
segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s @@ -706,7 +706,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s @@ -734,7 +734,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s @@ -761,7 +761,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s @@ -796,7 +796,7 @@ If the sum is empty for a given segment ID `i`, `output[i] = 0`. `num_segments` should equal the number of distinct segment IDs.
- +
segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s diff --git a/tensorflow/core/ops/ops.pbtxt b/tensorflow/core/ops/ops.pbtxt index b529ef9c76a329c374ed4343dbbb72ed498b58c6..59a0ee62eeba52dd780c13a570de45e5f7b0c480 100644 --- a/tensorflow/core/ops/ops.pbtxt +++ b/tensorflow/core/ops/ops.pbtxt @@ -1224,6 +1224,32 @@ op { } summary: "Gradients for batch normalization." } +op { + name: "BatchSelfAdjointEig" + input_arg { + name: "input" + description: "Shape is `[..., M, M]`." + type_attr: "T" + } + output_arg { + name: "output" + description: "Shape is `[..., M+1, M]`." + type_attr: "T" + } + attr { + name: "T" + type: "type" + description: "The type of values in the input and output." + allowed_values { + list { + type: DT_DOUBLE + type: DT_FLOAT + } + } + } + summary: "Calculates the Eigen Decomposition of a batch of square self-adjoint matrices." + description: "The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions\nform square matrices, with the same constraints as the single matrix\nSelfAdjointEig.\n\nThe result is a \'[..., M+1, M] matrix with [..., 0,:] containing the\neigenvalues, and subsequent [...,1:, :] containing the eigenvectors." +} op { name: "BiasAdd" input_arg { @@ -6519,6 +6545,32 @@ op { summary: "Selects elements from `t` or `e`, depending on `condition`." description: "The `condition`, `t`, and `e` tensors must all have the same shape,\nand the output will also have that shape. The `condition` tensor acts\nas an element-wise mask that chooses, based on the value at each\nelement, whether the corresponding element in the output should be\ntaken from `t` (if true) or `e` (if false). For example:\n\nFor example:\n\n```prettyprint\n# \'condition\' tensor is [[True, False]\n# [True, False]]\n# \'t\' is [[1, 1],\n# [1, 1]]\n# \'e\' is [[2, 2],\n# [2, 2]]\nselect(condition, t, e) ==> [[1, 2],\n [1, 2]]\n```" } +op { + name: "SelfAdjointEig" + input_arg { + name: "input" + description: "Shape is `[M, M]`." + type_attr: "T" + } + output_arg { + name: "output" + description: "Shape is `[M+1, M]`." + type_attr: "T" + } + attr { + name: "T" + type: "type" + description: "The type of values in the input and output." + allowed_values { + list { + type: DT_DOUBLE + type: DT_FLOAT + } + } + } + summary: "Calculates the Eigen Decomposition of a square Self-Adjoint matrix." + description: "Only the lower-triangular part of the input will be used in this case. The\nupper-triangular part will not be read.\n\nThe result is a M+1 x M matrix whose first row is the eigenvalues, and\nsubsequent rows are eigenvectors." +} op { name: "Shape" input_arg { diff --git a/tensorflow/core/ops/state_ops.cc b/tensorflow/core/ops/state_ops.cc index 0855c167863ed44cf120250665c3b7186c603a52..a5a3d14a075fe781d7e6a01733eb04c4fef2b4ac 100644 --- a/tensorflow/core/ops/state_ops.cc +++ b/tensorflow/core/ops/state_ops.cc @@ -188,7 +188,7 @@ override earlier entries. Requires `updates.shape = indices.shape + ref.shape[1:]`.
- +
ref: Should be from a `Variable` node. @@ -231,7 +231,7 @@ the same location, their contributions add. Requires `updates.shape = indices.shape + ref.shape[1:]`.
- +
ref: Should be from a `Variable` node. @@ -272,7 +272,7 @@ the same location, their (negated) contributions add. Requires `updates.shape = indices.shape + ref.shape[1:]`.
- +
ref: Should be from a `Variable` node. diff --git a/tensorflow/examples/android/BUILD b/tensorflow/examples/android/BUILD index 872aeeb6a2fcfe117745a281f43aa06cfc40fd98..042e5e6e14725eadf12f27eb74a1ef9097bd96d4 100644 --- a/tensorflow/examples/android/BUILD +++ b/tensorflow/examples/android/BUILD @@ -1,7 +1,9 @@ # Description: # Tensorflow camera demo app for Android. -package(default_visibility = ["//visibility:public"]) +package( + default_visibility = ["//visibility:public"], +) licenses(["notice"]) # Apache 2.0 diff --git a/tensorflow/g3doc/api_docs/python/array_ops.md b/tensorflow/g3doc/api_docs/python/array_ops.md index 09485d671ede281c3685a26d450d93bf91f0c97b..d7638643002631c457ff5ac82a762cf54cd131dd 100644 --- a/tensorflow/g3doc/api_docs/python/array_ops.md +++ b/tensorflow/g3doc/api_docs/python/array_ops.md @@ -904,7 +904,7 @@ If `indices` is a permutation and `len(indices) == params.shape[0]` then this operation will permute `params` accordingly.
- +
##### Args: @@ -954,7 +954,7 @@ For example: outputs[1] = [30, 40]
- +
##### Args: @@ -1013,7 +1013,7 @@ For example: [51, 52], [61, 62]]
- +
##### Args: diff --git a/tensorflow/g3doc/api_docs/python/image.md b/tensorflow/g3doc/api_docs/python/image.md index 3d8c51d5204568da02aca546440f1749a82c81a5..e9fd048b3f751419b104a0c00bed89c110381983 100644 --- a/tensorflow/g3doc/api_docs/python/image.md +++ b/tensorflow/g3doc/api_docs/python/image.md @@ -192,7 +192,7 @@ The convenience function [`resize_images()`](#resize_images) supports both 4-D and 3-D tensors as input and output. 4-D tensors are for batches of images, 3-D tensors for individual images. -Other resizing Ops only support 3-D individual images as input: +Other resizing Ops only support 4-D batches of images as input: [`resize_area`](#resize_area), [`resize_bicubic`](#resize_bicubic), [`resize_bilinear`](#resize_bilinear), [`resize_nearest_neighbor`](#resize_nearest_neighbor). @@ -200,9 +200,9 @@ Other resizing Ops only support 3-D individual images as input: Example: ```python -# Decode a JPG image and resize it to 299 by 299. +# Decode a JPG image and resize it to 299 by 299 using default method. image = tf.image.decode_jpeg(...) -resized_image = tf.image.resize_bilinear(image, [299, 299]) +resized_image = tf.image.resize_images(image, 299, 299) ``` - - - diff --git a/tensorflow/g3doc/api_docs/python/index.md b/tensorflow/g3doc/api_docs/python/index.md index b46ef9ffbc69ea0dda8bac258f64e95d6e0b33f9..5f5ae1e5eaf4125a5499e09381a7f1c497943ac2 100644 --- a/tensorflow/g3doc/api_docs/python/index.md +++ b/tensorflow/g3doc/api_docs/python/index.md @@ -68,6 +68,7 @@ * [`uniform_unit_scaling_initializer`](../../api_docs/python/state_ops.md#uniform_unit_scaling_initializer) * [`update_checkpoint_state`](../../api_docs/python/state_ops.md#update_checkpoint_state) * [`Variable`](../../api_docs/python/state_ops.md#Variable) + * [`variable_op_scope`](../../api_docs/python/state_ops.md#variable_op_scope) * [`variable_scope`](../../api_docs/python/state_ops.md#variable_scope) * [`zeros_initializer`](../../api_docs/python/state_ops.md#zeros_initializer) @@ -356,20 +357,3 @@ * [`write_graph`](../../api_docs/python/train.md#write_graph) * [`zero_fraction`](../../api_docs/python/train.md#zero_fraction) - diff --git a/tensorflow/g3doc/api_docs/python/math_ops.md b/tensorflow/g3doc/api_docs/python/math_ops.md index 346c2fbf9569857f4f71ee667cdcbf1a52659dc7..0e985160384809bef0eacba5fa1ae40ebcf5804e 100644 --- a/tensorflow/g3doc/api_docs/python/math_ops.md +++ b/tensorflow/g3doc/api_docs/python/math_ops.md @@ -1340,7 +1340,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
##### Args: @@ -1374,7 +1374,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
##### Args: @@ -1408,7 +1408,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
##### Args: @@ -1441,7 +1441,7 @@ Computes a tensor such that that `segment_ids[j] == i`.
- +
##### Args: @@ -1476,7 +1476,7 @@ over `j` such that `segment_ids[j] == i` and `N` is the total number of values summed.
- +
##### Args: @@ -1517,7 +1517,7 @@ If the sum is empty for a given segment ID `i`, `output[i] = 0`. `num_segments` should equal the number of distinct segment IDs.
- +
##### Args: diff --git a/tensorflow/g3doc/api_docs/python/nn.md b/tensorflow/g3doc/api_docs/python/nn.md index 1ce124a8350bd9085823c1616b9c9dad9a9d86f2..1a0b2df9ff551e053b7ccfa67ca18b6e3db27640 100644 --- a/tensorflow/g3doc/api_docs/python/nn.md +++ b/tensorflow/g3doc/api_docs/python/nn.md @@ -59,7 +59,7 @@ Computes Rectified Linear 6: `min(max(features, 0), 6)`. Computes exponential linear: `exp(features) - 1` if < 0, `features` otherwise. -See [Fast and Aaccurate Deep Network Learning by Exponential Linear Units (ELUs) +See [Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs) ](http://arxiv.org/abs/1511.07289) ##### Args: @@ -872,7 +872,7 @@ See [Noise-contrastive estimation: A new estimation principle for unnormalized statistical models] (http://www.jmlr.org/proceedings/papers/v9/gutmann10a/gutmann10a.pdf). Also see our [Candidate Sampling Algorithms Reference] -(http://www.tensorflow.org/extras/candidate_sampling.pdf) +(../../extras/candidate_sampling.pdf) Note: In the case where `num_true` > 1, we assign to each target class the target probability 1 / `num_true` so that the target probabilities @@ -906,7 +906,7 @@ with an otherwise unused class. `True`, this is a "Sampled Logistic" loss instead of NCE, and we are learning to generate log-odds instead of log probabilities. See our [Candidate Sampling Algorithms Reference] - (http://www.tensorflow.org/extras/candidate_sampling.pdf). + (../../extras/candidate_sampling.pdf). Default is False. * `name`: A name for the operation (optional). @@ -931,7 +931,7 @@ At inference time, you can compute full softmax probabilities with the expression `tf.nn.softmax(tf.matmul(inputs, weights) + biases)`. See our [Candidate Sampling Algorithms Reference] -(http://www.tensorflow.org/extras/candidate_sampling.pdf) +(../../extras/candidate_sampling.pdf) Also see Section 3 of http://arxiv.org/abs/1412.2007 for the math. diff --git a/tensorflow/g3doc/api_docs/python/state_ops.md b/tensorflow/g3doc/api_docs/python/state_ops.md index 82c2047e2c9c9281f0dfb2ea8a9a76c98c5f77ce..de8d81f9598fe0513ad9261164cd09195df1ed67 100644 --- a/tensorflow/g3doc/api_docs/python/state_ops.md +++ b/tensorflow/g3doc/api_docs/python/state_ops.md @@ -913,6 +913,58 @@ the constructor is used. If that one is `None` too, a Returns the current variable scope. +- - - + +### `tf.variable_op_scope(values, name, default_name, initializer=None)` {#variable_op_scope} + +Returns a context manager for defining an op that creates variables. + +This context manager validates that the given `values` are from the +same graph, ensures that that graph is the default graph, and pushes a +name scope and a variable scope. + +If `name` is not None, it is used as is in the variable scope. If `name` +is None, then `default_name` is used. In that case, if the same name has been +previously used in the same scope, it will made unique be appending `_N` to +it. + +This is intended to be used when defining generic ops and so reuse is always +inherited. + +For example, to define a new Python op called `my_op_with_vars`: + +```python +def my_op_with_vars(a, b, name=None): + with tf.variable_op_scope([a, b], name, "MyOp") as scope: + a = tf.convert_to_tensor(a, name="a") + b = tf.convert_to_tensor(b, name="b") + c = tf.get_variable('c') + # Define some computation that uses `a`, `b`, and `c`. + return foo_op(..., name=scope) +``` + +##### Args: + + +* `values`: The list of `Tensor` arguments that are passed to the op function. +* `name`: The name argument that is passed to the op function, this name is not + uniquified in the variable scope. +* `default_name`: The default name to use if the `name` argument is `None`, this + name will be uniquified. +* `initializer`: A default initializer to pass to variable scope. + +##### Returns: + + A context manager for use in defining a Python op. + +##### Raises: + + +* `ValueError`: when trying to reuse within a create scope, or create within + a reuse scope, or if reuse is not `None` or `True`. +* `TypeError`: when the types of some arguments are not appropriate. + + - - - ### `tf.variable_scope(name_or_scope, reuse=None, initializer=None)` {#variable_scope} @@ -983,7 +1035,7 @@ then all its sub-scopes become reusing as well. well as all sub-scopes; if `None`, we just inherit the parent scope reuse. * `initializer`: default initializer for variables within this scope. -##### Yields: +##### Returns: A scope that can be to captured and reused. @@ -1167,7 +1219,7 @@ override earlier entries. Requires `updates.shape = indices.shape + ref.shape[1:]`.
- +
##### Args: @@ -1215,7 +1267,7 @@ the same location, their contributions add. Requires `updates.shape = indices.shape + ref.shape[1:]`.
- +
##### Args: @@ -1262,7 +1314,7 @@ the same location, their (negated) contributions add. Requires `updates.shape = indices.shape + ref.shape[1:]`.
- +
##### Args: diff --git a/tensorflow/g3doc/get_started/index.md b/tensorflow/g3doc/get_started/index.md index e9e0bcd0cbc814dedaa15dc3c1a6189f87ae9a80..c00954000eb9f3bcb9cca8e0a6f909855069c929 100644 --- a/tensorflow/g3doc/get_started/index.md +++ b/tensorflow/g3doc/get_started/index.md @@ -60,10 +60,10 @@ suggest skimming blue, then red.

Images licensed CC BY-SA 4.0; original by W. Carter

@@ -77,12 +77,3 @@ TensorFlow features. * [Download and Setup](../get_started/os_setup.md) * [Basic Usage](../get_started/basic_usage.md) * [TensorFlow Mechanics 101](../tutorials/mnist/tf/index.md) - - - - diff --git a/tensorflow/g3doc/how_tos/graph_viz/index.md b/tensorflow/g3doc/how_tos/graph_viz/index.md index fd66e9ce872e8f31d90d00d8ddae3a931ce3ae10..fa79b7fa87410261baf9f91f81534eb20b211d0b 100644 --- a/tensorflow/g3doc/how_tos/graph_viz/index.md +++ b/tensorflow/g3doc/how_tos/graph_viz/index.md @@ -2,7 +2,7 @@ TensorFlow computation graphs are powerful but complicated. The graph visualization can help you understand and debug them. Here's an example of the visualization at work. -![Visualization of a TensorFlow graph](./graph_vis_animation.gif "Visualization of a TensorFlow graph") +![Visualization of a TensorFlow graph](../../images/graph_vis_animation.gif "Visualization of a TensorFlow graph") *Visualization of a TensorFlow graph.* To see your own graph, run TensorBoard pointing it to the log directory of the job, click on the graph tab on the top pane and select the appropriate run using the menu at the upper left corner. For in depth information on how to run TensorBoard and make sure you are logging all the necessary information, see [TensorBoard: Visualizing Learning](../../how_tos/summaries_and_tensorboard/index.md). @@ -43,10 +43,10 @@ expanded states. @@ -86,10 +86,10 @@ information since these nodes are usually related to bookkeeping functions.
- Unexpanded name scope + Unexpanded name scope - Expanded name scope + Expanded name scope
@@ -111,10 +111,10 @@ with hierarchical nodes, double-clicking expands the series.
- conv_1 is part of the main graph + conv_1 is part of the main graph - save is extracted as auxiliary node + save is extracted as auxiliary node
@@ -132,15 +132,15 @@ for constants and summary nodes. To summarize, here's a table of node symbols: Symbol | Meaning --- | --- -![Name scope](./namespace_node.png "Name scope") | *High-level* node representing a name scope. Double-click to expand a high-level node. -![Sequence of unconnected nodes](./horizontal_stack.png "Sequence of unconnected nodes") | Sequence of numbered nodes that are not connected to each other. -![Sequence of connected nodes](./vertical_stack.png "Sequence of connected nodes") | Sequence of numbered nodes that are connected to each other. -![Operation node](./op_node.png "Operation node") | An individual operation node. -![Constant node](./constant.png "Constant node") | A constant. -![Summary node](./summary.png "Summary node") | A summary node. -![Data flow edge](./dataflow_edge.png "Data flow edge") | Edge showing the data flow between operations. -![Control dependency edge](./control_edge.png "Control dependency edge") | Edge showing the control dependency between operations. -![Reference edge](./reference_edge.png "Reference edge") | A reference edge showing that the outgoing operation node can mutate the incoming tensor. +![Name scope](../../images/namespace_node.png "Name scope") | *High-level* node representing a name scope. Double-click to expand a high-level node. +![Sequence of unconnected nodes](../../images/horizontal_stack.png "Sequence of unconnected nodes") | Sequence of numbered nodes that are not connected to each other. +![Sequence of connected nodes](../../images/vertical_stack.png "Sequence of connected nodes") | Sequence of numbered nodes that are connected to each other. +![Operation node](../../images/op_node.png "Operation node") | An individual operation node. +![Constant node](../../images/constant.png "Constant node") | A constant. +![Summary node](../../images/summary.png "Summary node") | A summary node. +![Data flow edge](../../images/dataflow_edge.png "Data flow edge") | Edge showing the data flow between operations. +![Control dependency edge](../../images/control_edge.png "Control dependency edge") | Edge showing the control dependency between operations. +![Reference edge](../../images/reference_edge.png "Reference edge") | A reference edge showing that the outgoing operation node can mutate the incoming tensor. ## Interaction @@ -158,10 +158,10 @@ right corner of the visualization.
- Sequence of nodes + Sequence of nodes - Expanded sequence of nodes + Expanded sequence of nodes
@@ -194,10 +194,10 @@ The images below give an illustration for a piece of a real-life graph.
- Info card of a name scope + Info card of a name scope - Info card of operation node + Info card of operation node
diff --git a/tensorflow/g3doc/how_tos/index.md b/tensorflow/g3doc/how_tos/index.md index c63a4e19b811c5929460d05684cff3adc7e4baa4..748ecfd398b5a5537cfddc361eaa3c9bb026b54a 100644 --- a/tensorflow/g3doc/how_tos/index.md +++ b/tensorflow/g3doc/how_tos/index.md @@ -84,19 +84,3 @@ different locations in the model construction code. The "Variable Scope" mechanism is designed to facilitate that. [View Tutorial](../how_tos/variable_scope/index.md) - - - diff --git a/tensorflow/g3doc/how_tos/reading_data/index.md b/tensorflow/g3doc/how_tos/reading_data/index.md index 907652952a99c26c93b2bea17c4486b54c9bbcfa..e8ad141fea90a8d57f2aa77819197d031bd3f664 100644 --- a/tensorflow/g3doc/how_tos/reading_data/index.md +++ b/tensorflow/g3doc/how_tos/reading_data/index.md @@ -311,7 +311,7 @@ operations, so that our training loop can dequeue examples from the example queue.
- +
The helpers in `tf.train` that create these queues and enqueuing operations add diff --git a/tensorflow/g3doc/how_tos/summaries_and_tensorboard/index.md b/tensorflow/g3doc/how_tos/summaries_and_tensorboard/index.md index 23ca9712247e444b2f22d9d96accdb7878c7423b..a102344a9aefd886f5eca7e5db5c823c9c4298df 100644 --- a/tensorflow/g3doc/how_tos/summaries_and_tensorboard/index.md +++ b/tensorflow/g3doc/how_tos/summaries_and_tensorboard/index.md @@ -8,7 +8,7 @@ your TensorFlow graph, plot quantitative metrics about the execution of your graph, and show additional data like images that pass through it. When TensorBoard is fully configured, it looks like this: -![MNIST TensorBoard](./mnist_tensorboard.png "MNIST TensorBoard") +![MNIST TensorBoard](../../images/mnist_tensorboard.png "MNIST TensorBoard") ## Serializing the data diff --git a/tensorflow/g3doc/how_tos/threading_and_queues/index.md b/tensorflow/g3doc/how_tos/threading_and_queues/index.md index 6b71310e13bf72bd821f280352169af0d8d756be..68bb7626fabef67db264a6313e58fe600befbf4d 100644 --- a/tensorflow/g3doc/how_tos/threading_and_queues/index.md +++ b/tensorflow/g3doc/how_tos/threading_and_queues/index.md @@ -14,7 +14,7 @@ that takes an item off the queue, adds one to that item, and puts it back on the end of the queue. Slowly, the numbers on the queue increase.
- +
`Enqueue`, `EnqueueMany`, and `Dequeue` are special nodes. They take a pointer diff --git a/tensorflow/g3doc/resources/index.md b/tensorflow/g3doc/resources/index.md index 3ae48966560ffdb04fe8d1642fdf8fd50421d595..018ad4482203814cef729c52b8844d15b50e6ab6 100644 --- a/tensorflow/g3doc/resources/index.md +++ b/tensorflow/g3doc/resources/index.md @@ -55,14 +55,3 @@ https://github.com/tensorflow/tensorflow/issues) on GitHub. If you need help with using TensorFlow, please do not use the issue tracker for that. Instead, direct your questions to [Stack Overflow](https://stackoverflow.com/questions/tagged/tensorflow). - - - diff --git a/tensorflow/g3doc/tutorials/deep_cnn/index.md b/tensorflow/g3doc/tutorials/deep_cnn/index.md index 59d106680eb6ee691c322f133ebfc08cd8908c3c..66614d402fa8a1effe25878a9e67fb93ae15301b 100644 --- a/tensorflow/g3doc/tutorials/deep_cnn/index.md +++ b/tensorflow/g3doc/tutorials/deep_cnn/index.md @@ -9,7 +9,7 @@ CIFAR-10 classification is a common benchmark problem in machine learning. The problem is to classify RGB 32x32 pixel images across 10 categories: ```airplane, automobile, bird, cat, deer, dog, frog, horse, ship, and truck.``` -![CIFAR-10 Samples](./cifar_samples.png "CIFAR-10 Samples, from http://www.cs.toronto.edu/~kriz/cifar.html") +![CIFAR-10 Samples](../../images/cifar_samples.png "CIFAR-10 Samples, from http://www.cs.toronto.edu/~kriz/cifar.html") For more details refer to the [CIFAR-10 page](http://www.cs.toronto.edu/~kriz/cifar.html) and a [Tech Report](http://www.cs.toronto.edu/~kriz/learning-features-2009-TR.pdf) @@ -135,7 +135,7 @@ so that we may visualize them in TensorBoard. This is a good practice to verify that inputs are built correctly.
- +
Reading images from disk and distorting them can use a non-trivial amount of @@ -164,7 +164,7 @@ Layer Name | Description Here is a graph generated from TensorBoard describing the inference operation:
- +
> **EXERCISE**: The output of `inference` are un-normalized logits. Try editing @@ -199,7 +199,7 @@ loss and all these weight decay terms, as returned by the `loss()` function. We visualize it in TensorBoard with a [`scalar_summary`](../../api_docs/python/train.md#scalar_summary): -![CIFAR-10 Loss](./cifar_loss.png "CIFAR-10 Total Loss") +![CIFAR-10 Loss](../../images/cifar_loss.png "CIFAR-10 Total Loss") We train the model using standard [gradient descent](https://en.wikipedia.org/wiki/Gradient_descent) @@ -208,7 +208,7 @@ with a learning rate that [exponentially decays](../../api_docs/python/train.md#exponential_decay) over time. -![CIFAR-10 Learning Rate Decay](./cifar_lr_decay.png "CIFAR-10 Learning Rate Decay") +![CIFAR-10 Learning Rate Decay](../../images/cifar_lr_decay.png "CIFAR-10 Learning Rate Decay") The `train()` function adds the operations needed to minimize the objective by calculating the gradient and updating the learned variables (see @@ -289,8 +289,8 @@ For instance, we can watch how the distribution of activations and degree of sparsity in `local3` features evolve during training:
- - + +
Individual loss functions, as well as the total loss, are particularly @@ -372,7 +372,7 @@ processing a batch of data. Here is a diagram of this model:
- +
Note that each GPU computes inference as well as the gradients for a unique diff --git a/tensorflow/g3doc/tutorials/index.md b/tensorflow/g3doc/tutorials/index.md index 84215c72f1d1d745d7c9b43de177050b46d54391..ee22806f6907ea2b6d636a790a16ed9853f775bd 100644 --- a/tensorflow/g3doc/tutorials/index.md +++ b/tensorflow/g3doc/tutorials/index.md @@ -107,19 +107,3 @@ visual hallucination software. COMING SOON - - - diff --git a/tensorflow/g3doc/tutorials/mandelbrot/index.md b/tensorflow/g3doc/tutorials/mandelbrot/index.md index ee8a95d12b1ea7536fdb7b01e86fb10faf93d8f1..d88e7b5502df90c9dfc353f463e24ee30739e75e 100755 --- a/tensorflow/g3doc/tutorials/mandelbrot/index.md +++ b/tensorflow/g3doc/tutorials/mandelbrot/index.md @@ -110,7 +110,7 @@ Let's see what we've got. DisplayFractal(ns.eval()) ``` -![jpeg](mandelbrot_output.jpg) +![jpeg](../../images/mandelbrot_output.jpg) Not bad! diff --git a/tensorflow/g3doc/tutorials/mnist/beginners/index.md b/tensorflow/g3doc/tutorials/mnist/beginners/index.md index 569cbef9e9103e3ff930e3cdf5570f04d4404e61..99453d065d491628d33a1557f69829801a84687c 100644 --- a/tensorflow/g3doc/tutorials/mnist/beginners/index.md +++ b/tensorflow/g3doc/tutorials/mnist/beginners/index.md @@ -3,7 +3,7 @@ *This tutorial is intended for readers who are new to both machine learning and TensorFlow. If you already know what MNIST is, and what softmax (multinomial logistic) regression is, -you might prefer this [faster paced tutorial](../../../tutorials/mnist/pros/index.md).* +you might prefer this [faster paced tutorial](../pros/index.md).* When one learns how to program, there's a tradition that the first thing you do is print "Hello World." Just like programming has Hello World, machine learning @@ -13,7 +13,7 @@ MNIST is a simple computer vision dataset. It consists of images of handwritten digits like these:
- +
It also includes labels for each image, telling us which digit it is. For @@ -61,7 +61,7 @@ Each image is 28 pixels by 28 pixels. We can interpret this as a big array of numbers:
- +
We can flatten this array into a vector of 28x28 = 784 numbers. It doesn't @@ -83,7 +83,7 @@ the pixel intensity between 0 and 1, for a particular pixel in a particular image.
- +
The corresponding labels in MNIST are numbers between 0 and 9, describing @@ -97,7 +97,7 @@ Consequently, `mnist.train.labels` is a `[55000, 10]` array of floats.
- +
We're now ready to actually make our model! @@ -128,7 +128,7 @@ classes. Red represents negative weights, while blue represents positive weights.
- +
We also add some extra evidence called a bias. Basically, we want to be able @@ -175,13 +175,13 @@ although with a lot more \\(x\\)s. For each output, we compute a weighted sum of the \\(x\\)s, add a bias, and then apply softmax.
- +
If we write that out as equations, we get:
- +
We can "vectorize" this procedure, turning it into a matrix multiplication @@ -189,7 +189,7 @@ and vector addition. This is helpful for computational efficiency. (It's also a useful way to think.)
- +
More compactly, we can just write: diff --git a/tensorflow/g3doc/tutorials/mnist/download/index.md b/tensorflow/g3doc/tutorials/mnist/download/index.md index 70e6e37ef66cd58957d8daa412ae993ec8ff8198..3cb9528f345b2eadf04e116b3195beff305d8d37 100644 --- a/tensorflow/g3doc/tutorials/mnist/download/index.md +++ b/tensorflow/g3doc/tutorials/mnist/download/index.md @@ -19,7 +19,7 @@ MNIST is a classic problem in machine learning. The problem is to look at greyscale 28x28 pixel images of handwritten digits and determine which digit the image represents, for all the digits from zero to nine. -![MNIST Digits](../tf/mnist_digits.png "MNIST Digits") +![MNIST Digits](../../../images/mnist_digits.png "MNIST Digits") For more information, refer to [Yann LeCun's MNIST page](http://yann.lecun.com/exdb/mnist/) or [Chris Olah's visualizations of MNIST](http://colah.github.io/posts/2014-10-Visualizing-MNIST/). diff --git a/tensorflow/g3doc/tutorials/mnist/input_data.py b/tensorflow/g3doc/tutorials/mnist/input_data.py index 3078137f2e75b4c58a2301eb46ab9fef5878fa17..ae3727c82e0f9d5c3fd400ce6aa1ea16ce1b7cc2 100644 --- a/tensorflow/g3doc/tutorials/mnist/input_data.py +++ b/tensorflow/g3doc/tutorials/mnist/input_data.py @@ -42,7 +42,7 @@ def maybe_download(filename, work_directory): def _read32(bytestream): dt = numpy.dtype(numpy.uint32).newbyteorder('>') - return numpy.frombuffer(bytestream.read(4), dtype=dt) + return numpy.frombuffer(bytestream.read(4), dtype=dt)[0] def extract_images(filename): diff --git a/tensorflow/g3doc/tutorials/mnist/pros/index.md b/tensorflow/g3doc/tutorials/mnist/pros/index.md index 6df9e430a39fd69e8381c3307ede9b184297c480..4d8b5e84bd65400601635b912c99512a3c325d18 100644 --- a/tensorflow/g3doc/tutorials/mnist/pros/index.md +++ b/tensorflow/g3doc/tutorials/mnist/pros/index.md @@ -9,7 +9,7 @@ while constructing a deep convolutional MNIST classifier. *This introduction assumes familiarity with neural networks and the MNIST dataset. If you don't have a background with them, check out the -[introduction for beginners](../../../tutorials/mnist/beginners/index.md).* +[introduction for beginners](../beginners/index.md).* ## Setup diff --git a/tensorflow/g3doc/tutorials/mnist/tf/index.md b/tensorflow/g3doc/tutorials/mnist/tf/index.md index f7cd3b527c15909d4a1bc97b9ba0baab8c55861f..373b8968c54b3ebbb47e5af687ea4e1e2ff804ea 100644 --- a/tensorflow/g3doc/tutorials/mnist/tf/index.md +++ b/tensorflow/g3doc/tutorials/mnist/tf/index.md @@ -31,7 +31,7 @@ MNIST is a classic problem in machine learning. The problem is to look at greyscale 28x28 pixel images of handwritten digits and determine which digit the image represents, for all the digits from zero to nine. -![MNIST Digits](./mnist_digits.png "MNIST Digits") +![MNIST Digits](../../../images/mnist_digits.png "MNIST Digits") For more information, refer to [Yann LeCun's MNIST page](http://yann.lecun.com/exdb/mnist/) or [Chris Olah's visualizations of MNIST](http://colah.github.io/posts/2014-10-Visualizing-MNIST/). @@ -90,7 +90,7 @@ loss. and apply gradients.
- +
### Inference @@ -401,7 +401,7 @@ summary_writer.add_summary(summary_str, step) When the events files are written, TensorBoard may be run against the training folder to display the values from the summaries. -![MNIST TensorBoard](./mnist_tensorboard.png "MNIST TensorBoard") +![MNIST TensorBoard](../../../images/mnist_tensorboard.png "MNIST TensorBoard") **NOTE**: For more info about how to build and run Tensorboard, please see the accompanying tutorial [Tensorboard: Visualizing Your Training](../../../how_tos/summaries_and_tensorboard/index.md). diff --git a/tensorflow/g3doc/tutorials/pdes/index.md b/tensorflow/g3doc/tutorials/pdes/index.md index ca6f84985e855a74e5caf9f3d9f9bad2b5bd600b..9d922320cb84a4610a315ffb086f2a423f3f0261 100755 --- a/tensorflow/g3doc/tutorials/pdes/index.md +++ b/tensorflow/g3doc/tutorials/pdes/index.md @@ -92,7 +92,7 @@ for n in range(40): DisplayArray(u_init, rng=[-0.1, 0.1]) ``` -![jpeg](pde_output_1.jpg) +![jpeg](../../images/pde_output_1.jpg) Now let's specify the details of the differential equation. @@ -137,7 +137,7 @@ for i in range(1000): DisplayArray(U.eval(), rng=[-0.1, 0.1]) ``` -![jpeg](pde_output_2.jpg) +![jpeg](../../images/pde_output_2.jpg) Look! Ripples! diff --git a/tensorflow/g3doc/tutorials/seq2seq/index.md b/tensorflow/g3doc/tutorials/seq2seq/index.md index 6cbbf6a3bd1d2986afea2b94d597abbd90a69c11..63542dc6bad58dafe07b9e896140f1e1f66853f7 100644 --- a/tensorflow/g3doc/tutorials/seq2seq/index.md +++ b/tensorflow/g3doc/tutorials/seq2seq/index.md @@ -41,7 +41,7 @@ processes the input and a *decoder* that generates the output. This basic architecture is depicted below.
- +
Each box in the picture above represents a cell of the RNN, most commonly @@ -61,7 +61,7 @@ decoding step. A multi-layer sequence-to-sequence network with LSTM cells and attention mechanism in the decoder looks like this.
- +
## TensorFlow seq2seq Library diff --git a/tensorflow/g3doc/tutorials/word2vec/index.md b/tensorflow/g3doc/tutorials/word2vec/index.md index 3dc632c1bc0376357981f02fe9af0a7f28339f6c..f026d8c5b59f069cab65f88d295d4b55eaa2c04d 100644 --- a/tensorflow/g3doc/tutorials/word2vec/index.md +++ b/tensorflow/g3doc/tutorials/word2vec/index.md @@ -51,7 +51,7 @@ means that we may need more data in order to successfully train statistical models. Using vector representations can overcome some of these obstacles.
- +
[Vector space models](https://en.wikipedia.org/wiki/Vector_space_model) (VSMs) @@ -124,7 +124,7 @@ probability using the score for all other \\(V\\) words \\(w'\\) in the current context \\(h\\), *at every training step*.
- +
On the other hand, for feature learning in word2vec we do not need a full @@ -135,7 +135,7 @@ same context. We illustrate this below for a CBOW model. For skip-gram the direction is simply inverted.
- +
Mathematically, the objective (for each example) is to maximize @@ -232,7 +232,7 @@ below (see also for example [Mikolov et al., 2013](http://www.aclweb.org/anthology/N13-1090)).
- +
This explains why these vectors are also useful as features for many canonical @@ -329,7 +329,7 @@ After training has finished we can visualize the learned embeddings using t-SNE.
- +
Et voila! As expected, words that are similar end up clustering nearby each diff --git a/tensorflow/python/BUILD b/tensorflow/python/BUILD index 0c75bd8dc725b5438fcc845605ad346b667d0503..1fd5c539b82f1ea7f6e0be70bc140d14a23ec82a 100644 --- a/tensorflow/python/BUILD +++ b/tensorflow/python/BUILD @@ -1,7 +1,9 @@ # Description: # Python support for TensorFlow. -package(default_visibility = ["//tensorflow:internal"]) +package( + default_visibility = ["//tensorflow:internal"], +) licenses(["notice"]) # Apache 2.0 @@ -49,13 +51,23 @@ py_library( ) py_tests( - name = "platform_tests", + name = "default_platform_tests", srcs = glob(["platform/default/*_test.py"]), additional_deps = [ ":platform", ":platform_test", ], - prefix = "platform", + prefix = "default_platform", +) + +py_tests( + name = "google_platform_tests", + srcs = glob(["platform/google/*_test.py"]), + additional_deps = [ + ":platform", + ":platform_test", + ], + prefix = "google_platform", ) cc_library( @@ -843,6 +855,7 @@ cpu_only_kernel_test_list = glob([ "kernel_tests/random_shuffle_queue_test.py", "kernel_tests/save_restore_ops_test.py", "kernel_tests/segment_reduction_ops_test.py", + "kernel_tests/self_adjoint_eig_op_test.py", "kernel_tests/sparse_concat_op_test.py", "kernel_tests/sparse_matmul_op_test.py", "kernel_tests/sparse_reorder_op_test.py", diff --git a/tensorflow/python/framework/docs.py b/tensorflow/python/framework/docs.py index 145b8049ad2aa57d0b79ac2349d7d1307c94d957..38e72deb308f72c17bea10444a86eec26dc7812a 100644 --- a/tensorflow/python/framework/docs.py +++ b/tensorflow/python/framework/docs.py @@ -98,12 +98,6 @@ class Index(Document): print(" * %s" % link, file=f) print("", file=f) - # actually include the files right here - print('", file=f) - def collect_members(module_to_name): """Collect all symbols from a list of modules. diff --git a/tensorflow/python/kernel_tests/batch_matmul_op_test.py b/tensorflow/python/kernel_tests/batch_matmul_op_test.py index 809b23bd7d59762db289b4daaec272529c28040a..25e0abe01428c928422955c874ce56a53a437a05 100644 --- a/tensorflow/python/kernel_tests/batch_matmul_op_test.py +++ b/tensorflow/python/kernel_tests/batch_matmul_op_test.py @@ -151,14 +151,14 @@ class BatchMatmulOpTest(tf.test.TestCase): self._randComplex([10, 30, 75]), True, True) def testEmpty(self): - self._compare(np.empty([0, 3, 2]).astype(np.float32), - np.empty([0, 2, 4]).astype(np.float32), False, False) - self._compare(np.empty([3, 2, 0]).astype(np.float32), - np.empty([3, 0, 5]).astype(np.float32), False, False) - self._compare(np.empty([3, 0, 2]).astype(np.float32), - np.empty([3, 2, 5]).astype(np.float32), False, False) - self._compare(np.empty([3, 3, 2]).astype(np.float32), - np.empty([3, 2, 0]).astype(np.float32), False, False) + self._compare(np.zeros([0, 3, 2]).astype(np.float32), + np.zeros([0, 2, 4]).astype(np.float32), False, False) + self._compare(np.zeros([3, 2, 0]).astype(np.float32), + np.zeros([3, 0, 5]).astype(np.float32), False, False) + self._compare(np.zeros([3, 0, 2]).astype(np.float32), + np.zeros([3, 2, 5]).astype(np.float32), False, False) + self._compare(np.zeros([3, 3, 2]).astype(np.float32), + np.zeros([3, 2, 0]).astype(np.float32), False, False) class BatchMatmulGradientTest(tf.test.TestCase): diff --git a/tensorflow/python/kernel_tests/reduction_ops_test.py b/tensorflow/python/kernel_tests/reduction_ops_test.py index 3867034dc16a6705eb2854e9843b72d46c47c596..7ff3851da7d8173eebe36d45ce24d8f963bad991 100644 --- a/tensorflow/python/kernel_tests/reduction_ops_test.py +++ b/tensorflow/python/kernel_tests/reduction_ops_test.py @@ -115,7 +115,7 @@ class SumReductionTest(tf.test.TestCase): self._compareAll(np_arr, [1, 2, 3, 4]) self._compareAll(np_arr, [0, 1, 2, 3, 4]) - # Simple tests for various tf. + # Simple tests for various types. def testDoubleReduce1D(self): np_arr = np.arange(1, 6).reshape([5]).astype(np.float64) self._compare(np_arr, [], False) @@ -126,6 +126,11 @@ class SumReductionTest(tf.test.TestCase): self._compare(np_arr, [], False) self._compare(np_arr, [0], False) + def testComplex64Reduce1D(self): + np_arr = np.arange(1, 6).reshape([5]).astype(np.complex64) + self._compare(np_arr, [], False) + self._compare(np_arr, [0], False) + def testInvalidIndex(self): np_arr = np.arange(0, 10).reshape([2, 5]).astype(np.float32) input_tensor = tf.convert_to_tensor(np_arr) diff --git a/tensorflow/python/kernel_tests/self_adjoint_eig_op_test.py b/tensorflow/python/kernel_tests/self_adjoint_eig_op_test.py new file mode 100644 index 0000000000000000000000000000000000000000..c6a42296c405e4543575712e3a6267d04f4f9b55 --- /dev/null +++ b/tensorflow/python/kernel_tests/self_adjoint_eig_op_test.py @@ -0,0 +1,105 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for tensorflow.ops.tf.self_adjoint_eig.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +# pylint: disable=g-bad-import-order,wildcard-import,unused-import + +import tensorflow.python.platform +import numpy as np +from six.moves import xrange # pylint: disable=redefined-builtin +import tensorflow as tf + + +class SelfAdjointEigOpTest(tf.test.TestCase): + + def _testEigs(self, x, d, tf_ans, use_gpu=False): + np_eig_val, np_eig_vec = np.linalg.eig(x) + + # First check the eigenvalues + self.assertAllClose(sorted(np_eig_val), sorted(tf_ans[0, :])) + + # need to make things canonical. This test may still fail in case there are + # two equal eigenvalues, so that there is indeterminacy in the eigenvectors. + # For now, assume that we will only test matrices with distinct eigenvalues. + np_arg = np.argsort(np_eig_val) + tf_arg = np.argsort(tf_ans[0, :]) + + np_eig_vecs_sorted = np.array([np_eig_vec[:, i] for i in np_arg]).T + tf_eig_vecs_sorted = np.array([tf_ans[1:, i] for i in tf_arg]).T + np_eig_vecs_signed_sorted = np.array([np_eig_vecs_sorted[:, i] * + np.sign(np_eig_vecs_sorted[0, i]) + for i in xrange(d)]).T + tf_eig_vecs_signed_sorted = np.array([tf_eig_vecs_sorted[:, i] * + np.sign(tf_eig_vecs_sorted[0, i]) + for i in xrange(d)]).T + self.assertAllClose(np_eig_vecs_signed_sorted, tf_eig_vecs_signed_sorted) + + def _compareSelfAdjointEig(self, x, use_gpu=False): + with self.test_session() as sess: + tf_eig = tf.self_adjoint_eig(tf.constant(x)) + tf_eig_out = sess.run([tf_eig])[0] + + d, _ = x.shape + self.assertEqual([d+1, d], tf_eig.get_shape().dims) + self._testEigs(x, d, tf_eig_out, use_gpu) + + def _compareBatchSelfAdjointEigRank3(self, x, use_gpu=False): + with self.test_session() as sess: + tf_eig = tf.batch_self_adjoint_eig(tf.constant(x)) + tf_out = sess.run([tf_eig])[0] + dlist = x.shape + d = dlist[-2] + + self.assertEqual([d+1, d], tf_eig.get_shape().dims[-2:]) + # not testing the values. + self.assertEqual(dlist[0], tf_eig.get_shape().dims[0]) + + for i in xrange(dlist[0]): + self._testEigs(x[i], d, tf_out[i]) + + def testBasic(self): + self._compareSelfAdjointEig( + np.array([[3., 0., 1.], [0., 2., -2.], [1., -2., 3.]])) + + def testBatch(self): + simple_array = np.array([[[1., 0.], [0., 5.]]]) # shape (1, 2, 2) + self._compareBatchSelfAdjointEigRank3(simple_array) + self._compareBatchSelfAdjointEigRank3(np.vstack((simple_array, simple_array))) + odd_sized_array = np.array([[[3., 0., 1.], [0., 2., -2.], [1., -2., 3.]]]) + self._compareBatchSelfAdjointEigRank3( + np.vstack((odd_sized_array, odd_sized_array))) + + # Generate random positive-definite matrices. + matrices = np.random.rand(10, 5, 5) + for i in xrange(10): + matrices[i] = np.dot(matrices[i].T, matrices[i]) + self._compareBatchSelfAdjointEigRank3(matrices) + + def testNonSquareMatrix(self): + with self.assertRaises(ValueError): + tf.self_adjoint_eig(tf.constant(np.array([[1., 2., 3.], [3., 4., 5.]]))) + + def testWrongDimensions(self): + tensor3 = tf.constant([1., 2.]) + with self.assertRaises(ValueError): + tf.self_adjoint_eig(tensor3) + + +if __name__ == "__main__": + tf.test.main() diff --git a/tensorflow/python/ops/linalg_ops.py b/tensorflow/python/ops/linalg_ops.py index 953835d55e689a3b71fd72a58eb4e2295f685358..457bc894b4ac5478a6b6f75260d874fc885ddfba 100644 --- a/tensorflow/python/ops/linalg_ops.py +++ b/tensorflow/python/ops/linalg_ops.py @@ -79,3 +79,24 @@ def _BatchMatrixInverseShape(op): # The matrices in the batch must be square. input_shape[-1].assert_is_compatible_with(input_shape[-2]) return [input_shape] + + +@ops.RegisterShape("SelfAdjointEig") +def _SelfAdjointEigShape(op): + input_shape = op.inputs[0].get_shape().with_rank(2) + # The matrix must be square. + input_shape[0].assert_is_compatible_with(input_shape[1]) + d = input_shape.dims[0] + out_shape = tensor_shape.TensorShape([d+1, d]) + return [out_shape] + + +@ops.RegisterShape("BatchSelfAdjointEig") +def _BatchSelfAdjointEigShape(op): + input_shape = op.inputs[0].get_shape().with_rank_at_least(3) + # The matrices in the batch must be square. + input_shape[-1].assert_is_compatible_with(input_shape[-2]) + dlist = input_shape.dims + dlist[-2] += 1 + out_shape = tensor_shape.TensorShape(dlist) + return [out_shape] diff --git a/tensorflow/python/ops/math_ops.py b/tensorflow/python/ops/math_ops.py index 2555b4ba17887754db4a1adadc4ec1b84b5acc87..b5ed02d693f1c1c1ed90db8655dd22d6c6016ce0 100644 --- a/tensorflow/python/ops/math_ops.py +++ b/tensorflow/python/ops/math_ops.py @@ -70,6 +70,9 @@ mathematical functions for matrices to your graph. @@cholesky @@batch_cholesky +@@self_adjoint_eig +@@batch_self_adjoint_eig + ## Complex Number Functions TensorFlow provides several operations that you can use to add complex number diff --git a/tensorflow/python/ops/nn.py b/tensorflow/python/ops/nn.py index 065552c7edea9c37efca41e3ffddf330fd41c15e..e8880d59a8be3e0be14450eae368166c76634ef9 100644 --- a/tensorflow/python/ops/nn.py +++ b/tensorflow/python/ops/nn.py @@ -711,7 +711,7 @@ def nce_loss(weights, biases, inputs, labels, num_sampled, num_classes, unnormalized statistical models] (http://www.jmlr.org/proceedings/papers/v9/gutmann10a/gutmann10a.pdf). Also see our [Candidate Sampling Algorithms Reference] - (http://www.tensorflow.org/extras/candidate_sampling.pdf) + (../../extras/candidate_sampling.pdf) Note: In the case where `num_true` > 1, we assign to each target class the target probability 1 / `num_true` so that the target probabilities @@ -743,7 +743,7 @@ def nce_loss(weights, biases, inputs, labels, num_sampled, num_classes, `True`, this is a "Sampled Logistic" loss instead of NCE, and we are learning to generate log-odds instead of log probabilities. See our [Candidate Sampling Algorithms Reference] - (http://www.tensorflow.org/extras/candidate_sampling.pdf). + (../../extras/candidate_sampling.pdf). Default is False. name: A name for the operation (optional). @@ -782,7 +782,7 @@ def sampled_softmax_loss(weights, biases, inputs, labels, num_sampled, expression `tf.nn.softmax(tf.matmul(inputs, weights) + biases)`. See our [Candidate Sampling Algorithms Reference] - (http://www.tensorflow.org/extras/candidate_sampling.pdf) + (../../extras/candidate_sampling.pdf) Also see Section 3 of http://arxiv.org/abs/1412.2007 for the math. diff --git a/tensorflow/python/platform/default/_resource_loader.py b/tensorflow/python/platform/default/_resource_loader.py index 0fe18aef153c1ffb8b7058237f3631f74615ec28..f42a52094e850846b9e53b8e4c78a59761a1193a 100644 --- a/tensorflow/python/platform/default/_resource_loader.py +++ b/tensorflow/python/platform/default/_resource_loader.py @@ -36,10 +36,15 @@ def load_resource(path): Raises: IOError: If the path is not found, or the resource can't be opened. """ - path = os.path.join('tensorflow', path) + tensorflow_root = ( + os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir, + os.pardir)) + path = os.path.join(tensorflow_root, path) path = os.path.abspath(path) try: with open(path, 'rb') as f: return f.read() except IOError as e: logging.warning('IOError %s on path %s', e, path) + raise e diff --git a/tensorflow/python/platform/default/_resource_loader_test.py b/tensorflow/python/platform/default/_resource_loader_test.py new file mode 100644 index 0000000000000000000000000000000000000000..28d8ee1d601b4801c8f022de068e5ce91c2d8171 --- /dev/null +++ b/tensorflow/python/platform/default/_resource_loader_test.py @@ -0,0 +1,31 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from tensorflow.python.platform import googletest +from tensorflow.python.platform.default import _resource_loader as resource_loader + + +class DefaultResourceLoaderTest(googletest.TestCase): + + def test_exception(self): + with self.assertRaises(IOError): + resource_loader.load_resource("/fake/file/path/dne") + +if __name__ == "__main__": + googletest.main() diff --git a/tensorflow/python/summary/impl/event_file_loader_test.py b/tensorflow/python/summary/impl/event_file_loader_test.py index 4f6ac75d839ab9d9315fbc3a4ee97f88242063ca..1f961b4b78731fd436673b026c84a499ede7cada 100644 --- a/tensorflow/python/summary/impl/event_file_loader_test.py +++ b/tensorflow/python/summary/impl/event_file_loader_test.py @@ -20,6 +20,7 @@ from __future__ import division from __future__ import print_function import os +import tempfile from tensorflow.python.framework import test_util from tensorflow.python.platform import googletest @@ -32,8 +33,7 @@ class EventFileLoaderTest(test_util.TensorFlowTestCase): b'\xd5A\x1a\rbrain.Event:1\xec\xf32\x8d') def _WriteToFile(self, filename, data): - path = os.path.join(self.get_temp_dir(), filename) - with open(path, 'ab') as f: + with open(filename, 'ab') as f: f.write(data) def _LoaderForTestFile(self, filename): @@ -41,36 +41,41 @@ class EventFileLoaderTest(test_util.TensorFlowTestCase): os.path.join(self.get_temp_dir(), filename)) def testEmptyEventFile(self): - self._WriteToFile('empty_event_file', b'') - loader = self._LoaderForTestFile('empty_event_file') + filename = tempfile.NamedTemporaryFile().name + self._WriteToFile(filename, b'') + loader = self._LoaderForTestFile(filename) self.assertEqual(len(list(loader.Load())), 0) def testSingleWrite(self): - self._WriteToFile('single_event_file', EventFileLoaderTest.RECORD) - loader = self._LoaderForTestFile('single_event_file') + filename = tempfile.NamedTemporaryFile().name + self._WriteToFile(filename, EventFileLoaderTest.RECORD) + loader = self._LoaderForTestFile(filename) events = list(loader.Load()) self.assertEqual(len(events), 1) self.assertEqual(events[0].wall_time, 1440183447.0) self.assertEqual(len(list(loader.Load())), 0) def testMultipleWrites(self): - self._WriteToFile('staggered_event_file', EventFileLoaderTest.RECORD) - loader = self._LoaderForTestFile('staggered_event_file') + filename = tempfile.NamedTemporaryFile().name + self._WriteToFile(filename, EventFileLoaderTest.RECORD) + loader = self._LoaderForTestFile(filename) self.assertEqual(len(list(loader.Load())), 1) - self._WriteToFile('staggered_event_file', EventFileLoaderTest.RECORD) + self._WriteToFile(filename, EventFileLoaderTest.RECORD) self.assertEqual(len(list(loader.Load())), 1) def testMultipleLoads(self): - self._WriteToFile('multiple_loads_event_file', EventFileLoaderTest.RECORD) - loader = self._LoaderForTestFile('multiple_loads_event_file') + filename = tempfile.NamedTemporaryFile().name + self._WriteToFile(filename, EventFileLoaderTest.RECORD) + loader = self._LoaderForTestFile(filename) loader.Load() loader.Load() self.assertEqual(len(list(loader.Load())), 1) def testMultipleWritesAtOnce(self): - self._WriteToFile('multiple_event_file', EventFileLoaderTest.RECORD) - self._WriteToFile('multiple_event_file', EventFileLoaderTest.RECORD) - loader = self._LoaderForTestFile('staggered_event_file') + filename = tempfile.NamedTemporaryFile().name + self._WriteToFile(filename, EventFileLoaderTest.RECORD) + self._WriteToFile(filename, EventFileLoaderTest.RECORD) + loader = self._LoaderForTestFile(filename) self.assertEqual(len(list(loader.Load())), 2) diff --git a/tensorflow/tensorboard/tfgraph-demo-index.html b/tensorflow/tensorboard/components/tf-graph/demo/index.html similarity index 82% rename from tensorflow/tensorboard/tfgraph-demo-index.html rename to tensorflow/tensorboard/components/tf-graph/demo/index.html index 84b7aaa94c3e50a4cc6766d857ecc3951b028316..30231cb6fae05cac5d5847c58195e9486fc4fe7b 100644 --- a/tensorflow/tensorboard/tfgraph-demo-index.html +++ b/tensorflow/tensorboard/components/tf-graph/demo/index.html @@ -14,9 +14,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN tf-graph Demo - - - + + +
- Color by structure + Color by structure - Color by device + Color by device