{"id":16925579,"url":"https://github.com/bpiel/guildsman","last_synced_at":"2025-08-24T13:07:35.475Z","repository":{"id":70307043,"uuid":"105477694","full_name":"bpiel/guildsman","owner":"bpiel","description":"TensorFlow library for Clojure","archived":false,"fork":false,"pushed_at":"2018-07-06T16:47:16.000Z","size":66046,"stargazers_count":129,"open_issues_count":0,"forks_count":5,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-02-27T19:58:25.432Z","etag":null,"topics":["clojure","deep-learning","machine-learning","tensorflow"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bpiel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-01T22:01:17.000Z","updated_at":"2024-09-14T02:55:26.000Z","dependencies_parsed_at":"2023-02-27T05:00:12.363Z","dependency_job_id":null,"html_url":"https://github.com/bpiel/guildsman","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpiel%2Fguildsman","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpiel%2Fguildsman/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpiel%2Fguildsman/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpiel%2Fguildsman/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bpiel","download_url":"https://codeload.github.com/bpiel/guildsman/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243852420,"owners_count":20358267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","deep-learning","machine-learning","tensorflow"],"created_at":"2024-10-13T20:11:03.766Z","updated_at":"2025-08-24T13:07:35.458Z","avatar_url":"https://github.com/bpiel.png","language":"Clojure","funding_links":[],"categories":["人工智能"],"sub_categories":["机器学习"],"readme":"# Guildsman\n\n## Resignation\n\nAs of July 6, 2018, I'm resigning from my work on Guildsman. While I have many things working, I never released a version. There are all kinds of reasons why I'm stopping this project. The most significant is that my career had been taking me into ML, but that is no longer the case. \n\n**Thanks to everyone who gave me support and encouragement!**\n\n\n---\n## UPDATE -- Mar 1, 2018\nhttps://bpiel.github.io/guildsman/posts/creeping-2018-03-01/\n\n---\n\n## Resources\n\nI spoke about, and demonstrated, Guildsman at Conj 2017 in Baltimore. You can watch here:\n\nhttps://www.youtube.com/watch?v=8_HOB62rpvw\n\nIf you want to know more, please reach out. Any of these work:\n- file an issue\n- twitter: @bpiel\n- email: on my github profile page\n- slack -- https://clojurians.slack.com\n  - `#tensorflow`\n  - bpiel\n\nDuring this pre-release phase, I'll try to add to this README as it becomes clear through conversations what others are most interested in or confused by. Once this hits alpha, the project should be able to maintain the README itself, by learning from examples of other good READMEs. This is known as \"self-documenting code\".\n\n## YOU CAN HELP!\n\nA few people have expressed interest in helping out with Guildsman. The state of the project makes it impractical for anyone to contribute directly (ie no docs, no tests, highly unstable). BUT, **you can contribute** to TensorFlow in a way that has a **VERY** meaningful impact on what Guildsman is capable of -- by implementing gradients in TensorFlow's C++ layer.\n\n**NOTE**: There's been confusion around this, so I want to be very clear. These c++ gradient implementations are going directly to TensorFlow's code base. You submit a PR to TensorFlow. At no point is this code in Guildsman.\n\nThe reasons why these gradients are so important are laid out (partially, at least) in the video (linked above, especially starting around the 18min mark). \n\n## A Guide To Implementing C++ Gradients in TensorFlow\n\n### Prerequisite Knowledge\n\nMore Important:\n- familiarity with Python\n- familiarity with C++ (My c++ is **weak**, but I've gotten by.)\n\nLess Important:\n\n- familiarity with the underlying math\n\nThe mathematical logic is already written out in Python. You only need to port it to C++. The difficulty of implementing a gradient varies wildly depending on its complexity. Most are not trivial. But, I don't think a deep understanding of the math makes the porting process easier.\n\nIf you *do* want to learn more about the math, this wikipedia article is one place you could start. It describes the context in which the individial gradient implementations are being used, what the higher goal is, and how it is acheived.\n\nhttps://en.wikipedia.org/wiki/Automatic_differentiation#Reverse_accumulation\n\n\n### The Process\n\nBesides the actual coding, you'll need to determine which gradient to tackle, call dibs, and get your PR accepted. Each of those steps have their own unique set of challenges. If you have questions -- AFTER reading all of this :) -- please get in touch.\n\nHere are instructions from TF related to contributing, both generally and gradients specifically. I wrote my own notes below, but please read these first.\n- https://github.com/tensorflow/tensorflow/blob/master/CONTRIBUTING.md\n- https://github.com/tensorflow/tensorflow/tree/master/tensorflow/cc/gradients\n\n\n- Legal stuff!\n  - You **MUST** sign a Contributor License Agreement. If you read the TF instructions that I linked to above, then you already know that.\n  - This was a painless process for me, but that's affected by your legal relationship with your employer, or anyone who might own some part of your time/output.\n\n- Find a gradient implementation in the TF Python code that doesn't have a counterpart in c++.\n  - See the [gradient TODO list](#gradient-todo-list)\n  - This github search should return all the py grads: https://github.com/tensorflow/tensorflow/search?utf8=%E2%9C%93\u0026q=%22ops.RegisterGradient%22\u0026type= \n  - This should return all the c++ grads: https://github.com/tensorflow/tensorflow/search?utf8=%E2%9C%93\u0026q=%22REGISTER_GRADIENT_OP%22\u0026type=\n  - Which one should you do???\n    - For your first one, just try to find a simple one. Lines of code is a good indicator\n    - After that, the optimal choice would maximize `(value to community)/(your time)`\n      - Check the prioritized list in the [gradient TODO list](#gradient-todo-list) section.\n      - Anything in math_grad.py or nn_grad.py is probably not bad.\n      - Any new gradient is better than no gradient. Just do it!\n    - You may be able to find github issues that request a specific gradient. Here's one (currently open) that I filed: https://github.com/tensorflow/tensorflow/issues/12686\n\n- Implement the thing.\n  - I'm not even going to guess about what would be the most effective words to write here. Instead, there's examples below.\n \n- Implement a test.\n  - Again, see examples below.\n  - The tests are shockingly simple. The good Google TF people have implemented some test helper tooling that takes any operation, calculates the correct gradient values and compares them to the output of a gradient implementation. If the two agree within some margin of error, the test passes! Implementing a test is just a matter of wiring the operation and its gradient (that you wrote) up to this gradient verifier.\n\n- Run the test.\n\nGoogle has its own build tool, bazel, that TF uses. In addition to compilation (and who knows what else), you also use bazel to run tests. If there's a lot of compilation that needs to occurr before a test can be run (ex: the first time your run a test), you may be waiting for *hours*. Don't worry, subsequent runs will be fast (though, still not as fast as I'd like). Here's an example showing how I run the nn_grad tests:\n\n`sudo tensorflow/tools/ci_build/ci_build.sh CPU bazel test //tensorflow/cc:gradients_nn_grad_test`\n\nThat would get called from the root dir of the TF repo.\n\n- Fix code, run test, fix code, run test, fix code, run test....... tests pass! submit PR!\n - Definitely cc me on the PR when you do! (@bpiel)\n \n\n### Example - BiasAdd\n\nThe first PR of mine accepted into TensorFlow implemented the gradient for `BiasAdd`. `BiasAdd` is just a special case of matrix addition that is optimized for neural networks, but that's not important for the purposes of this example. What *is* important is that this is a simple case. It's made especially simple by the fact that the gradient for `BiasAdd` is already implemented as its own operation, `BiasAddGrad`. All I had to do was write some glue code and register it so that the auto differentiation logic could find it. This is not usually the case, but there are others like this.\n\n**My PR:**\nhttps://github.com/tensorflow/tensorflow/pull/12448/files\n\n**Python Code (the code to be ported)**\nhttps://github.com/tensorflow/tensorflow/blob/e5306d3dc75ea1b4338dc7b4518824a7698f0f92/tensorflow/python/ops/nn_grad.py#L237\n\n```python\n@ops.RegisterGradient(\"BiasAdd\")\ndef _BiasAddGrad(op, received_grad):\n  \"\"\"Return the gradients for the 2 inputs of bias_op.\n  The first input of unused_bias_op is the tensor t, and its gradient is\n  just the gradient the unused_bias_op received.\n  The second input of unused_bias_op is the bias vector which has one fewer\n  dimension than \"received_grad\" (the batch dimension.)  Its gradient is the\n  received gradient Summed on the batch dimension, which is the first dimension.\n  Args:\n    op: The BiasOp for which we need to generate gradients.\n    received_grad: Tensor.  The gradients passed to the BiasOp.\n  Returns:\n    Two tensors, the first one for the \"tensor\" input of the BiasOp,\n    the second one for the \"bias\" input of the BiasOp.\n  \"\"\"\n  try:\n    data_format = op.get_attr(\"data_format\")\n  except ValueError:\n    data_format = None\n  return (received_grad, gen_nn_ops.bias_add_grad(out_backprop=received_grad,\n                                                  data_format=data_format))\n```\n\n**The C++ code I wrote:**\nhttps://github.com/tensorflow/tensorflow/blob/e5306d3dc75ea1b4338dc7b4518824a7698f0f92/tensorflow/cc/gradients/nn_grad.cc#L106\n\n```c++\nStatus BiasAddGradHelper(const Scope\u0026 scope, const Operation\u0026 op,\n                         const std::vector\u003cOutput\u003e\u0026 grad_inputs,\n                         std::vector\u003cOutput\u003e* grad_outputs) {\n  string data_format;\n  BiasAddGrad::Attrs input_attrs;\n  TF_RETURN_IF_ERROR(\n      GetNodeAttr(op.output(0).node()-\u003eattrs(), \"data_format\", \u0026data_format));\n  input_attrs.DataFormat(data_format);\n  auto dx_1 = BiasAddGrad(scope, grad_inputs[0], input_attrs);\n  grad_outputs-\u003epush_back(Identity(scope, grad_inputs[0]));\n  grad_outputs-\u003epush_back(dx_1);\n  return scope.status();\n}\nREGISTER_GRADIENT_OP(\"BiasAdd\", BiasAddGradHelper);\n```\n\n**The test I wrote:**\nhttps://github.com/tensorflow/tensorflow/blob/e5306d3dc75ea1b4338dc7b4518824a7698f0f92/tensorflow/cc/gradients/nn_grad_test.cc#L150\n\n```c++\nTEST_F(NNGradTest, BiasAddGradHelper) {\n  TensorShape shape({4, 5});\n  TensorShape bias_shape({5});\n  auto x = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(shape));\n  auto bias = Placeholder(scope_, DT_FLOAT, Placeholder::Shape(bias_shape));\n  auto y = BiasAdd(scope_, x, bias);\n  RunTest({x, bias}, {shape, bias_shape}, {y}, {shape});\n}\n```\n\n**Relevant Docs:**\n\nhttps://www.tensorflow.org/api_docs/cc/\nhttps://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/bias-add\nhttps://www.tensorflow.org/versions/master/api_docs/cc/class/tensorflow/ops/bias-add-grad\nhttps://www.tensorflow.org/api_docs/cc/struct/tensorflow/ops/bias-add-grad/attrs\n\nhttps://www.tensorflow.org/api_docs/python/tf/nn/bias_add\n\nhttps://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/placeholder\n\n### Examples - TODO\n\nI've (currently) had three other grads accepted in the following two PRs. I'll try to get to expanding those into nicer example write-ups like the one above.\n\nhttps://github.com/tensorflow/tensorflow/pull/12665\nhttps://github.com/tensorflow/tensorflow/pull/12391\n\n\n### Gradient TODO List\n\n**as of Oct 18, 2017**\n\n#### Prioritized\n\nThese seem to be more important. Ordered by priority:\n\nSoftmaxCrossEntropyWithLogits\n\nFloor\n\nCast\n\nGatherV2\n\nPow\n\nSub\n\nProd\n\nConcatV2\n\nSlice\n\nTile\n\nTopKV2\n\n\n#### All Gradients that are in Python, but not C++\n\nAtan2\n\nAvgPool\n\nAvgPool3D\n\nAvgPool3DGrad\n\nAvgPoolGrad\n\nBadGrad\n\nBatchNormWithGlobalNormalization\n\nBetainc\n\nBiasAddGrad\n\nBiasAddV1\n\nCast\n\nCeil\n\nCholesky\n\nComplexAbs\n\nConcat\n\nConcatV2\n\nConv2DBackpropFilter\n\nConv2DBackpropInput\n\nConv3D\n\nConv3DBackpropFilterV2\n\nConv3DBackpropInputV2\n\nCopyOp\n\ncopy_override\n\nCropAndResize\n\nCross\n\nCTCLoss\n\nCumprod\n\nCumsum\n\nCustomSquare\n\nDebugGradientIdentity\n\nDepthwiseConv2dNative\n\nDigamma\n\nDilation2D\n\nEluGrad\n\nEnter\n\nErfc\n\nExit\n\nExtractImagePatches\n\nFakeQuantWithMinMaxArgs\n\nFakeQuantWithMinMaxVars\n\nFakeQuantWithMinMaxVarsPerChannel\n\nFFT\n\nFFT2D\n\nFFT3D\n\nFill\n\nFloor\n\nFloorDiv\n\nFloorMod\n\nFractionalAvgPool\n\nFractionalMaxPool\n\nFusedBatchNorm\n\nFusedBatchNormGrad\n\nFusedBatchNormGradV2\n\nFusedBatchNormV2\n\nGather\n\nGatherV2\n\nIdentityN\n\nIFFT\n\nIFFT2D\n\nIFFT3D\n\nIgamma\n\nIgammac\n\nInvGrad\n\nIRFFT\n\nIRFFT2D\n\nLoopCond\n\nLRN\n\nMatrixDeterminant\n\nMatrixDiagPart\n\nMatrixInverse\n\nMatrixSetDiag\n\nMatrixSolve\n\nMatrixSolveLs\n\nMatrixTriangularSolve\n\nMaxPool3D\n\nMaxPool3DGrad\n\nMaxPool3DGradGrad\n\nMaxPoolGrad\n\nMaxPoolGradGrad\n\nMaxPoolGradV2\n\nMaxPoolWithArgmax\n\nMerge\n\nNaNGrad\n\nNextIteration\n\nNthElement\n\nPlaceholderWithDefault\n\nPolygamma\n\nPow\n\nPreventGradient\n\nPrint\n\nProd\n\nReadVariableOp\n\nReciprocalGrad\n\nRefEnter\n\nRefExit\n\nRefMerge\n\nRefNextIteration\n\nRefSwitch\n\nReluGrad\n\nResizeBicubic\n\nResizeBilinear\n\nResizeNearestNeighbor\n\nResourceGather\n\nReverse\n\nRFFT\n\nRFFT2D\n\nRint\n\nRound\n\nRsqrtGrad\n\nSegmentMax\n\nSegmentMean\n\nSegmentMin\n\nSegmentSum\n\nSelect\n\nSelfAdjointEigV2\n\nSeluGrad\n\nSigmoidGrad\n\nSlice\n\nSoftmaxCrossEntropyWithLogits\n\nSoftplus\n\nSoftplusGrad\n\nSoftsign\n\nSparseAdd\n\nSparseDenseCwiseAdd\n\nSparseDenseCwiseDiv\n\nSparseDenseCwiseMul\n\nSparseFillEmptyRows\n\nSparseMatMul\n\nSparseReduceSum\n\nSparseReorder\n\nSparseSegmentMean\n\nSparseSegmentSqrtN\n\nSparseSegmentSum\n\nSparseSoftmax\n\nSparseSoftmaxCrossEntropyWithLogits\n\nSparseSparseMaximum\n\nSparseSparseMinimum\n\nSparseTensorDenseAdd\n\nSparseTensorDenseMatMul\n\nSplitV\n\nSqrtGrad\n\nStridedSlice\n\nStridedSliceGrad\n\nSub\n\nSvd\n\nSwitch\n\nTanhGrad\n\nTensorArrayConcat\n\nTensorArrayConcatV2\n\nTensorArrayConcatV3\n\nTensorArrayGather\n\nTensorArrayGatherV2\n\nTensorArrayGatherV3\n\nTensorArrayRead\n\nTensorArrayReadV2\n\nTensorArrayReadV3\n\nTensorArrayScatter\n\nTensorArrayScatterV2\n\nTensorArrayScatterV3\n\nTensorArraySplit\n\nTensorArraySplitV2\n\nTensorArraySplitV3\n\nTensorArrayWrite\n\nTensorArrayWriteV2\n\nTensorArrayWriteV3\n\nTestStringOutput\n\nTile\n\nTopK\n\nTopKV2\n\nTruncateDiv\n\nUnsortedSegmentMax\n\nUnsortedSegmentSum\n\nZeta\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpiel%2Fguildsman","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbpiel%2Fguildsman","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpiel%2Fguildsman/lists"}