diff --git a/.github/workflows/CleanPreview.yml b/.github/workflows/CleanPreview.yml new file mode 100644 index 00000000..25946efc --- /dev/null +++ b/.github/workflows/CleanPreview.yml @@ -0,0 +1,27 @@ +# from https://github.com/CliMA/ClimaTimeSteppers.jl +name: Doc Preview Cleanup + +on: + pull_request: + types: [closed] + +jobs: + doc-preview-cleanup: + runs-on: ubuntu-latest + steps: + - name: Checkout gh-pages branch + uses: actions/checkout@v2 + with: + ref: gh-pages + - name: Delete preview and history + push changes + run: | + if [ -d "previews/PR$PRNUM" ]; then + git config user.name "Documenter.jl" + git config user.email "documenter@juliadocs.github.io" + git rm -rf "previews/PR$PRNUM" + git commit -m "delete preview" + git branch gh-pages-new $(echo "delete history" | git commit-tree HEAD^{tree}) + git push --force origin gh-pages-new:gh-pages + fi + env: + PRNUM: ${{ github.event.number }} diff --git a/.github/workflows/Comment.yml b/.github/workflows/Comment.yml new file mode 100644 index 00000000..79127a32 --- /dev/null +++ b/.github/workflows/Comment.yml @@ -0,0 +1,14 @@ +name: PR Comment # Write a comment in the PR with a link to the preview of the given website +on: + pull_request: + types: [opened, reopened] +jobs: + pr_comment: + runs-on: ubuntu-latest + steps: + - name: Create PR comment + if: github.event_name == 'pull_request' && github.repository == github.event.pull_request.head.repo.full_name # if this is a pull request build AND the pull request is NOT made from a fork + uses: thollander/actions-comment-pull-request@71efef56b184328c7ef1f213577c3a90edaa4aff + with: + message: 'Once the build has completed, you can preview your PR at this URL: https://fluxml.ai/previews/PR${{ github.event.number }}/' + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/Deploy.yml b/.github/workflows/Deploy.yml new file mode 100644 index 00000000..11703eab --- /dev/null +++ b/.github/workflows/Deploy.yml @@ -0,0 +1,62 @@ +name: Build and Deploy +on: + push: + branches: + - master + - main + pull_request: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + persist-credentials: false + # NOTE: Python is necessary for the pre-rendering (minification) step + - name: Install python + uses: actions/setup-python@v4 + with: + python-version: '3.8' + # NOTE: Here you can install dependencies such as matplotlib if you use + # packages such as PyPlot. + # - run: pip install matplotlib + - name: Install Julia + uses: julia-actions/setup-julia@v1 + # NOTE + # The steps below ensure that NodeJS and Franklin are loaded then it + # installs highlight.js which is needed for the prerendering step + # (code highlighting + katex prerendering). + # Then the environment is activated and instantiated to install all + # Julia packages which may be required to successfully build your site. + # The last line should be `optimize()` though you may want to give it + # specific arguments, see the documentation or ?optimize in the REPL. + - run: julia -e ' + using Pkg; Pkg.add(["NodeJS", "Franklin"]); + using NodeJS; run(`$(npm_cmd()) install highlight.js`); + using Franklin; + Pkg.activate("."); Pkg.instantiate(); + optimize()' + - name: Fix URLs for PR preview deployment (pull request previews) + if: github.event_name == 'pull_request' + run: | + echo "PREVIEW_FRANKLIN_WEBSITE_URL=https://fluxml.ai/previews/PR${{ github.event.number }}/" >> $GITHUB_ENV + echo "PREVIEW_FRANKLIN_PREPATH=previews/PR${{ github.event.number }}" >> $GITHUB_ENV + - name: Deploy (preview) + if: github.event_name == 'pull_request' && github.repository == github.event.pull_request.head.repo.full_name # if this build is a PR build and the PR is NOT from a fork + uses: JamesIves/github-pages-deploy-action@releases/v4 + with: + branch: gh-pages # The branch where the PRs previews are stored + folder: __site + token: ${{ secrets.GITHUB_TOKEN }} + target-folder: "previews/PR${{ github.event.number }}" # The website preview is going to be stored in a subfolder + - name: Deploy (main) + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: JamesIves/github-pages-deploy-action@releases/v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: gh-pages # Replace here the branch where your website is deployed + folder: __site + clean-exclude: | + previews/* diff --git a/.gitignore b/.gitignore index 03a95f60..7447087c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ -_site -.sass-cache -.jekyll-metadata -Gemfile.lock - -vendor -bin +__site/ +.DS_Store +franklin +franklin.pub +node_modules/ +Manifest.toml diff --git a/404.md b/404.md index 7d7867a2..eb94d60f 100644 --- a/404.md +++ b/404.md @@ -1,7 +1,4 @@ ---- -layout: page ---- - +~~~ +~~~ -# 404 +~~~ +

404

+~~~ **Page not found :(** diff --git a/CNAME b/CNAME deleted file mode 100644 index 538732d3..00000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -fluxml.ai diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 1fbea86f..00000000 --- a/Gemfile +++ /dev/null @@ -1,33 +0,0 @@ -source "https://rubygems.org" - -# Hello! This is where you manage which Jekyll version is used to run. -# When you want to use a different version, change it below, save the -# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: -# -# bundle exec jekyll serve -# -# This will help ensure the proper Jekyll version is running. -# Happy Jekylling! -# gem "jekyll", "~> 4.2.1" -# Commented out since I was getting errors otherwsie. - -# This is the default theme for new Jekyll sites. You may change this to anything you like. -gem "minima", "~> 2.0" - -# If you want to use GitHub Pages, remove the "gem "jekyll"" above and -# uncomment the line below. To upgrade, run `bundle update github-pages`. -# gem "github-pages", group: :jekyll_plugins - -# If you have any plugins, put them here! -group :jekyll_plugins do - gem "jekyll-feed", "~> 0.6" - gem "jekyll-octicons" -end - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] - -# Performance-booster for watching directories on Windows -gem "wdm", "~> 0.1.0" if Gem.win_platform? - -gem "webrick", "~> 1.7" diff --git a/Project.toml b/Project.toml new file mode 100644 index 00000000..8f357c56 --- /dev/null +++ b/Project.toml @@ -0,0 +1,3 @@ +[deps] +Franklin = "713c75ef-9fc9-4b05-94a9-213340da978e" +NodeJS = "2bd173c7-0d6d-553b-b6af-13a54713934c" \ No newline at end of file diff --git a/SomeFile.jl b/SomeFile.jl deleted file mode 100644 index 7bff6aa5..00000000 --- a/SomeFile.jl +++ /dev/null @@ -1,1268 +0,0 @@ -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("This file is here to make this a Julia repo so it shows up on the Julia Hacktoberfest issue tracker") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") -print("test") diff --git a/assets/images/FluxGitHubPreview.png b/_assets/FluxGitHubPreview.png similarity index 100% rename from assets/images/FluxGitHubPreview.png rename to _assets/FluxGitHubPreview.png diff --git a/_assets/favicon_io/android-chrome-192x192.png b/_assets/favicon_io/android-chrome-192x192.png new file mode 100644 index 00000000..7aafc3b7 Binary files /dev/null and b/_assets/favicon_io/android-chrome-192x192.png differ diff --git a/_assets/favicon_io/android-chrome-512x512.png b/_assets/favicon_io/android-chrome-512x512.png new file mode 100644 index 00000000..349452ad Binary files /dev/null and b/_assets/favicon_io/android-chrome-512x512.png differ diff --git a/_assets/favicon_io/apple-touch-icon.png b/_assets/favicon_io/apple-touch-icon.png new file mode 100644 index 00000000..0600206d Binary files /dev/null and b/_assets/favicon_io/apple-touch-icon.png differ diff --git a/_assets/favicon_io/favicon-16x16.png b/_assets/favicon_io/favicon-16x16.png new file mode 100644 index 00000000..d1f35ba6 Binary files /dev/null and b/_assets/favicon_io/favicon-16x16.png differ diff --git a/_assets/favicon_io/favicon-32x32.png b/_assets/favicon_io/favicon-32x32.png new file mode 100644 index 00000000..f6c1630b Binary files /dev/null and b/_assets/favicon_io/favicon-32x32.png differ diff --git a/_assets/favicon_io/favicon.ico b/_assets/favicon_io/favicon.ico new file mode 100644 index 00000000..5fa3624d Binary files /dev/null and b/_assets/favicon_io/favicon.ico differ diff --git a/_assets/favicon_io/site.webmanifest b/_assets/favicon_io/site.webmanifest new file mode 100644 index 00000000..45dc8a20 --- /dev/null +++ b/_assets/favicon_io/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/_assets/friends/FluxGitHubPreview.png b/_assets/friends/FluxGitHubPreview.png new file mode 100644 index 00000000..a0e643a9 Binary files /dev/null and b/_assets/friends/FluxGitHubPreview.png differ diff --git a/assets/images/alan-turing.jpg b/_assets/friends/alan-turing.jpg similarity index 100% rename from assets/images/alan-turing.jpg rename to _assets/friends/alan-turing.jpg diff --git a/assets/images/beacon_biosignals.jpg b/_assets/friends/beacon_biosignals.jpg similarity index 100% rename from assets/images/beacon_biosignals.jpg rename to _assets/friends/beacon_biosignals.jpg diff --git a/assets/images/cambridge.jpg b/_assets/friends/cambridge.jpg similarity index 100% rename from assets/images/cambridge.jpg rename to _assets/friends/cambridge.jpg diff --git a/assets/images/cmu-logo.png b/_assets/friends/cmu-logo.png similarity index 100% rename from assets/images/cmu-logo.png rename to _assets/friends/cmu-logo.png diff --git a/assets/images/edinburgh.png b/_assets/friends/edinburgh.png similarity index 100% rename from assets/images/edinburgh.png rename to _assets/friends/edinburgh.png diff --git a/assets/images/invenia-logo.png b/_assets/friends/invenia-logo.png similarity index 100% rename from assets/images/invenia-logo.png rename to _assets/friends/invenia-logo.png diff --git a/assets/images/juliac-logo.png b/_assets/friends/juliac-logo.png similarity index 100% rename from assets/images/juliac-logo.png rename to _assets/friends/juliac-logo.png diff --git a/assets/images/mit-logo.png b/_assets/friends/mit-logo.png similarity index 100% rename from assets/images/mit-logo.png rename to _assets/friends/mit-logo.png diff --git a/assets/images/rai-logo.png b/_assets/friends/rai-logo.png similarity index 100% rename from assets/images/rai-logo.png rename to _assets/friends/rai-logo.png diff --git a/assets/images/ucl-logo.png b/_assets/friends/ucl-logo.png similarity index 100% rename from assets/images/ucl-logo.png rename to _assets/friends/ucl-logo.png diff --git a/assets/images/uoft_logo.png b/_assets/friends/uoft_logo.png similarity index 100% rename from assets/images/uoft_logo.png rename to _assets/friends/uoft_logo.png diff --git a/assets/images/washington.jpg b/_assets/friends/washington.jpg similarity index 100% rename from assets/images/washington.jpg rename to _assets/friends/washington.jpg diff --git a/assets/2021-12-1-flux-numfocus/flux.png b/_assets/logo.png similarity index 100% rename from assets/2021-12-1-flux-numfocus/flux.png rename to _assets/logo.png diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 9fa83e74..00000000 --- a/_config.yml +++ /dev/null @@ -1,44 +0,0 @@ -# Welcome to Jekyll! -# -# This config file is meant for settings that affect your whole blog, values -# which you are expected to set up once and rarely edit after that. If you find -# yourself editing this file very often, consider using Jekyll's data files -# feature for the data you need to update frequently. -# -# For technical reasons, this file is *NOT* reloaded automatically when you use -# 'bundle exec jekyll serve'. If you change this file, please restart the server process. - -# Site settings -# These are used to personalize your new site. If you look in the HTML files, -# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. -# You can create any custom variable you would like, and they will be accessible -# in the templates via {{ site.myvariable }}. -title: Flux -email: mike.j.innes@gmail.com -description: >- # this means to ignore newlines until "baseurl:" - The Flux machine learning library for Julia -baseurl: "" # the subpath of your site, e.g. /blog -url: "https://fluxml.github.io" # the base hostname & protocol for your site, e.g. http://example.com -twitter_username: FluxML -github_username: FluxML - -# Build settings -markdown: kramdown -kramdown: - input: GFM #Github Flavored Markdown -theme: minima -plugins: - - jekyll-feed - - jekyll-octicons - -# Exclude from processing. -# The following items will not be processed, by default. Create a custom list -# to override the default setting. -# exclude: -# - Gemfile -# - Gemfile.lock -# - node_modules -# - vendor/bundle/ -# - vendor/cache/ -# - vendor/gems/ -# - vendor/ruby/ diff --git a/script/default.css b/_css/script_default.css similarity index 100% rename from script/default.css rename to _css/script_default.css diff --git a/_css/site.css b/_css/site.css new file mode 100644 index 00000000..9ac950a2 --- /dev/null +++ b/_css/site.css @@ -0,0 +1,274 @@ +@import url("https://fonts.googleapis.com/css?family=Lato:400,400i"); + +.octicon { + display: inline-block; + vertical-align: text-bottom; + fill: currentColor +} + +body { + background: #143c3c; + font-family: Lato, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + line-height: 1.7 +} + +.logo { + font-style: italic +} + +.navbar .logo { + text-shadow: 2px 2px 5px rgba(0,0,0,0.1) +} + +.content { + background: #f0fafa +} + +.content .container { + background: white; + padding-top: 2em; + padding-bottom: 2em +} + +.content h1 { + font-size: 20pt; + padding-bottom: 0.2em; + border-bottom: 3px solid #ebf5eb; + text-align: center; + font-weight: bold; + margin-bottom: 1em +} + +.content h2 { + font-size: 18pt; + text-align: right; + margin-top: 2em +} + +.content h3 { + font-size: 14pt; + font-weight: bold; + margin-top: 2em +} + +.content h4 { + font-size: 13pt; + margin-top: 2em +} + +.content h5 { + font-size: 13pt; + font-style: italic; + margin-top: 2em +} + +.content blockquote { + font-style: italic; + border-left: 5px solid #ebf5eb; + padding-left: 1em; + margin-left: 1em +} + +.content .author { + text-align: right; + font-style: italic; + color: #009696 +} + +.content .attrib { + font-style: italic; + color: #003232 +} + +.container img { + max-width: 100%; +} +.container h1, .container h2, .container h3, .container h4, .container h5, .container p, .container blockquote, .container .hljs, .container ul :not(.navbar-nav) { + max-width: 650px; + margin-left: auto; + margin-right: auto; +} +.container p { + text-align:justify; +} +.container p.p-image { + max-width: 100%; + text-align: center; +} + +.lighter { + font-weight: 300; + letter-spacing: 1px +} + +p a:hover, p a:visited:hover { + color: #006464; + text-decoration: none +} + +p a, p a:visited { + color: #006464; + border-bottom: 2px solid #b4dcdc +} + +p a:hover { + border-bottom: 2px solid #0aa +} + +.feature a:hover, .feature a:visited:hover { + color: #006464; + text-decoration: none +} + +.feature a, .feature a:visited { + color: #006464; + border-bottom: 2px solid #b4dcdc +} + +.feature a:hover { + border-bottom: 2px solid #0aa +} + +.call { + padding-top: 2em; + padding-bottom: 2em; + text-align: center +} + +.call p:last-child { + margin: 0 +} + +.footer { + margin-top: 1.5rem; + margin-bottom: 3rem; + color: white +} + +pre { + margin: 0 +} + +pre code.hljs { + background: #f5ffff; + border: 2px solid #c8f0f0; + border-radius: 5px; + padding-left: 1em; + padding-right: 1em; + margin-bottom: 1em; +} + +.navbar-collapse.collapse.in { + display: block !important +} + +.jumbotron { + margin-bottom: 0; + position: relative; + border-bottom: 1px thick; +} + +.jumbotron .container { + max-width: 750px; + box-shadow: 2px; + position: relative; + padding: none; + text-align: center; +} + +.jumbotron .buttons { + padding: 10px; +} + +@media (min-width: 576px){ + .jumbotron .container{ + padding: calc(1rem + 30px) 15px; + } +} + +.jumbotron hr { + border-top: 1px solid rgb(100, 150, 150); +} + +.jumbotron h1 { + font-family: lato; + font-style: italic; +} + +/* Description */ +.jumbotron { + padding: 0; +} + +.jumbotron p { + font-size: 1.1em; + margin-bottom: 1.5rem; +} + +.btn-primary { + color: rgb(30, 50, 50); + border-color: rgb(150, 200, 200); + background: none; + border-width: 2px; +} + +.jumbotron .btn-primary:hover { + color: rgb(0, 0, 0); + border-color: rgb(30, 80, 80); + background: none; + border-width: 2px; +} + +/*Features*/ +.features { + background:white; + padding-top:2em; +} + +.feature { + padding-top: 1em; + padding-bottom: 2rem; + letter-spacing: 0.1px; +} + +.feature-title { + text-align:center; + color:rgb(100,130,130) +} + +.paper { + padding: 1em; +} + +.feature h5, .paper h5 { + font-style: italic; + padding-bottom: 0.5em; +} + +.friends{ + background: #fff; +} +.friends *{ + text-align: center; + padding:10px; +} +.friends h3{ + margin-top: 50px; +} +.friends ul{ + display: flex; + -webkit-justify-content: space-evenly; + justify-content: space-evenly; + flex-wrap: wrap; + list-style: none; + align-items: center; +} +.friends ul li img{ + max-width: 200px; + max-height: 100px; + height: auto; +} + +.tight-list p { + margin-bottom: 0; +} diff --git a/_data/experiments.yml b/_data/experiments.yml deleted file mode 100644 index 889dead0..00000000 --- a/_data/experiments.yml +++ /dev/null @@ -1,38 +0,0 @@ -go : - name: Go - pass_option: true - start_screen: false - game_over_message: Click to play again - instructions_page: experiments/game/instructions/go.html - code_link: "https://github.com/tejank10/AlphaGo.jl" - canvas: false - no_options: false -chess: - name: Chess - pass_option: false - start_screen: false - game_over_message: Click to play again - instructions_page: experiments/game/instructions/chess.html - code_link: "#" - canvas: false - no_options: false -breakout: - name: Breakout - pass_option: false - start_screen: true - start_message: Press [Enter] to start - game_over_message: Press [Left Arrow] or [Right Arrow] keys to play again - instructions_page: experiments/game/instructions/breakout.html - code_link: "#" - canvas: true - no_options: false -pong: - name: Pong - pass_option: false - start_screen: true - start_message: Press [Enter] to start - game_over_message: Press [Up arrow key] or [Down arrow key] to play again - instructions_page: experiments/game/instructions/pong.html - code_link: "#" - canvas: false - no_options: true \ No newline at end of file diff --git a/_includes/experiments/game/content.html b/_includes/experiments/game/content.html deleted file mode 100644 index 96ca7c1e..00000000 --- a/_includes/experiments/game/content.html +++ /dev/null @@ -1,44 +0,0 @@ -
-
-

Flux Experiment: {{ include.game.name }} Game

-
-
-
-
{{ include.game.name }}
- {% if include.game.no_options == false %} -
- {% if include.game.pass_option %} -
Pass
- {% endif %} -
-
-
- {% endif %} -
-
- {% if include.game.canvas %} - - {% else %} -
- {% endif %} -
- {% if include.game.start_screen %} -
-

{{ include.game.start_message }}

-
- {% endif %} - -
-
-
-
-

Instructions

- {% include {{ include.game.instructions_page }} %} - -
-
-
-
diff --git a/_includes/experiments/game/footer.html b/_includes/experiments/game/footer.html deleted file mode 100644 index e1121ea6..00000000 --- a/_includes/experiments/game/footer.html +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/_includes/experiments/game/headers.html b/_includes/experiments/game/headers.html deleted file mode 100644 index 7ac5a263..00000000 --- a/_includes/experiments/game/headers.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/_includes/experiments/game/instructions/breakout.html b/_includes/experiments/game/instructions/breakout.html deleted file mode 100644 index 8a574892..00000000 --- a/_includes/experiments/game/instructions/breakout.html +++ /dev/null @@ -1 +0,0 @@ -

Use arrow keys to move the paddle

\ No newline at end of file diff --git a/_includes/experiments/game/instructions/chess.html b/_includes/experiments/game/instructions/chess.html deleted file mode 100644 index 4f40057b..00000000 --- a/_includes/experiments/game/instructions/chess.html +++ /dev/null @@ -1,11 +0,0 @@ -

Human plays white, computer plays black. Drag and drop to move pieces. Standard rules apply

-

Moves

- \ No newline at end of file diff --git a/_includes/experiments/game/instructions/go.html b/_includes/experiments/game/instructions/go.html deleted file mode 100644 index b61f216b..00000000 --- a/_includes/experiments/game/instructions/go.html +++ /dev/null @@ -1,13 +0,0 @@ -

Human plays black, computer plays white. Two consecutive passes result in a game over. The best 3 moves found are circled in green. Illegal moves are shown in red

- -

Rules

- \ No newline at end of file diff --git a/_includes/experiments/game/instructions/pong.html b/_includes/experiments/game/instructions/pong.html deleted file mode 100644 index 8a574892..00000000 --- a/_includes/experiments/game/instructions/pong.html +++ /dev/null @@ -1 +0,0 @@ -

Use arrow keys to move the paddle

\ No newline at end of file diff --git a/_layout/foot.html b/_layout/foot.html new file mode 100644 index 00000000..e01cb41c --- /dev/null +++ b/_layout/foot.html @@ -0,0 +1,24 @@ + + + {{isnotpage index}} + + + {{end}} + + + + + + + + + + + + + + diff --git a/_layout/head.html b/_layout/head.html new file mode 100644 index 00000000..1f29d624 --- /dev/null +++ b/_layout/head.html @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Flux – Elegant ML + + + + {{insert navbar.html}} + + {{isnotpage index}} +
+
+ {{end}} + + {{ispage blogposts/*}} +

{{title}}

+ {{end}} + + {{ispage tutorialposts/*}} +

{{title}}

+ {{end}} + diff --git a/_layout/navbar.html b/_layout/navbar.html new file mode 100644 index 00000000..9c1692a2 --- /dev/null +++ b/_layout/navbar.html @@ -0,0 +1,44 @@ + + diff --git a/_layout/page_foot.html b/_layout/page_foot.html new file mode 100644 index 00000000..427a0950 --- /dev/null +++ b/_layout/page_foot.html @@ -0,0 +1,7 @@ +{{ispage blogposts/*}} +

– {{author}}

+{{end}} + +{{ispage tutorialposts/*}} +

– {{author}}

+{{end}} diff --git a/_layout/tag.html b/_layout/tag.html new file mode 100644 index 00000000..979b60c3 --- /dev/null +++ b/_layout/tag.html @@ -0,0 +1,18 @@ + + + + + + + + Tag: {{fill fd_tag}} + + + {{insert header.html}} +
+

Tag: {{fill fd_tag}}

+ {{taglist}} + {{insert page_foot.html}} +
+ + diff --git a/_layouts/blog.html b/_layouts/blog.html deleted file mode 100644 index c6a52642..00000000 --- a/_layouts/blog.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page ---- - -

{{page.title}}

- -{{content}} - -

– {{page.author}}

diff --git a/_layouts/default.html b/_layouts/default.html deleted file mode 100644 index ce7db836..00000000 --- a/_layouts/default.html +++ /dev/null @@ -1,125 +0,0 @@ ---- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Flux – {{page.title}} - - - - - - - {{content}} - - - - - - - - - - - - - - diff --git a/_layouts/page.html b/_layouts/page.html deleted file mode 100644 index 5c462601..00000000 --- a/_layouts/page.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -layout: default ---- - - - -
-
- - {{content}} - -
-
- - - - \ No newline at end of file diff --git a/_layouts/tutorials.html b/_layouts/tutorials.html deleted file mode 100755 index c6a52642..00000000 --- a/_layouts/tutorials.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page ---- - -

{{page.title}}

- -{{content}} - -

– {{page.author}}

diff --git a/script/highlight.pack.js b/_libs/highlight.pack.js similarity index 99% rename from script/highlight.pack.js rename to _libs/highlight.pack.js index dd12ef1d..f9d410c2 100644 --- a/script/highlight.pack.js +++ b/_libs/highlight.pack.js @@ -1,2 +1,2 @@ /*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ -!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("julia",function(e){var r={keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},t="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",a={l:t,k:r,i:/<\//},n={cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,r:0},o={cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i={cN:"subst",b:/\$\(/,e:/\)/,k:r},l={cN:"variable",b:"\\$"+t},c={cN:"string",c:[e.BE,i,l],v:[{b:/\w*"""/,e:/"""\w*/,r:10},{b:/\w*"/,e:/"\w*/}]},s={cN:"string",c:[e.BE,i,l],b:"`",e:"`"},d={cN:"meta",b:"@"+t},u={cN:"comment",v:[{b:"#=",e:"=#",r:10},{b:"#",e:"$"}]};return a.c=[n,o,c,s,d,u,e.HCM,{cN:"keyword",b:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{b:/<:/}],i.c=a.c,a}); \ No newline at end of file +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("julia",function(e){var r={keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},t="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",a={l:t,k:r,i:/<\//},n={cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,r:0},o={cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i={cN:"subst",b:/\$\(/,e:/\)/,k:r},l={cN:"variable",b:"\\$"+t},c={cN:"string",c:[e.BE,i,l],v:[{b:/\w*"""/,e:/"""\w*/,r:10},{b:/\w*"/,e:/"\w*/}]},s={cN:"string",c:[e.BE,i,l],b:"`",e:"`"},d={cN:"meta",b:"@"+t},u={cN:"comment",v:[{b:"#=",e:"=#",r:10},{b:"#",e:"$"}]};return a.c=[n,o,c,s,d,u,e.HCM,{cN:"keyword",b:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{b:/<:/}],i.c=a.c,a}); diff --git a/_rss/head.xml b/_rss/head.xml new file mode 100644 index 00000000..4c9f62b1 --- /dev/null +++ b/_rss/head.xml @@ -0,0 +1,37 @@ + + + + + + + <![CDATA[ {{fd2rss website_title}} ]]> + + {{website_url}} + + + + + diff --git a/_rss/item.xml b/_rss/item.xml new file mode 100644 index 00000000..07f65064 --- /dev/null +++ b/_rss/item.xml @@ -0,0 +1,60 @@ + + + + <![CDATA[ {{fd2rss rss_title}} ]]> + + {{fd_full_url}} + {{fd_full_url}} + + + + + + {{if rss_full_content}} + + + + {{end}} + + + {{RFC822 rss_pubdate}} + + + {{isnotempty rss_author}} + {{rss_author}} + {{end}} + {{isnotempty author}} + + {{author}} + + {{end}} + + {{isnotempty rss_category}} + {{rss_category}} + {{end}} + + {{isnotempty rss_comments}} + {{rss_comments}} + {{end}} + + {{isnotempty rss_enclosure}} + {{rss_enclosure}} + {{end}} + diff --git a/assets/2019-03-05-dp-vs-rl/bptt.png b/assets/2019-03-05-dp-vs-rl/bptt.png deleted file mode 100644 index d11f1b26..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/bptt.png and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/cartpole-flow.png b/assets/2019-03-05-dp-vs-rl/cartpole-flow.png deleted file mode 100644 index dcda8ce0..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/cartpole-flow.png and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/cartpole.gif b/assets/2019-03-05-dp-vs-rl/cartpole.gif deleted file mode 100644 index 90833bf1..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/cartpole.gif and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/pendulum-dp.gif b/assets/2019-03-05-dp-vs-rl/pendulum-dp.gif deleted file mode 100644 index 1c22143f..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/pendulum-dp.gif and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/pendulum-training.gif b/assets/2019-03-05-dp-vs-rl/pendulum-training.gif deleted file mode 100644 index dccbf1a8..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/pendulum-training.gif and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/trebuchet-basic.gif b/assets/2019-03-05-dp-vs-rl/trebuchet-basic.gif deleted file mode 100644 index 21476ec2..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/trebuchet-basic.gif and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/trebuchet-flow.png b/assets/2019-03-05-dp-vs-rl/trebuchet-flow.png deleted file mode 100644 index e577bc91..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/trebuchet-flow.png and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/trebuchet-hit.gif b/assets/2019-03-05-dp-vs-rl/trebuchet-hit.gif deleted file mode 100644 index cf453f1f..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/trebuchet-hit.gif and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/trebuchet-miss.gif b/assets/2019-03-05-dp-vs-rl/trebuchet-miss.gif deleted file mode 100644 index b6c97ab9..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/trebuchet-miss.gif and /dev/null differ diff --git a/assets/2019-03-05-dp-vs-rl/trebuchet-wind.gif b/assets/2019-03-05-dp-vs-rl/trebuchet-wind.gif deleted file mode 100644 index fb838e15..00000000 Binary files a/assets/2019-03-05-dp-vs-rl/trebuchet-wind.gif and /dev/null differ diff --git a/assets/2020-06-29-acclerating-flux-torch/combined_benchmarks_2.png b/assets/2020-06-29-acclerating-flux-torch/combined_benchmarks_2.png deleted file mode 100644 index 17d0a0b3..00000000 Binary files a/assets/2020-06-29-acclerating-flux-torch/combined_benchmarks_2.png and /dev/null differ diff --git a/assets/2020-06-29-acclerating-flux-torch/resnet101.png b/assets/2020-06-29-acclerating-flux-torch/resnet101.png deleted file mode 100644 index 2a27e6ea..00000000 Binary files a/assets/2020-06-29-acclerating-flux-torch/resnet101.png and /dev/null differ diff --git a/assets/2020-12-20-Flux3D/bm_metrics.png b/assets/2020-12-20-Flux3D/bm_metrics.png deleted file mode 100644 index 1a878528..00000000 Binary files a/assets/2020-12-20-Flux3D/bm_metrics.png and /dev/null differ diff --git a/assets/2020-12-20-Flux3D/bm_pcloud.png b/assets/2020-12-20-Flux3D/bm_pcloud.png deleted file mode 100644 index 6d4d0cec..00000000 Binary files a/assets/2020-12-20-Flux3D/bm_pcloud.png and /dev/null differ diff --git a/assets/2020-12-20-Flux3D/bm_trimesh.png b/assets/2020-12-20-Flux3D/bm_trimesh.png deleted file mode 100644 index 5f2ffe21..00000000 Binary files a/assets/2020-12-20-Flux3D/bm_trimesh.png and /dev/null differ diff --git a/assets/2020-12-20-Flux3D/fitmesh_anim.gif b/assets/2020-12-20-Flux3D/fitmesh_anim.gif deleted file mode 100644 index ba01ece5..00000000 Binary files a/assets/2020-12-20-Flux3D/fitmesh_anim.gif and /dev/null differ diff --git a/assets/2020-12-20-Flux3D/visualize.png b/assets/2020-12-20-Flux3D/visualize.png deleted file mode 100644 index 1c1ae731..00000000 Binary files a/assets/2020-12-20-Flux3D/visualize.png and /dev/null differ diff --git a/assets/2020-12-20-Flux3D/visualize_anim.gif b/assets/2020-12-20-Flux3D/visualize_anim.gif deleted file mode 100644 index b86a0525..00000000 Binary files a/assets/2020-12-20-Flux3D/visualize_anim.gif and /dev/null differ diff --git a/assets/2021-10-8-dcgan-mnist/cat_gan.png b/assets/2021-10-8-dcgan-mnist/cat_gan.png deleted file mode 100644 index a3b59c5a..00000000 Binary files a/assets/2021-10-8-dcgan-mnist/cat_gan.png and /dev/null differ diff --git a/assets/2021-10-8-dcgan-mnist/output.gif b/assets/2021-10-8-dcgan-mnist/output.gif deleted file mode 100644 index 33435edb..00000000 Binary files a/assets/2021-10-8-dcgan-mnist/output.gif and /dev/null differ diff --git a/assets/2021-12-1-flux-numfocus/flux_numfocus.png b/assets/2021-12-1-flux-numfocus/flux_numfocus.png deleted file mode 100644 index e43b32a7..00000000 Binary files a/assets/2021-12-1-flux-numfocus/flux_numfocus.png and /dev/null differ diff --git a/assets/charges/maingif.gif b/assets/charges/maingif.gif deleted file mode 100644 index 56d830b3..00000000 Binary files a/assets/charges/maingif.gif and /dev/null differ diff --git a/assets/charges/plot1.png b/assets/charges/plot1.png deleted file mode 100644 index d3ab55e4..00000000 Binary files a/assets/charges/plot1.png and /dev/null differ diff --git a/assets/charges/plot2.png b/assets/charges/plot2.png deleted file mode 100644 index e1b2b6e2..00000000 Binary files a/assets/charges/plot2.png and /dev/null differ diff --git a/assets/charges/plot3.png b/assets/charges/plot3.png deleted file mode 100644 index c2557948..00000000 Binary files a/assets/charges/plot3.png and /dev/null differ diff --git a/assets/css/style.css b/assets/css/style.css deleted file mode 100644 index cad41b69..00000000 --- a/assets/css/style.css +++ /dev/null @@ -1,12 +0,0 @@ -#cppn{ - position:absolute; - top:0; - bottom:0; - height: 100%; - width: 100vw; -} - -iframe { - display: block; - border-style:none; -} diff --git a/assets/images/amd-logo.png b/assets/images/amd-logo.png deleted file mode 100644 index cb80abf7..00000000 Binary files a/assets/images/amd-logo.png and /dev/null differ diff --git a/assets/js/script.js b/assets/js/script.js deleted file mode 100644 index 6c1f1066..00000000 --- a/assets/js/script.js +++ /dev/null @@ -1,144 +0,0 @@ -(function(){ -function Screen(ele, w, h){ - this.frames = []; - this.isDrawing = false; - - this.index = 0; - var l = w*h; - var canvas = ele; - - this.addFrame = function(data){ - this.frames.push(data); - } - - this.next = function(){ - if(this.frames.length ==0) return; - - this.index = Math.floor((this.index + 1)%(this.frames.length)); - if(!this.isDrawing) - requestAnimationFrame(this.draw_); - } - - - this.draw_ = function(){ - if(this.isDrawing || this.frames.length == 0)return; - - this.isDrawing = true; - var data = this.frames[this.index]; - - var img = []; - for(var i = 0; i< w*h; i++){ - c = data[i]*255; - img.push(c, c, c, 255); - } - - var uint8 = new Uint8ClampedArray(img); - var imgData = new ImageData(uint8,w,h); - - - canvas.getContext("2d", {alpha: false}).putImageData(imgData, 0, 0) - this.isDrawing = false; - } - - this.draw_ = this.draw_.bind(this); - this.frameCount = ()=> this.frames.length; -} - - -function CPPN(canvas, {z_dim=2, w=100, h=100, rate=1, max=1, frames = 1000, func=Math.sin}={}){ - canvas.width = w; - canvas.height = h; - - // scaling canvas since CSS scaling is faster - canvas.style.width = w + "px"; - canvas.style.height = h + "px"; - var scaleX = window.innerWidth/ canvas.width; - var scaleY = canvas.parentElement.offsetHeight / canvas.height; - canvas.style.transform = "scaleX("+ scaleX +") scaleY(" + scaleY +")"; - canvas.style.transformOrigin = "0 0"; - - - var screen = new Screen(canvas, w, h); - var model_ = null; - - var counter = new Array(z_dim); - var speed = 2*Math.PI/frames; - var factor = Math.min(w, h); - var coords = getCoords(); - var zArr = new Array(frames); - - tf.randomUniform([z_dim]).data().then((counter)=>{ - for(var i = 0; i< frames; i++){ - var z_ = new Array(z_dim); - for(var j = 0; j< z_dim; j++){ - var n = counter[j] + speed; - z_[j] = max*func(rate*n); - counter[j] = n; - } - zArr[i] = z_; - } - }) - - function getCoords(){ - var x, y, r, collection = []; - for(var i=0; i< w; i++){ - x = (i/factor) - 0.5 - for(var j=0; j< h; j++){ - y = (j/factor) - 0.5 - r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); - collection.push([x, y, r]); - } - } - return collection; - } - - var next = z => requestAnimationFrame( call( draw, z)); - - var draw = function(){ - // console.log("draw ") - if(screen.frameCount() >= frames){ - screen.next(); - return next(); - } - var index = screen.frameCount(); - - var l = coords.length - var collection = new Array(l); - - - var z = zArr[index]; - for(var j = 0; j< l; j++){ - collection[j] = coords[j].concat(z); - } - - var input = tf.tensor(collection, [l, 3 + z_dim]); - var output = model_(input); - tf.dispose(input); - - output.data().then(r=>{ - screen.addFrame(r); - screen.next(); - tf.dispose(output); - }) - - next(); - } - - this.start = function(model){ - model_ = e => tf.tidy(() => model(e)); - - next(); - } -} - -var canvas = document.querySelector("#cppn"); -var cppn = new CPPN(canvas); - -function call(f){ - var f_ = f; - arguments[0] = this - return ()=> f_.call(...Array.from(arguments)); -} - -window.__init__ = ()=> cppn.start(model); -})(); diff --git a/blog.md b/blog.md index 52498966..1b9e4027 100755 --- a/blog.md +++ b/blog.md @@ -1,12 +1,9 @@ ---- -layout: blog -title: The Flux Blog ---- ++++ +title = "The Flux Blog" ++++ -{% for post in site.categories.blog %} -{% if post.external %} -[{{post.title}} {% octicon link-external %}]({{post.external}}) -{% else %} -[{{post.title}}]({{post.url}}) -{% endif %} ({{post.date | date: '%B %Y' }}) -{% endfor %} +~~~ +

Blog posts

+~~~ + +{{recentposts blogposts}} diff --git a/blog/_posts/2017-08-24-generic-gpu.md b/blog/_posts/2017-08-24-generic-gpu.md deleted file mode 100755 index 5df9cb56..00000000 --- a/blog/_posts/2017-08-24-generic-gpu.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Generic GPU Kernels -external: http://mikeinnes.github.io/2017/08/24/cudanative.html ---- diff --git a/blog/_posts/2017-12-06-ml-pl.md b/blog/_posts/2017-12-06-ml-pl.md deleted file mode 100755 index f55cca1d..00000000 --- a/blog/_posts/2017-12-06-ml-pl.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: On Machine Learning & Programming Languages -external: https://julialang.org/blog/2017/12/ml-pl/ ---- diff --git a/blog/_posts/2018-12-03-ml-language-compiler.md b/blog/_posts/2018-12-03-ml-language-compiler.md deleted file mode 100755 index 39b62ba1..00000000 --- a/blog/_posts/2018-12-03-ml-language-compiler.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Building a Language and Compiler for Machine Learning -external: https://julialang.org/blog/2018/12/ml-language-compiler/ ---- diff --git a/blogposts/2017-08-24-generic-gpu.md b/blogposts/2017-08-24-generic-gpu.md new file mode 100644 index 00000000..69611eef --- /dev/null +++ b/blogposts/2017-08-24-generic-gpu.md @@ -0,0 +1,5 @@ ++++ +title = "Generic GPU Kernels" +published = "24 August 2017" +external = "http://mikeinnes.github.io/2017/08/24/cudanative.html" ++++ diff --git a/blogposts/2017-12-06-ml-pl.md b/blogposts/2017-12-06-ml-pl.md new file mode 100644 index 00000000..867d5768 --- /dev/null +++ b/blogposts/2017-12-06-ml-pl.md @@ -0,0 +1,5 @@ ++++ +title = "On Machine Learning & Programming Languages" +published = "6 December 2017" +external = "https://julialang.org/blog/2017/12/ml-pl/" ++++ diff --git a/blogposts/2018-12-03-ml-language-compiler.md b/blogposts/2018-12-03-ml-language-compiler.md new file mode 100755 index 00000000..e0df0404 --- /dev/null +++ b/blogposts/2018-12-03-ml-language-compiler.md @@ -0,0 +1,5 @@ ++++ +title = "Building a Language and Compiler for Machine Learning" +published = "3 December 2018" +external = "https://julialang.org/blog/2018/12/ml-language-compiler/" ++++ diff --git a/blog/_posts/2019-02-07-what-is-differentiable-programming.md b/blogposts/2019-02-07-what-is-differentiable-programming.md similarity index 85% rename from blog/_posts/2019-02-07-what-is-differentiable-programming.md rename to blogposts/2019-02-07-what-is-differentiable-programming.md index f2845be5..2667cd9d 100755 --- a/blog/_posts/2019-02-07-what-is-differentiable-programming.md +++ b/blogposts/2019-02-07-what-is-differentiable-programming.md @@ -1,10 +1,12 @@ ---- -title: What Is Differentiable Programming? -author: Mike Innes -layout: blog ---- ++++ +title = "What Is Differentiable Programming?" +published = "7 February 2019" +author = "Mike Innes" ++++ -> With four parameters I can fit an elephant, and with five I can make him wiggle his trunk.
– John Von Neumann +> With four parameters I can fit an elephant, and with five I can make him wiggle his trunk. +> +> – John Von Neumann The idea of "differentiable programming" is coming up a lot in the machine learning world. To many, it's not clear if this term reflects a real shift in how researchers think about machine learning, or is just (another) rebranding of "deep learning". This post clarifies what new things differentiable programming (or ∂P) brings to the machine learning table. @@ -15,7 +17,7 @@ Most importantly, differentiable programming is actually a shift _opposite_ from Differentiability is the core idea that makes deep learning so successful. Where a brute force search over even a few hundred model parameters would be far too expensive, gradients mean that we can take a pseudo-random walk around interesting parts of parameter space and find a good set. Doing the next-dumbest thing to brute force gives up surprisingly little generality; it's far from obvious that we can come up with a differentiable objective when, say, working with sequences in language translation, but it turns out to be straightforward with a little ingenuity. -What about biological neurons and [[y = σ(W \times x + b)]]? There's nothing particularly special about this formula; it's just a simple and flexible example of a highly-parameterised non-linear function. In fact, it's probably the worst such function in most cases. A single neural net layer can, in principle, classify cat pictures, but only by the relatively uninteresting trick of acting as a lookup table. It's _guaranteed_ to work! – but the small print warns that you may need more parameters than there are atoms in the universe. To actually make it work you need to *encode problem structure in the model* – which is where it starts to look a lot more like traditional programming. +What about biological neurons and $y = σ(W \times x + b)$? There's nothing particularly special about this formula; it's just a simple and flexible example of a highly-parameterised non-linear function. In fact, it's probably the worst such function in most cases. A single neural net layer can, in principle, classify cat pictures, but only by the relatively uninteresting trick of acting as a lookup table. It's _guaranteed_ to work! – but the small print warns that you may need more parameters than there are atoms in the universe. To actually make it work you need to *encode problem structure in the model* – which is where it starts to look a lot more like traditional programming. For example, ConvNets have a huge advantage over the perceptron because they re-use [image kernels](https://en.wikipedia.org/wiki/Kernel_(image_processing)), which are long known to exploit translational invariance. An edge is an edge whether it shows up in the top left of an image or the centre, but where a perceptron would have to learn this case by case, a kernel can respond to any part of the image at once. It's hard to analyse convolutional nets in statistical terms, but much easier to see them as an auto-tuned version of what image processing experts used to write by hand. The image kernel is the first and simplest differentiable program. @@ -24,7 +26,7 @@ For example, ConvNets have a huge advantage over the perceptron because they re- ML toolkits increasingly support algorithmic differentiation (AD), allowing us to differentiate models with for loops, branches and recursion – or any program built on a set of differentiable mathematical primitives. This has led to more complex architectures: NLP models increasingly look more like classical grammar parsers with [stack-augmented](https://arxiv.org/abs/1603.06021) models, and one can even implement a [Turing machine analog](https://arxiv.org/pdf/1410.5401.pdf) or a [programming language interpreter](https://arxiv.org/abs/1605.06640) in a differentiable way. -The final step taken by differentiable programming is to no longer see matrix multiplies, convolutions and RNNs as the fundamental building blocks of deep learning, but instead as mere special cases. We can apply the techniques of deep learning to *any* parameterised, differentiable function [[f(x)]]. [[f]] could be a matrix multiply, but functions as complex as physics simulators or ray tracers can be differentiated and optimised just as well. Even [quantum computation](https://arxiv.org/abs/1803.00745) can fit into this framework. +The final step taken by differentiable programming is to no longer see matrix multiplies, convolutions and RNNs as the fundamental building blocks of deep learning, but instead as mere special cases. We can apply the techniques of deep learning to *any* parameterised, differentiable function $f(x)$. $f$ could be a matrix multiply, but functions as complex as physics simulators or ray tracers can be differentiated and optimised just as well. Even [quantum computation](https://arxiv.org/abs/1803.00745) can fit into this framework. Scientists have long used mechanistic models that sit between explicit programming and machine learning. Differential equations fit to data via sensitivities – as in physics, epidemiology or pharmacodynamics – are [equivalent in all but terminology to neural networks](https://julialang.org/blog/2019/01/fluxdiffeq). They are just far more constrained in what functions they can represent, making it easier to get a good result. @@ -41,4 +43,6 @@ If this is all so wonderful, why isn't everybody doing it already? Unfortunately Differentiable programming applies the techniques of deep learning to *complex existing programs*, taking advantage of the huge amount of knowledge embedded within them. Deep learning, statistics, programming and the sciences all have something to say about modelling the world around us, and it's time to put these fields [into a particle collider](https://arxiv.org/pdf/1702.00748.pdf). This will both improve current models and enable ML to be applied in areas where its current limitations – either interpretability or its computational and data requirements – make it infeasible alone. +~~~

Thanks to Hannah Lepper and James Bradbury for feedback on this post.

+~~~ diff --git a/blog/_posts/2019-03-05-dp-vs-rl.md b/blogposts/2019-03-05-dp-vs-rl.md similarity index 81% rename from blog/_posts/2019-03-05-dp-vs-rl.md rename to blogposts/2019-03-05-dp-vs-rl.md index de121d53..4491d292 100755 --- a/blog/_posts/2019-03-05-dp-vs-rl.md +++ b/blogposts/2019-03-05-dp-vs-rl.md @@ -1,19 +1,18 @@ ---- -title: Differentiable Control Problems -author: Mike Innes, Neethu Maria Joy, Tejan Karmali -layout: blog ---- ++++ +title = "Differentiable Control Problems" +published = "5 March 2019" +author = "Mike Innes, Neethu Maria Joy, Tejan Karmali" ++++ We've discussed the idea of [differentiable programming](https://fluxml.ai/2019/02/07/what-is-differentiable-programming.html), where we incorporate existing programs into deep learning models. This article shows what ∂P can bring to some simple but classic control problems, where we would normally use black-box Reinforcement Learning (RL). ∂P-based models not only learn far more effective control strategies, but also train orders of magnitude faster. The [code](https://github.com/FluxML/model-zoo/tree/master/contrib/games/differentiable-programming/trebuchet) is all available to run for yourself – they will mostly train in a few seconds on any laptop. - ## Follow the Gradient -Differentiation is what makes deep learning tick; given a function [[y = f(x)]] we use the gradient [[\frac{dy}{dx}]] to figure out how a change in [[x]] will affect [[y]]. Despite the mathematical clothing, gradients are actually a very general and intuitive concept. Forget the formulas you had to stare at in school; let's do something more fun, like throwing stuff. +Differentiation is what makes deep learning tick; given a function $y = f(x)$ we use the gradient $\frac{dy}{dx}$ to figure out how a change in $x$ will affect $y$. Despite the mathematical clothing, gradients are actually a very general and intuitive concept. Forget the formulas you had to stare at in school; let's do something more fun, like throwing stuff. - +![](/assets/2019-03-05-dp-vs-rl/trebuchet-basic.gif) -When we throw things with a trebuchet, our [[x]] represents a setting (say, the size of the counterweight, or the angle of release), and [[y]] is the distance the projectile travels before landing. If you're trying to aim, the gradient tells you something very useful – whether a change in aim will increase or decrease the distance. To maximise distance, just follow the gradient. +When we throw things with a trebuchet, our $x$ represents a setting (say, the size of the counterweight, or the angle of release), and $y$ is the distance the projectile travels before landing. If you're trying to aim, the gradient tells you something very useful – whether a change in aim will increase or decrease the distance. To maximise distance, just follow the gradient. Alright, but how can we get this magical number? The trick is a process called [algorithmic differentiation](https://github.com/FluxML/Zygote.jl), which is able to differentiate not only simple formulas like you learned in school, but also _programs_ of any complexity – like our trebuchet simulator. The upshot is that we can take a [simple simulator](https://github.com/Roboneet/Trebuchet.jl), written in Julia and [DiffEq](https://github.com/JuliaDiffEq/DifferentialEquations.jl) with no deep learning in mind, and get gradients for it in a single function call. @@ -32,19 +31,19 @@ Now we have that, let's do something interesting with it. A simple way to use this is to aim the trebuchet at a target, using gradients to fine-tune the angle of release; this kind of thing is common under the name of _parameter estimation_, and we've [covered examples like it before](https://julialang.org/blog/2019/01/fluxdiffeq). We can make things more interesting by going meta: instead of aiming the trebuchet given a single target, we'll optimise a neural network that can aim it given _any_ target. Here's how it works: the neural net takes two inputs, the target distance in metres and the current wind speed. The network spits out trebuchet settings (the mass of the counterweight and the angle of release) that get fed into the simulator, which calculates the achieved distance. We then compare to our target, and _backpropagate through the entire chain_, end to end, to adjust the weights of the network. Our "dataset" is a randomly chosen set of targets and wind speeds. - +![](/assets/2019-03-05-dp-vs-rl/trebuchet-flow.png) A nice property of this simple model is that training it is _fast_, because we've expressed exactly what we want from the model in a fully differentiable way. Initially it looks like this: - +![](/assets/2019-03-05-dp-vs-rl/trebuchet-miss.gif) After about five minutes of training (on a single core of my laptop's CPU), it looks like this: - +![](/assets/2019-03-05-dp-vs-rl/trebuchet-hit.gif) If you want to try pushing it, turn up the wind speed: - +![](/assets/2019-03-05-dp-vs-rl/trebuchet-wind.gif) It's only off by 16cm, or about 0.3%. @@ -52,55 +51,54 @@ What about just aiming the trebuchet directly? It is easy to do this by gradient This is about the simplest possible control problem, which we use mainly for illustrative purposes. But we can apply the same techniques, in more advanced ways, to classic RL problems as well. - ## Cart, meet Pole A more recognisable control problem is [CartPole](https://gym.openai.com/envs/CartPole-v0/), the "hello world" for reinforcement learning. The task is to learn to balance an upright pole by nudging its base left or right. Our setup is broadly similar to the trebuchet case: a [Julia implementation](https://github.com/tejank10/Gym.jl) means we can directly treat the reward produced by the environment as a loss. ∂P allows us to switch seamlessly from model-free to model-based RL. - +![](/assets/2019-03-05-dp-vs-rl/cartpole-flow.png) The astute reader may notice a snag. The action space for cartpole – nudge left or right – is discrete, and therefore not differentiable. We solve this by introducing a _differentiable discretisation_, defined [like so](https://github.com/FluxML/model-zoo/blob/cdda5cad3e87b216fa67069a5ca84a3016f2a604/games/differentiable-programming/cartpole/DiffRL.jl#L32): -$[[\begin{aligned} +$$ +\begin{aligned} f(x) &= \begin{cases} 1 & x \ge 0 \\\ -1 & x < 0 \end{cases} \\\ \frac{df}{dx} &= 1 -\end{aligned}]] +\end{aligned} +$$ -In other words, we force the gradient to behave as if [[f]] were the identity function. Given how much the mathematical idea of differentiability already gets abused in ML, it's perhaps not surprising that we can just cheat here; for training all we need is a signal to inform our pseudo-random walk around parameter space, and the rest is details. +In other words, we force the gradient to behave as if $f$ were the identity function. Given how much the mathematical idea of differentiability already gets abused in ML, it's perhaps not surprising that we can just cheat here; for training all we need is a signal to inform our pseudo-random walk around parameter space, and the rest is details. The results speak for themselves. Where RL methods need to train for hundreds of episodes before solving the problem, the ∂P model only needs around 5 episodes to win conclusively. - +![](/assets/2019-03-05-dp-vs-rl/cartpole.gif) ## The Pendulum & Backprop through Time An important aim for RL is to handle _delayed reward_, when an action doesn't help us until several steps in the future. ∂P allows this too, and in a very familiar way: when the environment is differentiable, we can actually train the agent using backpropagation through time, just like a recurrent net! In this case the environmental state becomes the "hidden state" that changes between time steps. - +![](/assets/2019-03-05-dp-vs-rl/bptt.png) To demonstrate this technique we looked at the [pendulum](https://github.com/openai/gym/wiki/Pendulum-v0) environment, where the task is to swing a pendulum until it stands upright, keeping it balanced with minimal effort. This is hard for RL models; after around 20 episodes of training the problem is solved, but often the route to a solution is visibly sub-optimal. In contrast, BPTT can beat the [RL leaderboard](https://github.com/openai/gym/wiki/Leaderboard#pendulum-v0) in _a single episode of training_. It's instructive to actually watch this episode unfold; at the beginning of the recording the strategy is random, and the model improves over time. The pace of learning is almost alarming. - +![](/assets/2019-03-05-dp-vs-rl/pendulum-training.gif) Despite only experiencing a single episode, the model generalises well to handle any initial angle, and has something pretty close to the optimal strategy. When restarted the model looks more like this. - +![](/assets/2019-03-05-dp-vs-rl/pendulum-dp.gif) This is just the beginning; we'll get the real wins applying DP to environments that are too hard for RL to work with at all, where rich simulations and models already exist (as in much of engineering and the sciences), and where interpretability is an important factor (as in medicine). - ## The Map Is Not The Territory The limitation of these toy models is that they equate the simulated training environment with the test environment; of course, the real world is not differentiable. In a more realistic model the simulation gives us a coarse outline of behaviour that is refined with data. That data informs (say) the simulated effect of wind, in turn improving the quality of gradients the simulator passes to the controller. Models can even form part of a controller's forward pass, enabling it to refine its predictions without having to learn system dynamics from scratch. Exploring these new architectures will make for exciting future work. - ## Coda The core idea is that _differentiable programming_, where we simply write an arbitrary numerical program and optimise it via gradients, is a powerful way to come up with better deep learning-like models and architectures – especially when we have a large library of differentiable code to hand. The toy models described are really only previews, but we hope they give an intuition for how these ideas can be applied in more realistic ways. -Just as functional programming involves reasoning about and expressing algorithms using functional patterns, differentiable programming involves expressing algorithms using differentiable patterns. Many such design patterns have already been developed by the deep learning community, such as for handling control problems or sequence and tree structured data. As the field matures, many more will be invented, and the resulting programs are likely to make even the most advanced current deep learning architectures look crude by comparison. \ No newline at end of file +Just as functional programming involves reasoning about and expressing algorithms using functional patterns, differentiable programming involves expressing algorithms using differentiable patterns. Many such design patterns have already been developed by the deep learning community, such as for handling control problems or sequence and tree structured data. As the field matures, many more will be invented, and the resulting programs are likely to make even the most advanced current deep learning architectures look crude by comparison. diff --git a/blog/_posts/2019-05-31-JSoC-Cohort.md b/blogposts/2019-05-30-JSoC-Cohort.md similarity index 96% rename from blog/_posts/2019-05-31-JSoC-Cohort.md rename to blogposts/2019-05-30-JSoC-Cohort.md index 378526ed..93c1e2d9 100755 --- a/blog/_posts/2019-05-31-JSoC-Cohort.md +++ b/blogposts/2019-05-30-JSoC-Cohort.md @@ -1,8 +1,8 @@ ---- -title: JSoC Cohort -author: Tejan Karmali, Shreyas Kowshik, Kartikey Gupta, Manjunath Bhat, Avik Pal, Raghvendra Gupta -layout: blog ---- ++++ +title = "JSoC Cohort" +published = "30 June 2019" +author = "Tejan Karmali, Shreyas Kowshik, Kartikey Gupta, Manjunath Bhat, Avik Pal, Raghvendra Gupta" ++++ We are excited to introduce our JSoC students accepted this year! Flux is hosting 6 JSoC students this time. They are a mix of students funded by [Google Summer of Code](https://summerofcode.withgoogle.com/) and Julia Season of Contributions, which is run by the community, thanks to the generous support from [NumFOCUS](https://numfocus.org/). Large parts of Flux ecosystem were created or improved by the students accepted through JSoC, many of whom have gone on to become long time contributors to FluxML. This year, we are proud to have students who will be working on a variety of sub-domains of Machine Learning, ranging from Differentiable Programming and Reinforcement Learning to GAN and Ray Tracing; to demonstrate a fresh approach to these paradigms using Julia. diff --git a/blog/_posts/2019-09-11-simulating-the-motion-of-charges.md b/blogposts/2019-09-11-simulating-the-motion-of-charges.md similarity index 94% rename from blog/_posts/2019-09-11-simulating-the-motion-of-charges.md rename to blogposts/2019-09-11-simulating-the-motion-of-charges.md index 6b7cb7ce..1e719fe0 100755 --- a/blog/_posts/2019-09-11-simulating-the-motion-of-charges.md +++ b/blogposts/2019-09-11-simulating-the-motion-of-charges.md @@ -1,8 +1,8 @@ ---- -title: Simulating the Motion of Charged Bodies -author: Sudhanshu Agrawal sudhanshuagr27@ucla.edu -layout: blog ---- ++++ +title = "Simulating the Motion of Charged Bodies" +published = "11 November 2019" +author = "Sudhanshu Agrawal sudhanshuagr27@ucla.edu" ++++ > “We demand rigidly defined areas of doubt and uncertainty!” – Douglas Adams, The Hitchhiker's Guide To The Galaxy @@ -37,11 +37,11 @@ The main advantage to doing so is that potential energy is a scalar quantity whe Let’s look at our classic formula to calculate potential energy -$[[U = \frac{1}{4 \pi \epsilon_0}\frac{q_1q_2}{r}]] +$$U = \frac{1}{4 \pi \epsilon_0}\frac{q_1q_2}{r}$$ -It quantifies the potential energy [[U]] of a system of two point-charges with magnitudes q1 and q2, separated by a distance r in free space (vacuum). +It quantifies the potential energy $U$ of a system of two point-charges with magnitudes q1 and q2, separated by a distance r in free space (vacuum). -If we want the total potential energy of a system of [[n]] charges, we just apply this formula [[^nC_2]] times. +If we want the total potential energy of a system of $n$ charges, we just apply this formula $^nC_2$ times. ## Let's Begin diff --git a/blog/_posts/2020-06-29-acclerating-flux-torch.md b/blogposts/2020-06-29-acclerating-flux-torch.md similarity index 97% rename from blog/_posts/2020-06-29-acclerating-flux-torch.md rename to blogposts/2020-06-29-acclerating-flux-torch.md index 335515c2..28c3d432 100755 --- a/blog/_posts/2020-06-29-acclerating-flux-torch.md +++ b/blogposts/2020-06-29-acclerating-flux-torch.md @@ -1,8 +1,8 @@ ---- -title: Accelerating Flux.jl with PyTorch kernels -author: Dhairya Gandhi, Mike Innes -layout: blog ---- ++++ +title = "Accelerating Flux.jl with PyTorch kernels" +published = "29 July 2020" +author = "Dhairya Gandhi, Mike Innes" ++++ Julia and Flux provide a flexible [differentiable programming](./2019-03-05-dp-vs-rl.md) system. Flux does not trade flexibility and abstraction for performance, and in fact strives to achieve both in the same package. For example, Flux is able to target multiple hardware accelerators such as [GPUs](https://fluxml.ai/Flux.jl/stable/gpu/) and [TPUs](https://arxiv.org/pdf/1810.09868.pdf). As a result, it is one of the pillars of Julia's [deep learning ecosystem](https://juliahub.com/ui/Packages/CUDAnative/4Zu2W/3.1.0?t=2), with almost 40 packages leveraging it. @@ -10,10 +10,12 @@ Here, we introduce [Torch.jl](https://github.com/FluxML/Torch.jl), a package tha For popular object detection models - ResNet50, ResNet101 and VGG19 - we compare inference times for Flux using Torch.jl with our native tooling, and find Flux+Torch to be 2-3x faster. On larger batch sizes, the difference is much higher, since Julia's GPU stack needs further development in the area of memory management and GC. +~~~

+~~~ All runs are with a Tesla K40 (12 GB), julia v1.4.2, Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz and 32 GB of DDR3 Memory. diff --git a/blog/_posts/2020-12-20-Flux3D.md b/blogposts/2020-12-20-Flux3D.md similarity index 98% rename from blog/_posts/2020-12-20-Flux3D.md rename to blogposts/2020-12-20-Flux3D.md index c7d15168..07cf95a0 100644 --- a/blog/_posts/2020-12-20-Flux3D.md +++ b/blogposts/2020-12-20-Flux3D.md @@ -1,8 +1,8 @@ ---- -title: Flux3D.jl, 3D Vision Library in Julia -author: Nirmal Suthar, Avik Pal, Dhairya Gandhi -layout: blog ---- ++++ +title = "Flux3D.jl, 3D Vision Library in Julia" +published = "20 December 2020" +author = "Nirmal Suthar, Avik Pal, Dhairya Gandhi" ++++ 3D computer vision involves various computer vision techniques like classification, segmentation, object detection, super-resolution and many more. Modeling these problems becomes significantly easier when there is a general purpose differentiation library available, alongside the litany of tools needed to solve a train ML model, which FluxML already supports. @@ -10,9 +10,11 @@ Performing 3D vision tasks involve preparing datasets to fit a certain represent ## What is Flux3D.jl +~~~
+~~~ Flux3D.jl is a 3D vision library, written completely in Julia. This package utilizes Flux.jl and Zygote.jl as its building blocks for training 3D vision models and for supporting differentiation. This package also has the support of CUDA GPU acceleration with CUDA.jl. Some of the roles of Flux3D are: @@ -32,15 +34,16 @@ Docs : [fluxml.ai/Flux3D.jl/stable](https://fluxml.ai/Flux3D.jl/stable) Kaolin is a popular 3D vision library based on PyTorch. Flux3D.jl is overall faster than Kaolin in terms of applying transforms on PointCloud/TriMesh and comparable with Kaolin in terms of applying metrics. However, there must be work done to improve the back pass in laplacian loss which uses `SparseArrays`. From the benchmarks, we can tell that Flux3D can outperform Kaolin. Some key-differences between the two are discussed later in this post. +~~~

+~~~ ## Short Walkthrough of the Flux3D.jl - A basic training pipeline requires preparing the datasets, defining the model, the loss function and finally training it. Let's go through each step along with visualising and evaluating the results. @@ -153,9 +156,11 @@ Flux and Zygote takes care of everything here :) Additonally, 3D structures and all relevant transforms, as well as metrics, are compatible with Zygote for supporting differentiation. +~~~
+~~~ ### 5. Visualization and Evaluation @@ -176,9 +181,11 @@ julia> vbox( ``` +~~~
+~~~ ## Why use Julia and FluxML ecosystem diff --git a/blog/_posts/2021-12-1-flux-numfocus.md b/blogposts/2021-12-1-flux-numfocus.md similarity index 94% rename from blog/_posts/2021-12-1-flux-numfocus.md rename to blogposts/2021-12-1-flux-numfocus.md index 71a7eac4..83819a55 100644 --- a/blog/_posts/2021-12-1-flux-numfocus.md +++ b/blogposts/2021-12-1-flux-numfocus.md @@ -1,12 +1,14 @@ ---- -title: Flux <3 NumFOCUS -author: Dhairya Gandhi, Logan Kilpatrick -layout: blog ---- ++++ +title = "Flux <3 NumFOCUS" +published = "1 December 2021" +author = "Dhairya Gandhi, Logan Kilpatrick" ++++ +~~~

+~~~ We are very excited to announce that [FluxML](https://fluxml.ai) is partnering with [NumFOCUS](https://numfocus.org) as an affiliated project to further the cause of open and reproducible science and growing the adoption of the FluxML ecosystem. Flux has always had the mission of being a simple, hackable and performant approach to machine learning, which is extended to a number of domains in science by means of differentiable programming. diff --git a/config.md b/config.md new file mode 100644 index 00000000..ab3e569b --- /dev/null +++ b/config.md @@ -0,0 +1,21 @@ ++++ +author = "FluxML" +mintoclevel = 2 + +website_title = "Flux.jl" +website_descr = "The elegant machine learning library" +website_url = "https://fluxml.ai" +website_img = "/assets/images/FluxGitHubPreview.png" +website_footer = """ + Flux: A Deep Learning Library for the Julia Programming Language + """ +website_twitter = "Follow @FluxML" +website_twitter_url = "https://twitter.com/FluxML?ref_src=twsrc%5Etfw" + +ignore = ["CONTRIBUTING.md"] + +prepath = get(ENV, "PREVIEW_FRANKLIN_PREPATH", ".") +website_url = get(ENV, "PREVIEW_FRANKLIN_WEBSITE_URL", "fluxml.ai") ++++ + +\newcommand{\totop}{~~~

⇧ back to top

~~~} diff --git a/experiments/breakout/assets/js/Board.js b/experiments/breakout/assets/js/Board.js deleted file mode 100644 index 12c8f573..00000000 --- a/experiments/breakout/assets/js/Board.js +++ /dev/null @@ -1,15 +0,0 @@ -function Board(container, {env}={}){ - this.container = container - this.render = ()=>{ - env.render(); - if(env.done()){ - show($$(".overlay #gameOver")) - }else{ - hide($$(".overlay #gameOver")) - } - }; - - this.removeStartScreen = ()=>{ - hide($$(".overlay #start")); - } -} diff --git a/experiments/breakout/assets/js/Breakout.js b/experiments/breakout/assets/js/Breakout.js deleted file mode 100644 index afc80560..00000000 --- a/experiments/breakout/assets/js/Breakout.js +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************** -======================================================= -Breakout Game -======================================================= -******************************************************/ -function Breakout(canvas,{width=500, height=400, brick_height=20, brick_width=50, paddle_width=50, paddle_height=10, ball_radius=5}={}){ - var score = 0; - canvas.width = width; - canvas.height = height; - var components = { - paddle: new Paddle(new Vector(Math.floor(width/2), canvas.height - paddle_height), { - width:paddle_width, - height:paddle_height, - total_width: width - }), - bricks: new BrickCollection(6, {width, brick_width, height, brick_height, padding: 40, colors: ["#c84848", "#c66c3a", "#b47a30", "#a2a22a", "#48a048","#4248c8"]}), - ball: new Ball(new Vector(Math.floor(width/2), Math.floor(height/2)), new Vector(-5, -5), {radius:ball_radius}) - } - - this.draw = ()=>{ - var ctx = canvas.getContext('2d'); - //background - ctx.fillStyle = "#000"; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - for( var c in components){ - components[c].draw(canvas); - } - ctx.font = '18px arial'; - ctx.fillStyle = "#fff"; - ctx.textAlign = "right"; - ctx.textBaseline = "top" - ctx.fillText('Score: '+ score, canvas.width - 10, 10); - } - - - this.play = ()=>{ - this.step(); - if(!this.done()) - requestAnimationFrame(this.play); - } - - this.step = (dir)=>{ - components.ball.move(); - - this.action(dir); - this.movePaddle(); - - var reward = this.collisionDetector(); - score += reward; - this.draw(); - return reward; - } - - this.collisionDetector = function(){ - var ball = components.ball; - var brickHit = components.bricks.detectCollision(ball); // collision with bricks - var reward = 0; - if(brickHit){ - - brickHit.deactivate(); - reward = 10; - ball.rebound([1, -1]); - } - var paddleHit = components.paddle.detectCollision(ball); // collision with paddle - if(paddleHit){ - ball.rebound([1, -1]); - } - var wallHit = components.ball.detectCollision(width, height); // collision with walls - wallHit.forEach(w=> ball.rebound(w)); - return reward; - } - - this.done = function(){ - return components.bricks.allHit() || components.ball.pos.y > height; - } - - this.movePaddle = ()=> components.paddle.move(); - - this.action = (dir)=>{ - components.paddle.setDirection(dir); - } - - this.reset = function(){ - components.ball.pos = new Vector(Math.floor(width/2), Math.floor(height/2)); - components.ball.speed = new Vector(-5, -5); - components.bricks.activateAll(); - score = 0; - } - - - this.render = this.draw; - this.config = ()=>{return null}; -} \ No newline at end of file diff --git a/experiments/breakout/assets/js/components.js b/experiments/breakout/assets/js/components.js deleted file mode 100644 index 3930e451..00000000 --- a/experiments/breakout/assets/js/components.js +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************** -======================================================= -Components -======================================================= -******************************************************/ - -function Brick(pos, active, {color="#0f0", width=50, height=10}={}){ - this.pos = pos; - this.active = active; - - this.draw = (canvas)=>{ - var ctx = canvas.getContext('2d'); - if(this.active){ - ctx.fillStyle = color; - ctx.fillRect(this.pos.x, this.pos.y, width, height); - // ctx.strokeStyle="#fff"; - // ctx.strokeRect(this.pos.x, this.pos.y, width, height); - } - } - - this.detectCollision = (ball)=>{ - if(!this.active)return null - - if((ball.pos.x > this.pos.x && ball.pos.x < this.pos.x + width) - && (ball.pos.y > this.pos.y && ball.pos.y < this.pos.y + height)){ - return this - } - - return null - } - - this.deactivate = ()=>{ - this.active = false; - } - - this.activate = ()=>{ - this.active = true; - } -} - -function BrickCollection(layers, {width, brick_width, height, brick_height, padding, colors}){ - var max_blocks = Math.floor(width/brick_width); - - this.contents = (new Array(layers*max_blocks)).fill(0).map((_, i)=> { - var color = colors[Math.floor(i/max_blocks)]; - var x = Math.floor((i% max_blocks)*brick_width); - var y = Math.floor(i/max_blocks)*brick_height + padding; - - return new Brick( - new Vector(x, y), - true, {width: brick_width, height: brick_height, color}) - }); - - this.draw = (canvas)=> { this.contents.forEach(e=>e.draw(canvas)); }; - - this.detectCollision = (ball)=>{ - if( ball.pos.y - ball.radius > layers*height + padding) return null; - - for (var brick of this.contents){ - if(brick.detectCollision(ball)) - return brick; - } - - return null; - } - - this.allHit = ()=>{ - for (var brick of this.contents){ - if(brick.active)return false; - } - return true; - } - - this.activateAll = ()=>{ - this.contents.forEach(brick => brick.activate()) - } -} diff --git a/experiments/breakout/assets/js/script.js b/experiments/breakout/assets/js/script.js deleted file mode 100644 index 1c98bdf7..00000000 --- a/experiments/breakout/assets/js/script.js +++ /dev/null @@ -1,27 +0,0 @@ -var __init__ = (function(){ - - var env = new Breakout(document.querySelector("#playground")); - var board = new Board(document.querySelector(".board"), {env}); - var game = new Game(env, board, null); - - document.addEventListener('keydown', event => { - var code = event.keyCode; - - if(code == 13){ - // remove startScreen - board.removeStartScreen(); - return game.play(); - } - - if(code != 39 && code != 37)return; - - game.action(code - 38); - }) - - document.addEventListener('keyup', event => { - game.action(0); - }) - env.draw(); -}) - -window.onload = __init__; \ No newline at end of file diff --git a/experiments/breakout/index.html b/experiments/breakout/index.html deleted file mode 100644 index fb17e5ce..00000000 --- a/experiments/breakout/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -layout: default -game: breakout ---- - -{% include experiments/game/headers.html %} - -{% assign game = site.data.experiments[page.game] %} -{% include experiments/game/content.html game=game %} - -{% include experiments/game/footer.html %} - - - - - - \ No newline at end of file diff --git a/experiments/cartPole/assets/bson/dqn.bson b/experiments/cartPole/assets/bson/dqn.bson deleted file mode 100644 index 602169cd..00000000 Binary files a/experiments/cartPole/assets/bson/dqn.bson and /dev/null differ diff --git a/experiments/cartPole/assets/css/cartpole.css b/experiments/cartPole/assets/css/cartpole.css deleted file mode 100644 index 2f6350a2..00000000 --- a/experiments/cartPole/assets/css/cartpole.css +++ /dev/null @@ -1,72 +0,0 @@ -#playground{ - /*background: linear-gradient(to bottom right, var(--dark), #5f924d, var(--dark)); */ - background: var(--medium); - margin-bottom: 10px; -} - -div{ - position:relative; -} - -#playground, #controls{ - /*box-shadow: 2px 2px 8px #060638;*/ -} - -#playground, #controls, .board, .demo_wrapper{ - width: 60vw; -} - -#playground, .board{ - min-height: 200px; - border-bottom-left-radius: 6px; - border-bottom-right-radius: 6px; - overflow: hidden; -} - -.demo_wrapper{ - margin: 0px auto; - height: 90%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} - -@media only screen and (max-width:768px){ - #playground, #controls, .board, .demo_wrapper{ - width: 90vw; - } -} - -.levels{ - flex: 1; - /* align-items: flex-end; */ - display: flex; - flex-direction: row; - justify-content: flex-end; - align-items: center; -} - -.levels > div{ - padding: 0px 10px; - border: 1px solid; - margin: 0 10px 0 0; - border-radius: 6px; - cursor: pointer; - transition: all 0.4s linear; -} - -.levels .selected{ - background: var(--dark); - color: var(--light); -} - -.stats{ - display: flex; - flex-direction: row; - /*justify-content: ;*/ - padding: 20px; -} -.stats > p{ - margin: 0 5px; -} \ No newline at end of file diff --git a/experiments/cartPole/assets/css/keyboard.css b/experiments/cartPole/assets/css/keyboard.css deleted file mode 100644 index 69ba34be..00000000 --- a/experiments/cartPole/assets/css/keyboard.css +++ /dev/null @@ -1,74 +0,0 @@ -.keyboard{ - position: absolute; -} - -.arrowkey{ - position: absolute; - top: 0; - border: 1px solid #fff; - left: 0; - width: 27%; - height: 44%; - border-radius: 3px; -} - -.keyboard .up, .keyboard .down{ - left: 34%; -} - -.keyboard .down,.keyboard .right,.keyboard .left{ - top: 51%; -} - -.keyboard .right{ - left: 66%; -} - - -.keyboard .left{ - left: 2%; -} - -.keyboard .up:before, .keyboard .left:before, .keyboard .right:before, .keyboard .down:before{ - position: absolute; - content: ''; - height: 0; - width: 0; - border: 5px solid transparent; -} - -.keyboard .up:before{ - top: calc(40% - 5px); - left: calc(50% - 5px); - border-bottom: 5px solid #fff; -} - -.keyboard .down:before{ - top: calc(60% - 5px); - left: calc(50% - 5px); - border-top: 5px solid #fff; -} - -.keyboard .right:before{ - top: calc(50% - 5px); - left: calc(60% - 5px); - border-left: 5px solid #fff; -} - -.keyboard .left:before{ - top: calc(50% - 5px); - left: calc(40% - 5px); - border-right: 5px solid #fff; -} - -.keyboard .highlight{ - background: #fff; -} - -.keyboard .highlight[data-key="left"]:before{ - border-right-color: #288228; -} - -.keyboard .highlight[data-key="right"]:before{ - border-left-color: #288228; -} \ No newline at end of file diff --git a/experiments/cartPole/assets/js/Board.js b/experiments/cartPole/assets/js/Board.js deleted file mode 100644 index a90fa90b..00000000 --- a/experiments/cartPole/assets/js/Board.js +++ /dev/null @@ -1,119 +0,0 @@ -(function(obj){ - - Object.assign(obj, {Board}); - - // render board - function Board(container, { - cartColor="#333", - poleColor="#fff" - }={}){ - const template = ( - '\ -
\ -

Game Over

\ -
\ -

Score: 0

\ -

\ -
\ -
\ -
' - ) - container.innerHTML = template; - - this.container = container; - this.cartColor = cartColor; - this.poleColor = poleColor; - this.keyboard = new Keyboard(container.querySelector('.keyboard')); - this.canvas = container.querySelector('#playground'); - this.ctx = this.canvas.getContext('2d'); - this.overlay = container.querySelector('.overlay'); - this.score = this.overlay.querySelector('.score span'); - this.apm = this.overlay.querySelector('.apm'); - this.gameOverScreen = this.overlay.querySelector('.game-over'); - } - - - Board.prototype.render = function({ - state, - action, - score, - cart_height, - cart_length, - pole_length, - pole_diameter, - done, - x_threshold, - kicked, - apm - }){ - // console.log(kicked); - ({x, theta} = state); - - var scaleToPixelsX = this.canvas.width*0.5/(cart_length/2 + x_threshold); - var scaleToPixelsY = this.canvas.height*0.5/(cart_height + pole_length); - - this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - - var cartX = (this.canvas.width/2 + scaleToPixelsX*(x - cart_length/2)); - var cartY = this.canvas.height - scaleToPixelsY*cart_height; - var rotateAngle = theta - Math.PI/2; - - // draw pole - this.ctx.translate(cartX + scaleToPixelsX*cart_length/2, cartY + scaleToPixelsY*pole_diameter/2); - this.ctx.fillStyle = this.poleColor; - this.ctx.rotate(rotateAngle); - this.ctx.scale(scaleToPixelsY, scaleToPixelsX); // needs to be (y, x) as this is rotated - this.ctx.fillRect(-pole_diameter/2, -pole_diameter/2, pole_length, pole_diameter); - this.ctx.scale(1/scaleToPixelsY, 1/scaleToPixelsX); - this.ctx.rotate(-rotateAngle); - this.ctx.translate(-(cartX + scaleToPixelsX*cart_length/2), -(cartY + scaleToPixelsY*pole_diameter/2)); - - // draw cart - this.ctx.fillStyle = this.cartColor; - this.ctx.fillRect(cartX, cartY, scaleToPixelsX*cart_length, scaleToPixelsY*cart_height); - - var dir = (d) => d == 1? 'left': 'right'; - - // highlight key - if(action != 0){ - this.keyboard.highlight(dir(action)); - } - if(kicked != 0){ - // console.log("draw") - var img = new Image(); - img.src = "./assets/red__" + dir(kicked)+ "_arrow.png"; - var ctx = this.ctx; - img.onload = function(){ - // this.ctx.drawImage(img, x, cartY - cart_height, cartY, cartY); - // console.log() - var v = kicked*2 - 3; - var dy = cart_height*scaleToPixelsY; - var ax = ctx.canvas.width/2 + scaleToPixelsX*(x - v*cart_length/2); - var ay = ctx.canvas.height - dy; - // console.log(v) - if(v == 1){ - ax -= dy; - } - // console.log(dy, ax); - ctx.drawImage(img, ax, ay, dy, dy); - } - } - if(apm != -1){ - this.apm.innerText = "APM: " + apm; - }else{ - this.apm.innerText = ""; - } - - // change score - this.score.innerText = score; - - // game over screen - if(done){ - this.gameOverScreen.className = this.gameOverScreen.className.replace("hidden-screen", ""); - }else{ - if(this.overlay.querySelector('.hidden-screen') == null){ - this.gameOverScreen.className += " hidden-screen"; - } - } - } -})(window) \ No newline at end of file diff --git a/experiments/cartPole/assets/js/CartPole.js b/experiments/cartPole/assets/js/CartPole.js deleted file mode 100644 index af130ba2..00000000 --- a/experiments/cartPole/assets/js/CartPole.js +++ /dev/null @@ -1,83 +0,0 @@ -(function(obj){ - - Object.assign(obj, {CartPole}) - - // cartPole env - function CartPole(){ - // ported from https://github.com/JuliaML/Reinforce.jl/blob/master/src/envs/cartpole.jl - const gravity = 9.8; - const mass_cart = 1.0; - const mass_pole = 0.1; - const total_mass = mass_cart + mass_pole; - const pole_length = 0.5; - const mass_pole_length = mass_pole * pole_length; - const force_mag = 10.0; - const tau = 0.02 ; - - const theta_threshold = Math.PI * 0.25 - const x_threshold = 2.4 - - //display settings - const cart_length = .4 - const cart_height = .05 - const pole_diameter = 0.02 - - var total_reward = 0; - var state = {x: 0, xvel: 0, theta: 0, thetavel: 0}; - var action = 0; - - - this.reset = ()=>{ - state = {x:0, theta: 0, xvel:0, thetavel: 0} - total_reward = 0; - action = 0; - } - - this.step = (a)=>{ - if(this.done()){ - return 0; - } - - action = a; - ({ x, xvel , theta, thetavel } = state); - - force = (action == 1 ? -1 : (a==2)?1:0) * force_mag; // extra action 0 for the case when user doesn't press any key - tmp = (force + mass_pole_length * Math.sin(theta) * (thetavel^2)) / total_mass - thetaacc = (gravity * Math.sin(theta) - tmp * Math.cos(theta)) / (pole_length * (4/3 - mass_pole * (Math.cos(theta)^2) / total_mass)) - xacc = tmp - mass_pole_length * thetaacc * Math.cos(theta) / total_mass; - state.x = (x += tau * xvel) - state.xvel = (xvel += tau * xacc) - state.theta = (theta += tau * thetavel) - state.thetavel = (thetavel += tau * thetaacc); - - var reward = this.done() || a == 0? 0.0 : 1.0; - total_reward += reward; - return reward - } - - this.done = ()=>{ - ({x, xvel , theta, thetavel } = state); - return !(Math.abs(x) <= x_threshold && Math.abs(theta) <= theta_threshold); - } - - this.config = ()=>{ - var done = this.done(); - - return ({ - state, - action, - score: total_reward, - cart_height, - cart_length, - pole_length, - pole_diameter, - x_threshold, - done - }); - - } - - this.state = () => state; - } - -})(window) \ No newline at end of file diff --git a/experiments/cartPole/assets/js/Keyboard.js b/experiments/cartPole/assets/js/Keyboard.js deleted file mode 100644 index 51d5fed9..00000000 --- a/experiments/cartPole/assets/js/Keyboard.js +++ /dev/null @@ -1,29 +0,0 @@ -(function(obj){ - Object.assign(obj, {Keyboard}); - - function Keyboard(container){ - const template = ( - '
\ -
\ -
\ -
' - ) - - container.innerHTML = template; - - this.highlight = (data)=>{ - - var old = container.querySelector('.highlight'); - if(old != null) - old.className = old.className.replace('highlight', ''); - - var key = container.querySelector('[data-key="'+ data +'"]'); - key.className += " highlight"; - setTimeout(()=>{ - key.className = key.className.replace('highlight', ''); - }, 200) - - - } - } -})(window) \ No newline at end of file diff --git a/experiments/cartPole/assets/js/dqn.js b/experiments/cartPole/assets/js/dqn.js deleted file mode 100644 index 3f04f539..00000000 --- a/experiments/cartPole/assets/js/dqn.js +++ /dev/null @@ -1,17 +0,0 @@ -let model = (function () { - let math = tf; - function mandrill(guineafowl) { - return math.add(math.vectorTimesMatrix(guineafowl, model.weights[0]), model.weights[1]); - }; - function buffalo(elk) { - return math.tanh(math.add(math.vectorTimesMatrix(elk, model.weights[2]), model.weights[3])); - }; - function barracuda(owl) { - return math.tanh(math.add(math.vectorTimesMatrix(owl, model.weights[4]), model.weights[5])); - }; - function model(raven) { - return mandrill(buffalo(barracuda(raven))); - }; - model.weights = []; - return model; -})(); \ No newline at end of file diff --git a/experiments/cartPole/assets/js/script.js b/experiments/cartPole/assets/js/script.js deleted file mode 100644 index 21275453..00000000 --- a/experiments/cartPole/assets/js/script.js +++ /dev/null @@ -1,96 +0,0 @@ -// Game -> CartPole , ( Board --> Keyboard ) - -Game.prototype.play = async function(){ - clearTimeout(this.playTimeout); - if(this.env.done())return; - - var scope = this; - switch(this.state){ - case this.states.H: - this.move(this.newAction); - // newAction = 0; - break; - case this.states.C: - this.kick(); - var a = await this.predict(this.env.state()) - var action = await this.transform.action(a); - this.move(action); - tf.dispose(a); - break; - default: - console.log("Invalid state", this.state); - } -} - -Game.prototype.kick = function(){ - this.env.step(this.newAction); - this.kicked = this.newAction; - this.newAction = this.defaultAction(); // we only kick once, not continously -} - -Game.prototype.display = function(){ - var s = this.defaultAction() - var kicked = s; - var apm = -1; - if(this.state == this.states.C){ - kicked = this.kicked; - apm = 60*1000/this.timeInt; - } - this.kicked = s; - - this.out.render(Object.assign({}, this.env.config(), {kicked, apm})); -} - - -var board = new Board(document.querySelector('.board')) - -function __init__(){ - - var cp = new CartPole(); - var game = new Game(cp, board, (e) => tf.tidy(()=>model(e))); - game.setState("human"); - - var reset = () => { - game.setState(game.state); - } - - var eachEl = (p, e, cb) => - Array.from(p.querySelectorAll(e)).forEach(el=> - el.addEventListener('click', (event) =>cb(el, event, p)) - ) - - - eachEl(document.querySelector('.options'), '.option', (el, event, p) => { - game.setState(el.getAttribute('data-state')); - highlight(el, p); - }) - - eachEl(document.querySelector('.levels'), 'div', (el, event, p) => { - // console.log(parseInt(el.getAttribute('data-time'))) - game.timeInt = parseInt(el.getAttribute('data-time')); - highlight(el, p); - }) - // set level to easy - game.setTimeInt(100); - - - // event listeners for keyboard - document.addEventListener('keydown', function(event){ - if(event.keyCode == 39){ // right - game.action(2); - }else if(event.keyCode == 37){ // left - game.action(1); - } - }) - var keyboard = document.querySelector('.keyboard') - keyboard.querySelector('.left').addEventListener('click', function(){ - game.action(1); - }) - keyboard.querySelector('.right').addEventListener('click', function(){ - game.action(2); - }) -} - -loadWeights("assets/bson/dqn.bson", document.querySelector('.board'), __init__, model); - - diff --git a/experiments/cartPole/assets/red__left_arrow.png b/experiments/cartPole/assets/red__left_arrow.png deleted file mode 100644 index 970855c7..00000000 Binary files a/experiments/cartPole/assets/red__left_arrow.png and /dev/null differ diff --git a/experiments/cartPole/assets/red__right_arrow.png b/experiments/cartPole/assets/red__right_arrow.png deleted file mode 100644 index 19cc4b69..00000000 Binary files a/experiments/cartPole/assets/red__right_arrow.png and /dev/null differ diff --git a/experiments/cartPole/index.html b/experiments/cartPole/index.html deleted file mode 100644 index 506a91af..00000000 --- a/experiments/cartPole/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -layout: default ---- - - - - - - - - - - - -
-
-

Flux Experiment: CartPole Game

-
-
-
CartPole
-
-
Easy
-
Hard
-
-
-
-
-
-
-
-
-

Instructions

-

A pole is attached by an un-actuated joint to a cart, which moves along a frictionless track. Use the arrow keys to apply a force on the cart. The pendulum starts upright, and the goal is to prevent it from falling over. A score of +1 is provided for every move that the pole remains upright. The game ends when the pole is more than 15 degrees from vertical, or the cart touches the edges.

- -
-
-
-
- - - - - - - - - - - diff --git a/experiments/chess/assets/chessboardjs/LICENSE.txt b/experiments/chess/assets/chessboardjs/LICENSE.txt deleted file mode 100644 index 4d3575ea..00000000 --- a/experiments/chess/assets/chessboardjs/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -Copyright 2013 Chris Oakman -http://chessboardjs.com/ - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/experiments/chess/assets/chessboardjs/css/chessboard-0.3.0.css b/experiments/chess/assets/chessboardjs/css/chessboard-0.3.0.css deleted file mode 100644 index e987b528..00000000 --- a/experiments/chess/assets/chessboardjs/css/chessboard-0.3.0.css +++ /dev/null @@ -1,70 +0,0 @@ -/*! - * chessboard.js v0.3.0 - * - * Copyright 2013 Chris Oakman - * Released under the MIT license - * https://github.com/oakmac/chessboardjs/blob/master/LICENSE - * - * Date: 10 Aug 2013 - */ - -/* clearfix */ -.clearfix-7da63 { - clear: both; -} - -/* board */ -.board-b72b1 { - border: 2px solid #404040; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -/* square */ -.square-55d63 { - float: left; - position: relative; - - /* disable any native browser highlighting */ - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -/* white square */ -.white-1e1d7 { - background-color: #f0d9b5; - color: #b58863; -} - -/* black square */ -.black-3c85d { - background-color: #b58863; - color: #f0d9b5; -} - -/* highlighted square */ -.highlight1-32417, .highlight2-9c5d2 { - -webkit-box-shadow: inset 0 0 3px 3px yellow; - -moz-box-shadow: inset 0 0 3px 3px yellow; - box-shadow: inset 0 0 3px 3px yellow; -} - -/* notation */ -.notation-322f9 { - cursor: default; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - position: absolute; -} -.alpha-d2270 { - bottom: 1px; - right: 3px; -} -.numeric-fc462 { - top: 2px; - left: 2px; -} \ No newline at end of file diff --git a/experiments/chess/assets/chessboardjs/css/chessboard-0.3.0.min.css b/experiments/chess/assets/chessboardjs/css/chessboard-0.3.0.min.css deleted file mode 100644 index ae68ca06..00000000 --- a/experiments/chess/assets/chessboardjs/css/chessboard-0.3.0.min.css +++ /dev/null @@ -1,2 +0,0 @@ -/*! chessboard.js v0.3.0 | (c) 2013 Chris Oakman | MIT License chessboardjs.com/license */ -.clearfix-7da63{clear:both}.board-b72b1{border:2px solid #fff;-moz-box-sizing:content-box;box-sizing:content-box}.square-55d63{float:left;position:relative;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.white-1e1d7{background-color:#f0d9b5;color:#b58863}.black-3c85d{background-color:#b58863;color:#f0d9b5}.highlight1-32417,.highlight2-9c5d2{-webkit-box-shadow:inset 0 0 3px 3px yellow;-moz-box-shadow:inset 0 0 3px 3px yellow;box-shadow:inset 0 0 3px 3px yellow}.notation-322f9{cursor:default;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;position:absolute}.alpha-d2270{bottom:1px;right:3px}.numeric-fc462{top:2px;left:2px} \ No newline at end of file diff --git a/experiments/chess/assets/chessboardjs/js/chessboard-0.3.0.js b/experiments/chess/assets/chessboardjs/js/chessboard-0.3.0.js deleted file mode 100644 index 8f1ac2d4..00000000 --- a/experiments/chess/assets/chessboardjs/js/chessboard-0.3.0.js +++ /dev/null @@ -1,1714 +0,0 @@ -/*! - * chessboard.js v0.3.0 - * - * Copyright 2013 Chris Oakman - * Released under the MIT license - * http://chessboardjs.com/license - * - * Date: 10 Aug 2013 - */ - -// start anonymous scope -;(function() { -'use strict'; - -//------------------------------------------------------------------------------ -// Chess Util Functions -//------------------------------------------------------------------------------ -var COLUMNS = 'abcdefgh'.split(''); - -function validMove(move) { - // move should be a string - if (typeof move !== 'string') return false; - - // move should be in the form of "e2-e4", "f6-d5" - var tmp = move.split('-'); - if (tmp.length !== 2) return false; - - return (validSquare(tmp[0]) === true && validSquare(tmp[1]) === true); -} - -function validSquare(square) { - if (typeof square !== 'string') return false; - return (square.search(/^[a-h][1-8]$/) !== -1); -} - -function validPieceCode(code) { - if (typeof code !== 'string') return false; - return (code.search(/^[bw][KQRNBP]$/) !== -1); -} - -// TODO: this whole function could probably be replaced with a single regex -function validFen(fen) { - if (typeof fen !== 'string') return false; - - // cut off any move, castling, etc info from the end - // we're only interested in position information - fen = fen.replace(/ .+$/, ''); - - // FEN should be 8 sections separated by slashes - var chunks = fen.split('/'); - if (chunks.length !== 8) return false; - - // check the piece sections - for (var i = 0; i < 8; i++) { - if (chunks[i] === '' || - chunks[i].length > 8 || - chunks[i].search(/[^kqrbnpKQRNBP1-8]/) !== -1) { - return false; - } - } - - return true; -} - -function validPositionObject(pos) { - if (typeof pos !== 'object') return false; - - for (var i in pos) { - if (pos.hasOwnProperty(i) !== true) continue; - - if (validSquare(i) !== true || validPieceCode(pos[i]) !== true) { - return false; - } - } - - return true; -} - -// convert FEN piece code to bP, wK, etc -function fenToPieceCode(piece) { - // black piece - if (piece.toLowerCase() === piece) { - return 'b' + piece.toUpperCase(); - } - - // white piece - return 'w' + piece.toUpperCase(); -} - -// convert bP, wK, etc code to FEN structure -function pieceCodeToFen(piece) { - var tmp = piece.split(''); - - // white piece - if (tmp[0] === 'w') { - return tmp[1].toUpperCase(); - } - - // black piece - return tmp[1].toLowerCase(); -} - -// convert FEN string to position object -// returns false if the FEN string is invalid -function fenToObj(fen) { - if (validFen(fen) !== true) { - return false; - } - - // cut off any move, castling, etc info from the end - // we're only interested in position information - fen = fen.replace(/ .+$/, ''); - - var rows = fen.split('/'); - var position = {}; - - var currentRow = 8; - for (var i = 0; i < 8; i++) { - var row = rows[i].split(''); - var colIndex = 0; - - // loop through each character in the FEN section - for (var j = 0; j < row.length; j++) { - // number / empty squares - if (row[j].search(/[1-8]/) !== -1) { - var emptySquares = parseInt(row[j], 10); - colIndex += emptySquares; - } - // piece - else { - var square = COLUMNS[colIndex] + currentRow; - position[square] = fenToPieceCode(row[j]); - colIndex++; - } - } - - currentRow--; - } - - return position; -} - -// position object to FEN string -// returns false if the obj is not a valid position object -function objToFen(obj) { - if (validPositionObject(obj) !== true) { - return false; - } - - var fen = ''; - - var currentRow = 8; - for (var i = 0; i < 8; i++) { - for (var j = 0; j < 8; j++) { - var square = COLUMNS[j] + currentRow; - - // piece exists - if (obj.hasOwnProperty(square) === true) { - fen += pieceCodeToFen(obj[square]); - } - - // empty space - else { - fen += '1'; - } - } - - if (i !== 7) { - fen += '/'; - } - - currentRow--; - } - - // squeeze the numbers together - // haha, I love this solution... - fen = fen.replace(/11111111/g, '8'); - fen = fen.replace(/1111111/g, '7'); - fen = fen.replace(/111111/g, '6'); - fen = fen.replace(/11111/g, '5'); - fen = fen.replace(/1111/g, '4'); - fen = fen.replace(/111/g, '3'); - fen = fen.replace(/11/g, '2'); - - return fen; -} - -window['ChessBoard'] = window['ChessBoard'] || function(containerElOrId, cfg) { -'use strict'; - -cfg = cfg || {}; - -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ - -var MINIMUM_JQUERY_VERSION = '1.7.0', - START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', - START_POSITION = fenToObj(START_FEN); - -// use unique class names to prevent clashing with anything else on the page -// and simplify selectors -var CSS = { - alpha: 'alpha-d2270', - black: 'black-3c85d', - board: 'board-b72b1', - chessboard: 'chessboard-63f37', - clearfix: 'clearfix-7da63', - highlight1: 'highlight1-32417', - highlight2: 'highlight2-9c5d2', - notation: 'notation-322f9', - numeric: 'numeric-fc462', - piece: 'piece-417db', - row: 'row-5277c', - sparePieces: 'spare-pieces-7492f', - sparePiecesBottom: 'spare-pieces-bottom-ae20f', - sparePiecesTop: 'spare-pieces-top-4028b', - square: 'square-55d63', - white: 'white-1e1d7' -}; - -//------------------------------------------------------------------------------ -// Module Scope Variables -//------------------------------------------------------------------------------ - -// DOM elements -var containerEl, - boardEl, - draggedPieceEl, - sparePiecesTopEl, - sparePiecesBottomEl; - -// constructor return object -var widget = {}; - -//------------------------------------------------------------------------------ -// Stateful -//------------------------------------------------------------------------------ - -var ANIMATION_HAPPENING = false, - BOARD_BORDER_SIZE = 2, - CURRENT_ORIENTATION = 'white', - CURRENT_POSITION = {}, - SQUARE_SIZE, - DRAGGED_PIECE, - DRAGGED_PIECE_LOCATION, - DRAGGED_PIECE_SOURCE, - DRAGGING_A_PIECE = false, - SPARE_PIECE_ELS_IDS = {}, - SQUARE_ELS_IDS = {}, - SQUARE_ELS_OFFSETS; - -//------------------------------------------------------------------------------ -// JS Util Functions -//------------------------------------------------------------------------------ - -// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript -function createId() { - return 'xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'.replace(/x/g, function(c) { - var r = Math.random() * 16 | 0; - return r.toString(16); - }); -} - -function deepCopy(thing) { - return JSON.parse(JSON.stringify(thing)); -} - -function parseSemVer(version) { - var tmp = version.split('.'); - return { - major: parseInt(tmp[0], 10), - minor: parseInt(tmp[1], 10), - patch: parseInt(tmp[2], 10) - }; -} - -// returns true if version is >= minimum -function compareSemVer(version, minimum) { - version = parseSemVer(version); - minimum = parseSemVer(minimum); - - var versionNum = (version.major * 10000 * 10000) + - (version.minor * 10000) + version.patch; - var minimumNum = (minimum.major * 10000 * 10000) + - (minimum.minor * 10000) + minimum.patch; - - return (versionNum >= minimumNum); -} - -//------------------------------------------------------------------------------ -// Validation / Errors -//------------------------------------------------------------------------------ - -function error(code, msg, obj) { - // do nothing if showErrors is not set - if (cfg.hasOwnProperty('showErrors') !== true || - cfg.showErrors === false) { - return; - } - - var errorText = 'ChessBoard Error ' + code + ': ' + msg; - - // print to console - if (cfg.showErrors === 'console' && - typeof console === 'object' && - typeof console.log === 'function') { - console.log(errorText); - if (arguments.length >= 2) { - console.log(obj); - } - return; - } - - // alert errors - if (cfg.showErrors === 'alert') { - if (obj) { - errorText += '\n\n' + JSON.stringify(obj); - } - window.alert(errorText); - return; - } - - // custom function - if (typeof cfg.showErrors === 'function') { - cfg.showErrors(code, msg, obj); - } -} - -// check dependencies -function checkDeps() { - // if containerId is a string, it must be the ID of a DOM node - if (typeof containerElOrId === 'string') { - // cannot be empty - if (containerElOrId === '') { - window.alert('ChessBoard Error 1001: ' + - 'The first argument to ChessBoard() cannot be an empty string.' + - '\n\nExiting...'); - return false; - } - - // make sure the container element exists in the DOM - var el = document.getElementById(containerElOrId); - if (! el) { - window.alert('ChessBoard Error 1002: Element with id "' + - containerElOrId + '" does not exist in the DOM.' + - '\n\nExiting...'); - return false; - } - - // set the containerEl - containerEl = $(el); - } - - // else it must be something that becomes a jQuery collection - // with size 1 - // ie: a single DOM node or jQuery object - else { - containerEl = $(containerElOrId); - - if (containerEl.length !== 1) { - window.alert('ChessBoard Error 1003: The first argument to ' + - 'ChessBoard() must be an ID or a single DOM node.' + - '\n\nExiting...'); - return false; - } - } - - // JSON must exist - if (! window.JSON || - typeof JSON.stringify !== 'function' || - typeof JSON.parse !== 'function') { - window.alert('ChessBoard Error 1004: JSON does not exist. ' + - 'Please include a JSON polyfill.\n\nExiting...'); - return false; - } - - // check for a compatible version of jQuery - if (! (typeof window.$ && $.fn && $.fn.jquery && - compareSemVer($.fn.jquery, MINIMUM_JQUERY_VERSION) === true)) { - window.alert('ChessBoard Error 1005: Unable to find a valid version ' + - 'of jQuery. Please include jQuery ' + MINIMUM_JQUERY_VERSION + ' or ' + - 'higher on the page.\n\nExiting...'); - return false; - } - - return true; -} - -function validAnimationSpeed(speed) { - if (speed === 'fast' || speed === 'slow') { - return true; - } - - if ((parseInt(speed, 10) + '') !== (speed + '')) { - return false; - } - - return (speed >= 0); -} - -// validate config / set default options -function expandConfig() { - if (typeof cfg === 'string' || validPositionObject(cfg) === true) { - cfg = { - position: cfg - }; - } - - // default for orientation is white - if (cfg.orientation !== 'black') { - cfg.orientation = 'white'; - } - CURRENT_ORIENTATION = cfg.orientation; - - // default for showNotation is true - if (cfg.showNotation !== false) { - cfg.showNotation = true; - } - - // default for draggable is false - if (cfg.draggable !== true) { - cfg.draggable = false; - } - - // default for dropOffBoard is 'snapback' - if (cfg.dropOffBoard !== 'trash') { - cfg.dropOffBoard = 'snapback'; - } - - // default for sparePieces is false - if (cfg.sparePieces !== true) { - cfg.sparePieces = false; - } - - // draggable must be true if sparePieces is enabled - if (cfg.sparePieces === true) { - cfg.draggable = true; - } - - // default piece theme is wikipedia - if (cfg.hasOwnProperty('pieceTheme') !== true || - (typeof cfg.pieceTheme !== 'string' && - typeof cfg.pieceTheme !== 'function')) { - cfg.pieceTheme = 'img/chesspieces/wikipedia/{piece}.png'; - } - - // animation speeds - if (cfg.hasOwnProperty('appearSpeed') !== true || - validAnimationSpeed(cfg.appearSpeed) !== true) { - cfg.appearSpeed = 200; - } - if (cfg.hasOwnProperty('moveSpeed') !== true || - validAnimationSpeed(cfg.moveSpeed) !== true) { - cfg.moveSpeed = 200; - } - if (cfg.hasOwnProperty('snapbackSpeed') !== true || - validAnimationSpeed(cfg.snapbackSpeed) !== true) { - cfg.snapbackSpeed = 50; - } - if (cfg.hasOwnProperty('snapSpeed') !== true || - validAnimationSpeed(cfg.snapSpeed) !== true) { - cfg.snapSpeed = 25; - } - if (cfg.hasOwnProperty('trashSpeed') !== true || - validAnimationSpeed(cfg.trashSpeed) !== true) { - cfg.trashSpeed = 100; - } - - // make sure position is valid - if (cfg.hasOwnProperty('position') === true) { - if (cfg.position === 'start') { - CURRENT_POSITION = deepCopy(START_POSITION); - } - - else if (validFen(cfg.position) === true) { - CURRENT_POSITION = fenToObj(cfg.position); - } - - else if (validPositionObject(cfg.position) === true) { - CURRENT_POSITION = deepCopy(cfg.position); - } - - else { - error(7263, 'Invalid value passed to config.position.', cfg.position); - } - } - - return true; -} - -//------------------------------------------------------------------------------ -// DOM Misc -//------------------------------------------------------------------------------ - -// calculates square size based on the width of the container -// got a little CSS black magic here, so let me explain: -// get the width of the container element (could be anything), reduce by 1 for -// fudge factor, and then keep reducing until we find an exact mod 8 for -// our square size -function calculateSquareSize() { - var containerWidth = parseInt(containerEl.css('width'), 10); - - // defensive, prevent infinite loop - if (! containerWidth || containerWidth <= 0) { - return 0; - } - - // pad one pixel - var boardWidth = containerWidth - 1; - - while (boardWidth % 8 !== 0 && boardWidth > 0) { - boardWidth--; - } - - return (boardWidth / 8); -} - -// create random IDs for elements -function createElIds() { - // squares on the board - for (var i = 0; i < COLUMNS.length; i++) { - for (var j = 1; j <= 8; j++) { - var square = COLUMNS[i] + j; - SQUARE_ELS_IDS[square] = square + '-' + createId(); - } - } - - // spare pieces - var pieces = 'KQRBNP'.split(''); - for (var i = 0; i < pieces.length; i++) { - var whitePiece = 'w' + pieces[i]; - var blackPiece = 'b' + pieces[i]; - SPARE_PIECE_ELS_IDS[whitePiece] = whitePiece + '-' + createId(); - SPARE_PIECE_ELS_IDS[blackPiece] = blackPiece + '-' + createId(); - } -} - -//------------------------------------------------------------------------------ -// Markup Building -//------------------------------------------------------------------------------ - -function buildBoardContainer() { - var html = '
'; - - if (cfg.sparePieces === true) { - html += '
'; - } - - html += '
'; - - if (cfg.sparePieces === true) { - html += '
'; - } - - html += '
'; - - return html; -} - -/* -var buildSquare = function(color, size, id) { - var html = '
'; - - if (cfg.showNotation === true) { - - } - - html += '
'; - - return html; -}; -*/ - -function buildBoard(orientation) { - if (orientation !== 'black') { - orientation = 'white'; - } - - var html = ''; - - // algebraic notation / orientation - var alpha = deepCopy(COLUMNS); - var row = 8; - if (orientation === 'black') { - alpha.reverse(); - row = 1; - } - - var squareColor = 'white'; - for (var i = 0; i < 8; i++) { - html += '
'; - for (var j = 0; j < 8; j++) { - var square = alpha[j] + row; - - html += '
'; - - if (cfg.showNotation === true) { - // alpha notation - if ((orientation === 'white' && row === 1) || - (orientation === 'black' && row === 8)) { - html += '
' + - alpha[j] + '
'; - } - - // numeric notation - if (j === 0) { - html += '
' + - row + '
'; - } - } - - html += '
'; // end .square - - squareColor = (squareColor === 'white' ? 'black' : 'white'); - } - html += '
'; - - squareColor = (squareColor === 'white' ? 'black' : 'white'); - - if (orientation === 'white') { - row--; - } - else { - row++; - } - } - - return html; -} - -function buildPieceImgSrc(piece) { - if (typeof cfg.pieceTheme === 'function') { - return cfg.pieceTheme(piece); - } - - if (typeof cfg.pieceTheme === 'string') { - return cfg.pieceTheme.replace(/{piece}/g, piece); - } - - // NOTE: this should never happen - error(8272, 'Unable to build image source for cfg.pieceTheme.'); - return ''; -} - -function buildPiece(piece, hidden, id) { - var html = ''; - - return html; -} - -function buildSparePieces(color) { - var pieces = ['wK', 'wQ', 'wR', 'wB', 'wN', 'wP']; - if (color === 'black') { - pieces = ['bK', 'bQ', 'bR', 'bB', 'bN', 'bP']; - } - - var html = ''; - for (var i = 0; i < pieces.length; i++) { - html += buildPiece(pieces[i], false, SPARE_PIECE_ELS_IDS[pieces[i]]); - } - - return html; -} - -//------------------------------------------------------------------------------ -// Animations -//------------------------------------------------------------------------------ - -function animateSquareToSquare(src, dest, piece, completeFn) { - // get information about the source and destination squares - var srcSquareEl = $('#' + SQUARE_ELS_IDS[src]); - var srcSquarePosition = srcSquareEl.offset(); - var destSquareEl = $('#' + SQUARE_ELS_IDS[dest]); - var destSquarePosition = destSquareEl.offset(); - - // create the animated piece and absolutely position it - // over the source square - var animatedPieceId = createId(); - $('body').append(buildPiece(piece, true, animatedPieceId)); - var animatedPieceEl = $('#' + animatedPieceId); - animatedPieceEl.css({ - display: '', - position: 'absolute', - top: srcSquarePosition.top, - left: srcSquarePosition.left - }); - - // remove original piece from source square - srcSquareEl.find('.' + CSS.piece).remove(); - - // on complete - var complete = function() { - // add the "real" piece to the destination square - destSquareEl.append(buildPiece(piece)); - - // remove the animated piece - animatedPieceEl.remove(); - - // run complete function - if (typeof completeFn === 'function') { - completeFn(); - } - }; - - // animate the piece to the destination square - var opts = { - duration: cfg.moveSpeed, - complete: complete - }; - animatedPieceEl.animate(destSquarePosition, opts); -} - -function animateSparePieceToSquare(piece, dest, completeFn) { - var srcOffset = $('#' + SPARE_PIECE_ELS_IDS[piece]).offset(); - var destSquareEl = $('#' + SQUARE_ELS_IDS[dest]); - var destOffset = destSquareEl.offset(); - - // create the animate piece - var pieceId = createId(); - $('body').append(buildPiece(piece, true, pieceId)); - var animatedPieceEl = $('#' + pieceId); - animatedPieceEl.css({ - display: '', - position: 'absolute', - left: srcOffset.left, - top: srcOffset.top - }); - - // on complete - var complete = function() { - // add the "real" piece to the destination square - destSquareEl.find('.' + CSS.piece).remove(); - destSquareEl.append(buildPiece(piece)); - - // remove the animated piece - animatedPieceEl.remove(); - - // run complete function - if (typeof completeFn === 'function') { - completeFn(); - } - }; - - // animate the piece to the destination square - var opts = { - duration: cfg.moveSpeed, - complete: complete - }; - animatedPieceEl.animate(destOffset, opts); -} - -// execute an array of animations -function doAnimations(a, oldPos, newPos) { - ANIMATION_HAPPENING = true; - - var numFinished = 0; - function onFinish() { - numFinished++; - - // exit if all the animations aren't finished - if (numFinished !== a.length) return; - - drawPositionInstant(); - ANIMATION_HAPPENING = false; - - // run their onMoveEnd function - if (cfg.hasOwnProperty('onMoveEnd') === true && - typeof cfg.onMoveEnd === 'function') { - cfg.onMoveEnd(deepCopy(oldPos), deepCopy(newPos)); - } - } - - for (var i = 0; i < a.length; i++) { - // clear a piece - if (a[i].type === 'clear') { - $('#' + SQUARE_ELS_IDS[a[i].square] + ' .' + CSS.piece) - .fadeOut(cfg.trashSpeed, onFinish); - } - - // add a piece (no spare pieces) - if (a[i].type === 'add' && cfg.sparePieces !== true) { - $('#' + SQUARE_ELS_IDS[a[i].square]) - .append(buildPiece(a[i].piece, true)) - .find('.' + CSS.piece) - .fadeIn(cfg.appearSpeed, onFinish); - } - - // add a piece from a spare piece - if (a[i].type === 'add' && cfg.sparePieces === true) { - animateSparePieceToSquare(a[i].piece, a[i].square, onFinish); - } - - // move a piece - if (a[i].type === 'move') { - animateSquareToSquare(a[i].source, a[i].destination, a[i].piece, - onFinish); - } - } -} - -// returns the distance between two squares -function squareDistance(s1, s2) { - s1 = s1.split(''); - var s1x = COLUMNS.indexOf(s1[0]) + 1; - var s1y = parseInt(s1[1], 10); - - s2 = s2.split(''); - var s2x = COLUMNS.indexOf(s2[0]) + 1; - var s2y = parseInt(s2[1], 10); - - var xDelta = Math.abs(s1x - s2x); - var yDelta = Math.abs(s1y - s2y); - - if (xDelta >= yDelta) return xDelta; - return yDelta; -} - -// returns an array of closest squares from square -function createRadius(square) { - var squares = []; - - // calculate distance of all squares - for (var i = 0; i < 8; i++) { - for (var j = 0; j < 8; j++) { - var s = COLUMNS[i] + (j + 1); - - // skip the square we're starting from - if (square === s) continue; - - squares.push({ - square: s, - distance: squareDistance(square, s) - }); - } - } - - // sort by distance - squares.sort(function(a, b) { - return a.distance - b.distance; - }); - - // just return the square code - var squares2 = []; - for (var i = 0; i < squares.length; i++) { - squares2.push(squares[i].square); - } - - return squares2; -} - -// returns the square of the closest instance of piece -// returns false if no instance of piece is found in position -function findClosestPiece(position, piece, square) { - // create array of closest squares from square - var closestSquares = createRadius(square); - - // search through the position in order of distance for the piece - for (var i = 0; i < closestSquares.length; i++) { - var s = closestSquares[i]; - - if (position.hasOwnProperty(s) === true && position[s] === piece) { - return s; - } - } - - return false; -} - -// calculate an array of animations that need to happen in order to get -// from pos1 to pos2 -function calculateAnimations(pos1, pos2) { - // make copies of both - pos1 = deepCopy(pos1); - pos2 = deepCopy(pos2); - - var animations = []; - var squaresMovedTo = {}; - - // remove pieces that are the same in both positions - for (var i in pos2) { - if (pos2.hasOwnProperty(i) !== true) continue; - - if (pos1.hasOwnProperty(i) === true && pos1[i] === pos2[i]) { - delete pos1[i]; - delete pos2[i]; - } - } - - // find all the "move" animations - for (var i in pos2) { - if (pos2.hasOwnProperty(i) !== true) continue; - - var closestPiece = findClosestPiece(pos1, pos2[i], i); - if (closestPiece !== false) { - animations.push({ - type: 'move', - source: closestPiece, - destination: i, - piece: pos2[i] - }); - - delete pos1[closestPiece]; - delete pos2[i]; - squaresMovedTo[i] = true; - } - } - - // add pieces to pos2 - for (var i in pos2) { - if (pos2.hasOwnProperty(i) !== true) continue; - - animations.push({ - type: 'add', - square: i, - piece: pos2[i] - }) - - delete pos2[i]; - } - - // clear pieces from pos1 - for (var i in pos1) { - if (pos1.hasOwnProperty(i) !== true) continue; - - // do not clear a piece if it is on a square that is the result - // of a "move", ie: a piece capture - if (squaresMovedTo.hasOwnProperty(i) === true) continue; - - animations.push({ - type: 'clear', - square: i, - piece: pos1[i] - }); - - delete pos1[i]; - } - - return animations; -} - -//------------------------------------------------------------------------------ -// Control Flow -//------------------------------------------------------------------------------ - -function drawPositionInstant() { - // clear the board - boardEl.find('.' + CSS.piece).remove(); - - // add the pieces - for (var i in CURRENT_POSITION) { - if (CURRENT_POSITION.hasOwnProperty(i) !== true) continue; - - $('#' + SQUARE_ELS_IDS[i]).append(buildPiece(CURRENT_POSITION[i])); - } -} - -function drawBoard() { - boardEl.html(buildBoard(CURRENT_ORIENTATION)); - drawPositionInstant(); - - if (cfg.sparePieces === true) { - if (CURRENT_ORIENTATION === 'white') { - sparePiecesTopEl.html(buildSparePieces('black')); - sparePiecesBottomEl.html(buildSparePieces('white')); - } - else { - sparePiecesTopEl.html(buildSparePieces('white')); - sparePiecesBottomEl.html(buildSparePieces('black')); - } - } -} - -// given a position and a set of moves, return a new position -// with the moves executed -function calculatePositionFromMoves(position, moves) { - position = deepCopy(position); - - for (var i in moves) { - if (moves.hasOwnProperty(i) !== true) continue; - - // skip the move if the position doesn't have a piece on the source square - if (position.hasOwnProperty(i) !== true) continue; - - var piece = position[i]; - delete position[i]; - position[moves[i]] = piece; - } - - return position; -} - -function setCurrentPosition(position) { - var oldPos = deepCopy(CURRENT_POSITION); - var newPos = deepCopy(position); - var oldFen = objToFen(oldPos); - var newFen = objToFen(newPos); - - // do nothing if no change in position - if (oldFen === newFen) return; - - // run their onChange function - if (cfg.hasOwnProperty('onChange') === true && - typeof cfg.onChange === 'function') { - cfg.onChange(oldPos, newPos); - } - - // update state - CURRENT_POSITION = position; -} - -function isXYOnSquare(x, y) { - for (var i in SQUARE_ELS_OFFSETS) { - if (SQUARE_ELS_OFFSETS.hasOwnProperty(i) !== true) continue; - - var s = SQUARE_ELS_OFFSETS[i]; - if (x >= s.left && x < s.left + SQUARE_SIZE && - y >= s.top && y < s.top + SQUARE_SIZE) { - return i; - } - } - - return 'offboard'; -} - -// records the XY coords of every square into memory -function captureSquareOffsets() { - SQUARE_ELS_OFFSETS = {}; - - for (var i in SQUARE_ELS_IDS) { - if (SQUARE_ELS_IDS.hasOwnProperty(i) !== true) continue; - - SQUARE_ELS_OFFSETS[i] = $('#' + SQUARE_ELS_IDS[i]).offset(); - } -} - -function removeSquareHighlights() { - boardEl.find('.' + CSS.square) - .removeClass(CSS.highlight1 + ' ' + CSS.highlight2); -} - -function snapbackDraggedPiece() { - // there is no "snapback" for spare pieces - if (DRAGGED_PIECE_SOURCE === 'spare') { - trashDraggedPiece(); - return; - } - - removeSquareHighlights(); - - // animation complete - function complete() { - drawPositionInstant(); - draggedPieceEl.css('display', 'none'); - - // run their onSnapbackEnd function - if (cfg.hasOwnProperty('onSnapbackEnd') === true && - typeof cfg.onSnapbackEnd === 'function') { - cfg.onSnapbackEnd(DRAGGED_PIECE, DRAGGED_PIECE_SOURCE, - deepCopy(CURRENT_POSITION), CURRENT_ORIENTATION); - } - } - - // get source square position - var sourceSquarePosition = - $('#' + SQUARE_ELS_IDS[DRAGGED_PIECE_SOURCE]).offset(); - - // animate the piece to the target square - var opts = { - duration: cfg.snapbackSpeed, - complete: complete - }; - draggedPieceEl.animate(sourceSquarePosition, opts); - - // set state - DRAGGING_A_PIECE = false; -} - -function trashDraggedPiece() { - removeSquareHighlights(); - - // remove the source piece - var newPosition = deepCopy(CURRENT_POSITION); - delete newPosition[DRAGGED_PIECE_SOURCE]; - setCurrentPosition(newPosition); - - // redraw the position - drawPositionInstant(); - - // hide the dragged piece - draggedPieceEl.fadeOut(cfg.trashSpeed); - - // set state - DRAGGING_A_PIECE = false; -} - -function dropDraggedPieceOnSquare(square) { - removeSquareHighlights(); - - // update position - var newPosition = deepCopy(CURRENT_POSITION); - delete newPosition[DRAGGED_PIECE_SOURCE]; - newPosition[square] = DRAGGED_PIECE; - setCurrentPosition(newPosition); - - // get target square information - var targetSquarePosition = $('#' + SQUARE_ELS_IDS[square]).offset(); - - // animation complete - var complete = function() { - drawPositionInstant(); - draggedPieceEl.css('display', 'none'); - - // execute their onSnapEnd function - if (cfg.hasOwnProperty('onSnapEnd') === true && - typeof cfg.onSnapEnd === 'function') { - cfg.onSnapEnd(DRAGGED_PIECE_SOURCE, square, DRAGGED_PIECE); - } - }; - - // snap the piece to the target square - var opts = { - duration: cfg.snapSpeed, - complete: complete - }; - draggedPieceEl.animate(targetSquarePosition, opts); - - // set state - DRAGGING_A_PIECE = false; -} - -function beginDraggingPiece(source, piece, x, y) { - // run their custom onDragStart function - // their custom onDragStart function can cancel drag start - if (typeof cfg.onDragStart === 'function' && - cfg.onDragStart(source, piece, - deepCopy(CURRENT_POSITION), CURRENT_ORIENTATION) === false) { - return; - } - - // set state - DRAGGING_A_PIECE = true; - DRAGGED_PIECE = piece; - DRAGGED_PIECE_SOURCE = source; - - // if the piece came from spare pieces, location is offboard - if (source === 'spare') { - DRAGGED_PIECE_LOCATION = 'offboard'; - } - else { - DRAGGED_PIECE_LOCATION = source; - } - - // capture the x, y coords of all squares in memory - captureSquareOffsets(); - - // create the dragged piece - draggedPieceEl.attr('src', buildPieceImgSrc(piece)) - .css({ - display: '', - position: 'absolute', - left: x - (SQUARE_SIZE / 2), - top: y - (SQUARE_SIZE / 2) - }); - - if (source !== 'spare') { - // highlight the source square and hide the piece - $('#' + SQUARE_ELS_IDS[source]).addClass(CSS.highlight1) - .find('.' + CSS.piece).css('display', 'none'); - } -} - -function updateDraggedPiece(x, y) { - // put the dragged piece over the mouse cursor - draggedPieceEl.css({ - left: x - (SQUARE_SIZE / 2), - top: y - (SQUARE_SIZE / 2) - }); - - // get location - var location = isXYOnSquare(x, y); - - // do nothing if the location has not changed - if (location === DRAGGED_PIECE_LOCATION) return; - - // remove highlight from previous square - if (validSquare(DRAGGED_PIECE_LOCATION) === true) { - $('#' + SQUARE_ELS_IDS[DRAGGED_PIECE_LOCATION]) - .removeClass(CSS.highlight2); - } - - // add highlight to new square - if (validSquare(location) === true) { - $('#' + SQUARE_ELS_IDS[location]).addClass(CSS.highlight2); - } - - // run onDragMove - if (typeof cfg.onDragMove === 'function') { - cfg.onDragMove(location, DRAGGED_PIECE_LOCATION, - DRAGGED_PIECE_SOURCE, DRAGGED_PIECE, - deepCopy(CURRENT_POSITION), CURRENT_ORIENTATION); - } - - // update state - DRAGGED_PIECE_LOCATION = location; -} - -function stopDraggedPiece(location) { - // determine what the action should be - var action = 'drop'; - if (location === 'offboard' && cfg.dropOffBoard === 'snapback') { - action = 'snapback'; - } - if (location === 'offboard' && cfg.dropOffBoard === 'trash') { - action = 'trash'; - } - - // run their onDrop function, which can potentially change the drop action - if (cfg.hasOwnProperty('onDrop') === true && - typeof cfg.onDrop === 'function') { - var newPosition = deepCopy(CURRENT_POSITION); - - // source piece is a spare piece and position is off the board - //if (DRAGGED_PIECE_SOURCE === 'spare' && location === 'offboard') {...} - // position has not changed; do nothing - - // source piece is a spare piece and position is on the board - if (DRAGGED_PIECE_SOURCE === 'spare' && validSquare(location) === true) { - // add the piece to the board - newPosition[location] = DRAGGED_PIECE; - } - - // source piece was on the board and position is off the board - if (validSquare(DRAGGED_PIECE_SOURCE) === true && location === 'offboard') { - // remove the piece from the board - delete newPosition[DRAGGED_PIECE_SOURCE]; - } - - // source piece was on the board and position is on the board - if (validSquare(DRAGGED_PIECE_SOURCE) === true && - validSquare(location) === true) { - // move the piece - delete newPosition[DRAGGED_PIECE_SOURCE]; - newPosition[location] = DRAGGED_PIECE; - } - - var oldPosition = deepCopy(CURRENT_POSITION); - - var result = cfg.onDrop(DRAGGED_PIECE_SOURCE, location, DRAGGED_PIECE, - newPosition, oldPosition, CURRENT_ORIENTATION); - if (result === 'snapback' || result === 'trash') { - action = result; - } - } - - // do it! - if (action === 'snapback') { - snapbackDraggedPiece(); - } - else if (action === 'trash') { - trashDraggedPiece(); - } - else if (action === 'drop') { - dropDraggedPieceOnSquare(location); - } -} - -//------------------------------------------------------------------------------ -// Public Methods -//------------------------------------------------------------------------------ - -// clear the board -widget.clear = function(useAnimation) { - widget.position({}, useAnimation); -}; - -/* -// get or set config properties -// TODO: write this, GitHub Issue #1 -widget.config = function(arg1, arg2) { - // get the current config - if (arguments.length === 0) { - return deepCopy(cfg); - } -}; -*/ - -// remove the widget from the page -widget.destroy = function() { - // remove markup - containerEl.html(''); - draggedPieceEl.remove(); - - // remove event handlers - containerEl.unbind(); -}; - -// shorthand method to get the current FEN -widget.fen = function() { - return widget.position('fen'); -}; - -// flip orientation -widget.flip = function() { - widget.orientation('flip'); -}; - -/* -// TODO: write this, GitHub Issue #5 -widget.highlight = function() { - -}; -*/ - -// move pieces -widget.move = function() { - // no need to throw an error here; just do nothing - if (arguments.length === 0) return; - - var useAnimation = true; - - // collect the moves into an object - var moves = {}; - for (var i = 0; i < arguments.length; i++) { - // any "false" to this function means no animations - if (arguments[i] === false) { - useAnimation = false; - continue; - } - - // skip invalid arguments - if (validMove(arguments[i]) !== true) { - error(2826, 'Invalid move passed to the move method.', arguments[i]); - continue; - } - - var tmp = arguments[i].split('-'); - moves[tmp[0]] = tmp[1]; - } - - // calculate position from moves - var newPos = calculatePositionFromMoves(CURRENT_POSITION, moves); - - // update the board - widget.position(newPos, useAnimation); - - // return the new position object - return newPos; -}; - -widget.orientation = function(arg) { - // no arguments, return the current orientation - if (arguments.length === 0) { - return CURRENT_ORIENTATION; - } - - // set to white or black - if (arg === 'white' || arg === 'black') { - CURRENT_ORIENTATION = arg; - drawBoard(); - return; - } - - // flip orientation - if (arg === 'flip') { - CURRENT_ORIENTATION = (CURRENT_ORIENTATION === 'white') ? 'black' : 'white'; - drawBoard(); - return; - } - - error(5482, 'Invalid value passed to the orientation method.', arg); -}; - -widget.position = function(position, useAnimation) { - // no arguments, return the current position - if (arguments.length === 0) { - return deepCopy(CURRENT_POSITION); - } - - // get position as FEN - if (typeof position === 'string' && position.toLowerCase() === 'fen') { - return objToFen(CURRENT_POSITION); - } - - // default for useAnimations is true - if (useAnimation !== false) { - useAnimation = true; - } - - // start position - if (typeof position === 'string' && position.toLowerCase() === 'start') { - position = deepCopy(START_POSITION); - } - - // convert FEN to position object - if (validFen(position) === true) { - position = fenToObj(position); - } - - // validate position object - if (validPositionObject(position) !== true) { - error(6482, 'Invalid value passed to the position method.', position); - return; - } - - if (useAnimation === true) { - // start the animations - doAnimations(calculateAnimations(CURRENT_POSITION, position), - CURRENT_POSITION, position); - - // set the new position - setCurrentPosition(position); - } - // instant update - else { - setCurrentPosition(position); - drawPositionInstant(); - } -}; - -widget.resize = function() { - // calulate the new square size - SQUARE_SIZE = calculateSquareSize(); - - // set board width - boardEl.css('width', (SQUARE_SIZE * 8) + 'px'); - - // set drag piece size - draggedPieceEl.css({ - height: SQUARE_SIZE, - width: SQUARE_SIZE - }); - - // spare pieces - if (cfg.sparePieces === true) { - containerEl.find('.' + CSS.sparePieces) - .css('paddingLeft', (SQUARE_SIZE + BOARD_BORDER_SIZE) + 'px'); - } - - // redraw the board - drawBoard(); -}; - -// set the starting position -widget.start = function(useAnimation) { - widget.position('start', useAnimation); -}; - -//------------------------------------------------------------------------------ -// Browser Events -//------------------------------------------------------------------------------ - -function isTouchDevice() { - return ('ontouchstart' in document.documentElement); -} - -// reference: http://www.quirksmode.org/js/detect.html -function isMSIE() { - return (navigator && navigator.userAgent && - navigator.userAgent.search(/MSIE/) !== -1); -} - -function stopDefault(e) { - e.preventDefault(); -} - -function mousedownSquare(e) { - // do nothing if we're not draggable - if (cfg.draggable !== true) return; - - var square = $(this).attr('data-square'); - - // no piece on this square - if (validSquare(square) !== true || - CURRENT_POSITION.hasOwnProperty(square) !== true) { - return; - } - - beginDraggingPiece(square, CURRENT_POSITION[square], e.pageX, e.pageY); -} - -function touchstartSquare(e) { - // do nothing if we're not draggable - if (cfg.draggable !== true) return; - - var square = $(this).attr('data-square'); - - // no piece on this square - if (validSquare(square) !== true || - CURRENT_POSITION.hasOwnProperty(square) !== true) { - return; - } - - e = e.originalEvent; - beginDraggingPiece(square, CURRENT_POSITION[square], - e.changedTouches[0].pageX, e.changedTouches[0].pageY); -} - -function mousedownSparePiece(e) { - // do nothing if sparePieces is not enabled - if (cfg.sparePieces !== true) return; - - var piece = $(this).attr('data-piece'); - - beginDraggingPiece('spare', piece, e.pageX, e.pageY); -} - -function touchstartSparePiece(e) { - // do nothing if sparePieces is not enabled - if (cfg.sparePieces !== true) return; - - var piece = $(this).attr('data-piece'); - - e = e.originalEvent; - beginDraggingPiece('spare', piece, - e.changedTouches[0].pageX, e.changedTouches[0].pageY); -} - -function mousemoveWindow(e) { - // do nothing if we are not dragging a piece - if (DRAGGING_A_PIECE !== true) return; - - updateDraggedPiece(e.pageX, e.pageY); -} - -function touchmoveWindow(e) { - // do nothing if we are not dragging a piece - if (DRAGGING_A_PIECE !== true) return; - - // prevent screen from scrolling - e.preventDefault(); - - updateDraggedPiece(e.originalEvent.changedTouches[0].pageX, - e.originalEvent.changedTouches[0].pageY); -} - -function mouseupWindow(e) { - // do nothing if we are not dragging a piece - if (DRAGGING_A_PIECE !== true) return; - - // get the location - var location = isXYOnSquare(e.pageX, e.pageY); - - stopDraggedPiece(location); -} - -function touchendWindow(e) { - // do nothing if we are not dragging a piece - if (DRAGGING_A_PIECE !== true) return; - - // get the location - var location = isXYOnSquare(e.originalEvent.changedTouches[0].pageX, - e.originalEvent.changedTouches[0].pageY); - - stopDraggedPiece(location); -} - -function mouseenterSquare(e) { - // do not fire this event if we are dragging a piece - // NOTE: this should never happen, but it's a safeguard - if (DRAGGING_A_PIECE !== false) return; - - if (cfg.hasOwnProperty('onMouseoverSquare') !== true || - typeof cfg.onMouseoverSquare !== 'function') return; - - // get the square - var square = $(e.currentTarget).attr('data-square'); - - // NOTE: this should never happen; defensive - if (validSquare(square) !== true) return; - - // get the piece on this square - var piece = false; - if (CURRENT_POSITION.hasOwnProperty(square) === true) { - piece = CURRENT_POSITION[square]; - } - - // execute their function - cfg.onMouseoverSquare(square, piece, deepCopy(CURRENT_POSITION), - CURRENT_ORIENTATION); -} - -function mouseleaveSquare(e) { - // do not fire this event if we are dragging a piece - // NOTE: this should never happen, but it's a safeguard - if (DRAGGING_A_PIECE !== false) return; - - if (cfg.hasOwnProperty('onMouseoutSquare') !== true || - typeof cfg.onMouseoutSquare !== 'function') return; - - // get the square - var square = $(e.currentTarget).attr('data-square'); - - // NOTE: this should never happen; defensive - if (validSquare(square) !== true) return; - - // get the piece on this square - var piece = false; - if (CURRENT_POSITION.hasOwnProperty(square) === true) { - piece = CURRENT_POSITION[square]; - } - - // execute their function - cfg.onMouseoutSquare(square, piece, deepCopy(CURRENT_POSITION), - CURRENT_ORIENTATION); -} - -//------------------------------------------------------------------------------ -// Initialization -//------------------------------------------------------------------------------ - -function addEvents() { - // prevent browser "image drag" - $('body').on('mousedown mousemove', '.' + CSS.piece, stopDefault); - - // mouse drag pieces - boardEl.on('mousedown', '.' + CSS.square, mousedownSquare); - containerEl.on('mousedown', '.' + CSS.sparePieces + ' .' + CSS.piece, - mousedownSparePiece); - - // mouse enter / leave square - boardEl.on('mouseenter', '.' + CSS.square, mouseenterSquare); - boardEl.on('mouseleave', '.' + CSS.square, mouseleaveSquare); - - // IE doesn't like the events on the window object, but other browsers - // perform better that way - if (isMSIE() === true) { - // IE-specific prevent browser "image drag" - document.ondragstart = function() { return false; }; - - $('body').on('mousemove', mousemoveWindow); - $('body').on('mouseup', mouseupWindow); - } - else { - $(window).on('mousemove', mousemoveWindow); - $(window).on('mouseup', mouseupWindow); - } - - // touch drag pieces - if (isTouchDevice() === true) { - boardEl.on('touchstart', '.' + CSS.square, touchstartSquare); - containerEl.on('touchstart', '.' + CSS.sparePieces + ' .' + CSS.piece, - touchstartSparePiece); - $(window).on('touchmove', touchmoveWindow); - $(window).on('touchend', touchendWindow); - } -} - -function initDom() { - // build board and save it in memory - containerEl.html(buildBoardContainer()); - boardEl = containerEl.find('.' + CSS.board); - - if (cfg.sparePieces === true) { - sparePiecesTopEl = containerEl.find('.' + CSS.sparePiecesTop); - sparePiecesBottomEl = containerEl.find('.' + CSS.sparePiecesBottom); - } - - // create the drag piece - var draggedPieceId = createId(); - $('body').append(buildPiece('wP', true, draggedPieceId)); - draggedPieceEl = $('#' + draggedPieceId); - - // get the border size - BOARD_BORDER_SIZE = parseInt(boardEl.css('borderLeftWidth'), 10); - - // set the size and draw the board - widget.resize(); -} - -function init() { - if (checkDeps() !== true || - expandConfig() !== true) return; - - // create unique IDs for all the elements we will create - createElIds(); - - initDom(); - addEvents(); -} - -// go time -init(); - -// return the widget object -return widget; - -}; // end window.ChessBoard - -// expose util functions -window.ChessBoard.fenToObj = fenToObj; -window.ChessBoard.objToFen = objToFen; - -})(); // end anonymous wrapper diff --git a/experiments/chess/assets/chessboardjs/js/chessboard-0.3.0.min.js b/experiments/chess/assets/chessboardjs/js/chessboard-0.3.0.min.js deleted file mode 100644 index 81a29a1a..00000000 --- a/experiments/chess/assets/chessboardjs/js/chessboard-0.3.0.min.js +++ /dev/null @@ -1,31 +0,0 @@ -/*! chessboard.js v0.3.0 | (c) 2013 Chris Oakman | MIT License chessboardjs.com/license */ -(function(){function l(f){return"string"!==typeof f?!1:-1!==f.search(/^[a-h][1-8]$/)}function Q(f){if("string"!==typeof f)return!1;f=f.replace(/ .+$/,"");f=f.split("/");if(8!==f.length)return!1;for(var b=0;8>b;b++)if(""===f[b]||8m;m++){for(var l=f[m].split(""),r=0,w=0;wm;m++){for(var l=0;8>l;l++){var r=B[l]+n;!0===f.hasOwnProperty(r)?(r=f[r].split(""),r="w"===r[0]?r[1].toUpperCase(): -r[1].toLowerCase(),b+=r):b+="1"}7!==m&&(b+="/");n--}b=b.replace(/11111111/g,"8");b=b.replace(/1111111/g,"7");b=b.replace(/111111/g,"6");b=b.replace(/11111/g,"5");b=b.replace(/1111/g,"4");b=b.replace(/111/g,"3");return b=b.replace(/11/g,"2")}var B="abcdefgh".split("");window.ChessBoard=window.ChessBoard||function(f,b){function n(){return"xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx".replace(/x/g,function(a){return(16*Math.random()|0).toString(16)})}function m(a){return JSON.parse(JSON.stringify(a))}function X(a){a= -a.split(".");return{major:parseInt(a[0],10),minor:parseInt(a[1],10),patch:parseInt(a[2],10)}}function r(a,e,c){if(!0===b.hasOwnProperty("showErrors")&&!1!==b.showErrors){var d="ChessBoard Error "+a+": "+e;"console"===b.showErrors&&"object"===typeof console&&"function"===typeof console.log?(console.log(d),2<=arguments.length&&console.log(c)):"alert"===b.showErrors?(c&&(d+="\n\n"+JSON.stringify(c)),window.alert(d)):"function"===typeof b.showErrors&&b.showErrors(a,e,c)}}function w(a){return"fast"=== -a||"slow"===a?!0:parseInt(a,10)+""!==a+""?!1:0<=a}function I(){for(var a=0;a=b;b++){var c=B[a]+b;s[c]=c+"-"+n()}b="KQRBNP".split("");for(a=0;a';!0===b.sparePieces&&(a+='
');a+='
';!0===b.sparePieces&&(a+='
'); -return a+"
"}function A(a){"black"!==a&&(a="white");var e="",c=m(B),d=8;"black"===a&&(c.reverse(),d=1);for(var C="white",f=0;8>f;f++){for(var e=e+('
'),k=0;8>k;k++){var g=c[k]+d,e=e+('
');if(!0===b.showNotation){if("white"===a&&1===d||"black"===a&&8===d)e+='
'+c[k]+"
";0===k&&(e+='
'+d+"
")}e+="
";C="white"===C?"black":"white"}e+='
';C="white"===C?"black":"white";"white"===a?d--:d++}return e}function Y(a){if("function"===typeof b.pieceTheme)return b.pieceTheme(a);if("string"===typeof b.pieceTheme)return b.pieceTheme.replace(/{piece}/g,a);r(8272,"Unable to build image source for cfg.pieceTheme.");return""}function D(a,b,c){var d=''}function N(a){var b="wK wQ wR wB wN wP".split(" ");"black"===a&&(b="bK bQ bR bB bN bP".split(" "));a="";for(var c=0;c=d?c:d}function la(a){for(var b=[],c=0;8>c;c++)for(var d=0;8>d;d++){var g=B[c]+(d+1);a!==g&&b.push({square:g,distance:ka(a,g)})}b.sort(function(a,b){return a.distance-b.distance});a=[];for(c=0;c=d.left&&a=d.top&&b=a)p=0;else{for(a-=1;0!==a%8&&0=1E8*b.major+1E4*b.minor+b.patch;return a?!0:(window.alert("ChessBoard Error 1005: Unable to find a valid version of jQuery. Please include jQuery 1.7.0 or higher on the page.\n\nExiting..."), -!1)}()){if("string"===typeof b||!0===F(b))b={position:b};"black"!==b.orientation&&(b.orientation="white");u=b.orientation;!1!==b.showNotation&&(b.showNotation=!0);!0!==b.draggable&&(b.draggable=!1);"trash"!==b.dropOffBoard&&(b.dropOffBoard="snapback");!0!==b.sparePieces&&(b.sparePieces=!1);!0===b.sparePieces&&(b.draggable=!0);if(!0!==b.hasOwnProperty("pieceTheme")||"string"!==typeof b.pieceTheme&&"function"!==typeof b.pieceTheme)b.pieceTheme="img/chesspieces/wikipedia/{piece}.png";if(!0!==b.hasOwnProperty("appearSpeed")|| -!0!==w(b.appearSpeed))b.appearSpeed=200;if(!0!==b.hasOwnProperty("moveSpeed")||!0!==w(b.moveSpeed))b.moveSpeed=200;if(!0!==b.hasOwnProperty("snapbackSpeed")||!0!==w(b.snapbackSpeed))b.snapbackSpeed=50;if(!0!==b.hasOwnProperty("snapSpeed")||!0!==w(b.snapSpeed))b.snapSpeed=25;if(!0!==b.hasOwnProperty("trashSpeed")||!0!==w(b.trashSpeed))b.trashSpeed=100;!0===b.hasOwnProperty("position")&&("start"===b.position?g=m(fa):!0===Q(b.position)?g=K(b.position):!0===F(b.position)?g=m(b.position):r(7263,"Invalid value passed to config.position.", -b.position));W=!0}W&&(I(),ya(),xa());return q};window.ChessBoard.fenToObj=K;window.ChessBoard.objToFen=L})(); \ No newline at end of file diff --git a/experiments/chess/assets/js/Board.js b/experiments/chess/assets/js/Board.js deleted file mode 100644 index b9ab7253..00000000 --- a/experiments/chess/assets/js/Board.js +++ /dev/null @@ -1,24 +0,0 @@ -function Board(id, config){ - this.board = new ChessBoard(id,config); - - console.log(this.board) - this.render = function({ - state, - done, - action, - turn - }){ - var fen = state.split(" ")[0]; - if(this.board.fen().valueOf() == fen.valueOf()) - this.board.position(fen, true); - - var ele = $$("." + (turn=="b"?"comp":"human")); - highlight(ele, $$(".options")) - - if(done){ - show($$(".overlay #gameOver")) - }else{ - hide($$(".overlay #gameOver")) - } - } -} \ No newline at end of file diff --git a/experiments/chess/assets/js/Env.js b/experiments/chess/assets/js/Env.js deleted file mode 100644 index d31a8662..00000000 --- a/experiments/chess/assets/js/Env.js +++ /dev/null @@ -1,25 +0,0 @@ -function Env(){ - this.chess = new Chess(); - var action = null; - - this.done = function(){ - return this.chess.game_over(); - } - - this.step = function(a){ - action = a; - return this.chess.move(a); - } - - this.state = function(){ - return this.chess.fen(); - } - - this.config = function(){ - return {state: this.state(), done: this.done(), action, turn: this.chess.turn()}; - } - - this.reset = function(){ - return chess.reset(); - } -} \ No newline at end of file diff --git a/experiments/chess/assets/js/extenstions.js b/experiments/chess/assets/js/extenstions.js deleted file mode 100644 index e128e79d..00000000 --- a/experiments/chess/assets/js/extenstions.js +++ /dev/null @@ -1,22 +0,0 @@ -Game.prototype.isValidAction = function(action){ - // computer -> black piece - // human -> white piece - var nextColor = this.env.chess.turn() - var color = action.peice[0]; - if((color != nextColor) - // || (this.state == this.states.C && color == "w") || (this.state == this.states.H && action.peice[0] == "b") - ){ - return false; - } - - var res = this.env.chess.move(action); - if(res)this.env.chess.undo(); - - return res != null; -} - -Game.prototype.nextGameState = function(curr) { - // return (curr + 1)%2; - return curr -}; - diff --git a/experiments/chess/assets/js/script.js b/experiments/chess/assets/js/script.js deleted file mode 100644 index 2c70634f..00000000 --- a/experiments/chess/assets/js/script.js +++ /dev/null @@ -1,28 +0,0 @@ -var __init__ = function(){ - var start = "", end = "", env = new Env(); - - var board_config = { - draggable: true, - dropOffBoard: 'snapback', // this is the default - position: 'start', - onDragStart: dragStart, - onDrop: drop - } - var board = new Board("playground", board_config); - var game = new Game(env, board, null, {mode:"async"}); - - function dragStart(source, peice, state, orientation){ - // if(peice[0] == "b")return false; // user can't move black peices - } - - function drop(source, target, peice, newPos, oldPos, orientation){ - if(source == target)return; // no action - if(!game.action({from: source, to: target, nextState: ChessBoard.objToFen(newPos), peice})){ - return 'snapback'; - } - - return true; - } -} - -__init__() \ No newline at end of file diff --git a/experiments/chess/img/chesspieces/wikipedia/bB.png b/experiments/chess/img/chesspieces/wikipedia/bB.png deleted file mode 100644 index 42b1e747..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/bB.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/bK.png b/experiments/chess/img/chesspieces/wikipedia/bK.png deleted file mode 100644 index 0aad81e5..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/bK.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/bN.png b/experiments/chess/img/chesspieces/wikipedia/bN.png deleted file mode 100644 index 2eee2e21..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/bN.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/bP.png b/experiments/chess/img/chesspieces/wikipedia/bP.png deleted file mode 100644 index afa0c9d4..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/bP.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/bQ.png b/experiments/chess/img/chesspieces/wikipedia/bQ.png deleted file mode 100644 index c6810d85..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/bQ.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/bR.png b/experiments/chess/img/chesspieces/wikipedia/bR.png deleted file mode 100644 index c7eb127a..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/bR.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/wB.png b/experiments/chess/img/chesspieces/wikipedia/wB.png deleted file mode 100644 index bdee3d05..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/wB.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/wK.png b/experiments/chess/img/chesspieces/wikipedia/wK.png deleted file mode 100644 index a475d80b..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/wK.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/wN.png b/experiments/chess/img/chesspieces/wikipedia/wN.png deleted file mode 100644 index f1d1ce9e..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/wN.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/wP.png b/experiments/chess/img/chesspieces/wikipedia/wP.png deleted file mode 100644 index a83a3004..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/wP.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/wQ.png b/experiments/chess/img/chesspieces/wikipedia/wQ.png deleted file mode 100644 index e7960684..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/wQ.png and /dev/null differ diff --git a/experiments/chess/img/chesspieces/wikipedia/wR.png b/experiments/chess/img/chesspieces/wikipedia/wR.png deleted file mode 100644 index c4d6fb01..00000000 Binary files a/experiments/chess/img/chesspieces/wikipedia/wR.png and /dev/null differ diff --git a/experiments/chess/index.html b/experiments/chess/index.html deleted file mode 100644 index 667792de..00000000 --- a/experiments/chess/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -layout: default -game: chess ---- - -{% include experiments/game/headers.html %} - - - - - - -{% assign game = site.data.experiments[page.game] %} -{% include experiments/game/content.html game=game %} - -{% include experiments/game/footer.html %} - - - - \ No newline at end of file diff --git a/experiments/experiments.css b/experiments/experiments.css deleted file mode 100644 index e93ba659..00000000 --- a/experiments/experiments.css +++ /dev/null @@ -1,34 +0,0 @@ -body{ - min-height: 100vh; - display: flex; - flex-direction: column; -} - -.content{ - flex:2; - display: flex; -} -.demo-menu{ - padding: 10px; -} - -.demo-menu *{ - list-style: none; - text-decoration: none; - color: inherit; -} - -.demo-menu li{ - background: var(--light); - margin: 20px 0; - padding: 20px; -} - -.content li p{ - margin: 0; -} - -.content li p a{ - border-bottom: none; - font-weight: 600; -} \ No newline at end of file diff --git a/experiments/go/assets/bson/base_net.bson b/experiments/go/assets/bson/base_net.bson deleted file mode 100644 index 82388982..00000000 Binary files a/experiments/go/assets/bson/base_net.bson and /dev/null differ diff --git a/experiments/go/assets/bson/policy.bson b/experiments/go/assets/bson/policy.bson deleted file mode 100644 index 377b4f01..00000000 Binary files a/experiments/go/assets/bson/policy.bson and /dev/null differ diff --git a/experiments/go/assets/bson/value.bson b/experiments/go/assets/bson/value.bson deleted file mode 100644 index 84a9ed5d..00000000 Binary files a/experiments/go/assets/bson/value.bson and /dev/null differ diff --git a/experiments/go/assets/css/style.css b/experiments/go/assets/css/style.css deleted file mode 100644 index c208e97e..00000000 --- a/experiments/go/assets/css/style.css +++ /dev/null @@ -1,83 +0,0 @@ -.board { height: 500px; } -.pass{ - margin: 0 15px; - border: 1px solid var(--dark); - border-radius: 3px; - padding: 3px 15px; - cursor: pointer -} - -.pass.active{ - background: #dcdcdc; -} - - -.stats div{ - width: 100%; - justify-content: flex-end; - display: flex; -} - -.stats{ - padding: 0 20px; - background: #ebf5eb; - color: #41822a; - display: flex; -} - -.stats div p{ - display: flex; - align-items: center; - justify-content: space-around; -} - -.dot{ - width: 0; - height: 0; - border: 10px solid; - font-size: 0; - margin: 0 5px; - border-radius: 50%; -} - -.dot.black{ - border-color: #666; -} - -.dot.white{ - border-color: #fff; -} - -.pbar{ - position: absolute; - bottom: 0; - width: 0; - left: 0; - height: 3px; - background: var(--dark); - transition: width .7s cubic-bezier(0.69, 0.18, 0.74, 1.31); - border-top-right-radius: 6px; - /*border-bottom-right-radius: 50%;*/ -} - -#controls{ - position: relative; -} - -.wgo-board{ - border-top: none !important; - -} - -.num_readouts{ - width: 50px; - padding: 0 5px; - margin: 0 10px; - border: none; - border-bottom: 1px solid #95a595; -} - -.num_readouts:focus{ - outline: none; - border-bottom: 1px solid #556355; -} \ No newline at end of file diff --git a/experiments/go/assets/js/Board.js b/experiments/go/assets/js/Board.js deleted file mode 100644 index 76fa114b..00000000 --- a/experiments/go/assets/js/Board.js +++ /dev/null @@ -1,48 +0,0 @@ -function Board(board){ - - this.render = (config)=>{ - board.render(config); - - highlight($$("." + (config.turn==1?"human":"comp")), $$(".options")) - - var addS = (n, str) => n <= 1? str : str + "s"; - // var stats= $$("#game .stats"); - // if(stats == null){ - // stats = document.createElement('div'); - // stats.className = "stats" - // $$("#game").insertBefore(stats, $$("#game .board")) - // } - - // stats.innerHTML = "

Captures

\ - //
\ - //

" + config.capCount[WGo.B]+ " " + addS(config.capCount[WGo.B], "stone")+ "

\ - //

" + config.capCount[WGo.W]+ " " + addS(config.capCount[WGo.W], "stone")+ "

\ - //
" - - - - if(config.lastMove && config.lastMove.type == "pass"){ - var n = $$(".pass").className; - if(n.match("active") == null) $$(".pass").className = n + " active"; - setTimeout(()=>{ - var n = $$(".pass").className; - if(n.match("active") != null) $$(".pass").className = n.replace(" active", ""); - }, 1000) - } - - if(config.done){ - show($$(".overlay #gameOver")) - var score_ = $$(".overlay #gameOver .score"); - var info = "Black scores " + config.score + " points. " + (config.score > 0? "Black": "White") + " wins!"; - if(score_ == null){ - score_ = document.createElement('p'); - score_.className = "score" - $$(".overlay #gameOver").appendChild(score_); - } - score_.innerText = info; - }else{ - hide($$(".overlay #gameOver")) - } - }; -} - diff --git a/experiments/go/assets/js/Env.js b/experiments/go/assets/js/Env.js deleted file mode 100644 index 754d8e80..00000000 --- a/experiments/go/assets/js/Env.js +++ /dev/null @@ -1,188 +0,0 @@ -(function(obj){ - -Object.assign(obj, {Env}) - -function Env(s=9, repeat="KO"){ - this.s = s; - this.repeat = repeat; - this.env = new WGo.Game(s, repeat); - this.size = () => this.env.size; - this.n_moves = () => this.env.stack.length - 1; - this.moves = []; - this.model = null; - this.passes = []; -} - -Env.prototype.turn = function(){ - return this.env.turn; -} - -Env.prototype.state = function(){return getState(this.env)} - -Env.prototype.config = function(){ - var capCount = {}; - capCount[WGo.W] = this.env.getCaptureCount(WGo.W); - capCount[WGo.B] = this.env.getCaptureCount(WGo.B); - var score = this.find_score(this.env.getPosition()); - return {state: this.state(), done: this.done(), turn: this.turn(), capCount, lastMove: this.moves.slice(-1)[0], score} -} - -Env.prototype.setModel = function (m){ - this.model = m; -} - -Env.prototype.step = function(a){ - // console.log(a, "action") - this.moves.push(a) - if(a.type== "stone"){ - this.passes = []; - var k = this.env.play(a.x, a.y, a.c); - if(k instanceof Object)this.model.play_move(a); - } - else if(a.type == "pass"){ - if(this.passes.indexOf(a.c) == -1)this.passes.push(a.c); - this.env.pass(a.c); - this.model.play_move(a); - } -} - -Env.prototype.next = function(stack, a){ - var n = this.new_env(stack, a.c); - if(a.type== "stone"){ - n.play(a.x, a.y, a.c); - } - else if(a.type == "pass"){ - n.pass(a.c); - } - return n; -} - -Env.prototype.done = function(){ - return (this.passes.length >= 2); -} - -Env.prototype.reset = function(){ - this.env.firstPosition(); - this.passes = []; - this.model.__init__(this) -} - -Env.prototype.stack = function(){ - return this.env.stack.slice(); -} - -Env.prototype.getPosition = function(){ - return this.env.getPosition(); -} - -Env.prototype.new_env = function(stack, to_play){ - var n = new WGo.Game(this.s, this.repeat) - n.stack = stack.slice(); - n.turn = to_play || n.turn - return n; -} - -Env.prototype.all_legal_moves = function(stack, to_play){ - var s = this.size(); - var legal = new Array(s * s + 1).fill(1) - for(var x = 0; x< s; x++){ - for(var y = 0; y < s; y++){ - var n = this.new_env(stack, to_play) - var result = n.play(x, y, to_play) - - if(!(result instanceof Object)){ - var obj = {x, y, type: "stone"}; - legal[MCTS.to_flat(obj, s) - 1] = 0; - } - delete n - } - } - legal[81] = 1; - return legal; -} - -Env.prototype.check_if_done = function(moves){ - var pass = this.env.size * this.env.size + 1; - // console.log(moves) - out = moves.length >= 2 && moves.slice(-2).reduce((acc,e) => acc && (e == pass), true) - // console.log(out) - return out; -} - -var empty = 0; -var visited = 2; -var unknown = -2; - -Env.prototype.find_score = function({capCount, schema}={}){ - var board = schema.slice() - var n =this.size(); - board = MCTS.partition(board, n); - - - var i = 0; - var path = [], curr = null; - while((i = chooseEmpty(board, n)) && i ){ - var boundary = frontier({board, x: i[0], y: i[1], n}); - if(boundary.length == 0) break; - var same = true; - var h = boundary[0]; - for(var j of boundary){ - if(j != h){ - same =false; - break; - } - } - if(!same){ - h = unknown; - } - - for(var x = 0; x< n; x++){ - for(var y = 0; y< n; y++){ - if(board[x][y] == visited){ - board[x][y] = h; - } - } - } - - } - - var blackStones = schema.filter(e => e == WGo.B).length; - var whiteStones = schema.filter(e => e == WGo.W).length + 0.5; - var score = (blackStones - whiteStones); - // console.log("score: ", score) - return score; -} - -function chooseEmpty(board, n){ - for(var i = 0; i< n; i++){ - for(var j = 0; j< n; j++){ - if(board[i][j] == empty)return [i, j]; - } - } - return null; - } - -function frontier({board, x, y, n}){ - if(x < 0 || y< 0 || x >= n || y >= n || board[x][y] == visited) return []; - if(board[x][y]== WGo.B || board[x][y] == WGo.W)return [board[x][y]] - - var set = neighbours(board, x, y, n); - board[x][y] = visited; - var list = []; - for(var i of set){ - var [a, b] = i; - list.concat(frontier({board, x: a, b:y, n})); - } - return list; -} - -function neighbours(board, x, y, n){ - return [[x -1, y], [x, y -1], [x + 1, y], [x, y + 1]] - -} - -Env.prototype.lastMove = function(){ - return this.moves.slice(-1); -} - -})(window); \ No newline at end of file diff --git a/experiments/go/assets/js/MCTS/MCTSNode.js b/experiments/go/assets/js/MCTS/MCTSNode.js deleted file mode 100644 index a5366819..00000000 --- a/experiments/go/assets/js/MCTS/MCTSNode.js +++ /dev/null @@ -1,301 +0,0 @@ -/********** -=========== - -Original code at https://github.com/tejank10/AlphaGo.jl - -=========== -**********/ - -(function(obj){ - -obj.MCTS = obj.MCTS || {} - -Object.assign(obj.MCTS, {Node, DummyNode}) - -var MCTS = obj.MCTS; - -var c_puct = 0.96; -var val = (n, v) => new Array(n).fill(v); -var zeros = (n) => val(n, 0); -var ones = (n) => val(n, 1); -// var defObj = (n) => ({...zeros(n), "null":0, "-1":0}); - - -function Node(position, {parent, fmove=null, board_size=9, max_game_length, stack}={}){ - this.max_game_length = max_game_length || Math.floor((Math.pow(board_size,2) * 7) / 5); - this.parent = parent || new DummyNode(board_size); - this.board_size = board_size; - this.position = position; - this.fmove = fmove; - this.is_expanded = false; - this.losses_applied = 0; - - var total_moves = board_size * board_size + 1; - this.child_N = zeros(total_moves) - this.child_W = tf.zeros([total_moves]) - - // this.original_prior = zeros(total_moves) - this.child_prior = tf.zeros([total_moves]) - - this.children = {} - this.stack = stack || [position.schema()] - this.free = false; -} - -var node = Node.prototype; - -node.N = function(){ - return this.parent.child_N[this.fmove - 1]; -} - -node.set_N = function(value){ - this.parent.child_N[this.fmove - 1] = value; -} - -node.W = function(){ - return this.parent.child_W.buffer().get(this.fmove - 1); -} - -node.set_W = function(value){ - var x = this; - var l = x.parent.child_W.buffer(); - tf.dispose(x.parent.child_W); - l.set(value, x.fmove - 1) - x.parent.child_W = l.toTensor(); - return x.parent.child_W -} - -node.select_leaf = async function(nextLeaves){ - var current = this; - var n = this.board_size; - var pass_move = n * n + 1; - return (await this.select_leaf_loop(current, pass_move, n, nextLeaves)) -} - -node.select_leaf_loop = async function(current, pass_move, n, nextLeaves){ - var readouts = 0; - - var stop = (leaf) => !leaf.is_expanded || leaf.is_done() - - var d; - if((d = nextLeaves.splice(0,1)) && d.length == 1){ - current = d[0] - } - - while(readouts < 3){ - readouts++; - var current_new_N = current.N() + 1 - current.set_N(current_new_N) - - if (stop(current)){ - break; - } - - // if(current.fmove == 82) debugger - // if (current.position.last_move == pass_move - // && current.child_N[pass_move - 1] == 0){ - // current = current.maybe_add_child(pass_move) - // continue; - // } - cas = current.child_action_score() - // console.log("cas", this.child_N, current.child_N) - best_move = tf.tidy(()=>tf.argMax(cas).dataSync()[0] + 1) - tf.dispose(cas); - current = current.maybe_add_child(best_move) - } - - - - if (current.position.last_move == pass_move - && current.child_N[pass_move - 1] == 0 && !current.is_done()){ - // definetly explore this next - nextLeaves.push(current.maybe_add_child(pass_move)) - } - - if(stop(current))return [current, nextLeaves]; - else{ - var x= this; - return new Promise(function(resolve, reject){ - requestAnimationFrame(()=>{ - x.select_leaf_loop(current, pass_move, n, nextLeaves).then(out =>{ - resolve(out) - }) - }) - }) - } - -} - -function childname(node){ - if(node instanceof DummyNode || node.parent instanceof DummyNode)return "Dummy" - return childname(node.parent) +" >> " + node.fmove; -} - -node.maybe_add_child = function(move){ - // console.log("maybe_add_child", move) - - if(!this.children[move]){ - // console.log("add child:", childname(this), ">>", move) - var new_pos = this.position.play_move(move); - this.children[move] = new Node(new_pos, {fmove:move, parent:this, max_game_length: this.max_game_length}) - } - - return this.children[move]; -} - -node.child_action_score = function(){ - return tf.tidy(() =>{ - var larr = tf.tensor(this.legal_moves().map(e => 1000 *( 1 - e))); - var qarr = this.child_Q(); - // debugger; - var uarr = this.child_U(); - var l = this.board_size * this.board_size + 1; - var x = this; - return tf.sub(tf.add(tf.mul(qarr, tf.scalar(x.position.to_play)), uarr),larr) - }); -} - -node.child_Q = function(){ - var x = this; - var out = tf.tidy(() => (tf.div(x.child_W, tf.add(tf.scalar(1), tf.tensor(x.child_N))))) - // debugger; - return out; -} - -node.child_U = function(){ - var x = this; - return tf.tidy(() => tf.mul(tf.scalar(c_puct * Math.sqrt(1 + x.N())), - tf.div(x.child_prior, tf.add(tf.scalar(1), tf.tensor(x.child_N))))) -} - -node.legal_moves = function () { return this.position.legal_moves() }; - -node.backup_value = function(value, root_){ - this.set_W(this.W() + value); - if( this.parent == null || this == root_ )return; - this.parent.backup_value(value, root_); -} -node.add_virtual_loss = function(root_){ - this.losses_applied += 1; - var loss = this.position.to_play - this.set_W(this.W() + loss) - if (this.parent == null || this == root_) return; - this.parent.add_virtual_loss(root_) -} - -node.revert_virtual_loss = function(root_){ - this.losses_applied -= 1 - var revert = -1 * this.position.to_play; - this.set_W(this.W() + revert) - if (this.parent == null || this == root_) return; - - this.parent.revert_virtual_loss(root_) -} - -node.incorporate_results = function(move_probs, value, up_to){ - // console.log("incorporate_results", value, this.is_done()) - if (this.is_expanded){ - this.revert_visits(up_to) - return - } - this.is_expanded = true - // this.original_prior = move_probs.slice(); - tf.dispose(this.child_prior); - this.child_prior = move_probs; - - var len = this.board_size * this.board_size + 1 - tf.dispose(this.child_W) - this.child_W = tf.fill([len], value) - this.backup_value(value, up_to) -} - - -node.revert_visits = function(up_to){ - this.set_N(this.N() - 1) - // console.log(this.child_N) - if (this.parent == null || this == up_to )return; - this.parent.revert_visits(up_to); -} - -node.children_as_pi = function(squash=false){ - var probs = this.child_N; - var l = probs.length; - if(squash){ - for(var i = 0; i< l; i++){ - probs[i]= Math.pow(probs[i], 0.98) - } - } - var sum = 0; - for(var i = 0; i= this.max_game_length -} - -node.get_feats = function(){ - var last_eight = this.get_stack(8); - return this.position.get_feats(last_eight); -} - -node.get_stack = function(n){ - if(n == 0) return []; - if(this.isRoot) return this.stack.slice(0, n); - - return [this.position.schema()].concat(this.parent.get_stack(n - 1)); -} - -node.set_stack = function(n){ - this.stack = this.get_stack(n); -} - -node.set_dummy_parent = function(child_N){ - // debugger - this.parent.free_node(this.fmove); - this.parent = new DummyNode(this.board_size, child_N); - this.parent.child_N = child_N; -} - -node.free_node = function(savechild=-1){ - if(this.free) return; - tf.dispose(this.child_W); - tf.dispose(this.child_prior); - this.free = true; - for (var child in this.children){ - if(child != savechild) - this.children[child].free_node() - } - this.children = {} - if(this.parent != this) - this.parent.free_node(); -} - -function DummyNode(n){ - this.parent = null; - this.child_N = zeros(n*n + 1); - this.child_W = tf.zeros([n*n + 1]); - this.free = false; -} - -DummyNode.prototype = Object.create(node); - -DummyNode.prototype.get_stack = function(){ - return []; -}; - -DummyNode.prototype.free_node = function(){ - tf.dispose(this.child_W); - this.free = true; -} - -})(window); \ No newline at end of file diff --git a/experiments/go/assets/js/MCTS/MCTSPlayer.js b/experiments/go/assets/js/MCTS/MCTSPlayer.js deleted file mode 100644 index 83d9255a..00000000 --- a/experiments/go/assets/js/MCTS/MCTSPlayer.js +++ /dev/null @@ -1,189 +0,0 @@ -/********** -=========== - -Original code at https://github.com/tejank10/AlphaGo.jl - -=========== -**********/ - -(function(obj){ - -obj.MCTS = obj.MCTS || {} -Object.assign(obj.MCTS, {Player}) - -var MCTS = obj.MCTS; -var doNothing = () => null - -function Player(network, {layer, progress, num_readouts = 1, two_player_mode = false, resign_threshold = -0.9, board_size = 9, max_game_length}={}){ - this.board_size = board_size; - this.tau_threshold = two_player_mode ? -1 : (board_size * board_size / 12) / 2 * 2 - this.network = network; - this.num_readouts = num_readouts; - this.two_player_mode = two_player_mode; - this.qs = []; - this.searches_pi = []; - this.result = 0; - this.result_string = ""; - this.root = null - this.resign_threshold = resign_threshold; - this.position = null; - this.max_game_length = max_game_length; - this.layer = layer || doNothing; - this.progress = progress || doNothing; - this.current_readouts = 0; -} - -var player = Player.prototype; - -player.__init__ = function(pos){ - - this.root = new MCTS.Node(pos, { - max_game_length: this.max_game_length, - board_size: this.board_size - }); - this.result = 0 - this.searches_pi = []; - this.qs = []; -} - -player.suggest_move = async function(){ - if(this.root.legal_moves().filter(e => e == 1).length == 1){ - // pass move is the only legal move left - return MCTS.to_obj(this.board_size * this.board_size + 1, this.root.position.to_play, this.board_size); - } - // console.log("suggest move") - this.current_readouts = this.root.N(); - // console.log(cb) - return (await this.search_loop.bind(this)()); -} - -player.search_loop = async function(){ - if(this.root.N() >= this.current_readouts + this.num_readouts) - return this.pick_move(); - - await this.tree_search(); - this.layer(this.best_n(3)); - this.progress((this.root.N() - this.current_readouts)/this.num_readouts); - return (await this.search_loop.bind(this)()); -} - -player.tree_search = async function(parallel_readouts=8){ - var leaves = []; - var failsafe = 0; - - var leaves = await this.tree_search_loop(leaves, failsafe, parallel_readouts, []) - if(leaves.length == 0) return []; - - var { move_probs, values } = this.network.process(leaves) - - var len = this.board_size*this.board_size + 1 - - val = values.dataSync(); - tf.dispose(values) - for (var i in leaves){ - var leaf = leaves[i]; - var move_prob = move_probs.slice(0, 1).as1D() - var value = val[i]; - leaf.revert_virtual_loss(this.root) - leaf.incorporate_results(move_prob, value, this.root) - tf.dispose(move_prob); - } - tf.dispose(move_probs) - - return leaves -} - -player.tree_search_loop = async function(leaves, failsafe, parallel_readouts, nextLeaves){ - if(!(leaves.length < parallel_readouts && failsafe < 2 * parallel_readouts)) - return leaves; - - var count = 0; - - while((leaves.length < parallel_readouts && failsafe < 2 * parallel_readouts) && count < 2){ - count++; - failsafe += 1 - var res = await this.root.select_leaf(nextLeaves); - leaf = res[0] - nextLeaves = res[1] - - if (leaf.is_done()){ - value = (leaf.position.score() > 0 ? 1 : -1); - leaf.backup_value(value, this.root) - continue - } - - - - leaf.add_virtual_loss(this.root) - leaves.push(leaf) - } - - var scope = this; - return new Promise(function(resolve,reject){ - setTimeout(()=>{ - scope.tree_search_loop(leaves, failsafe, parallel_readouts, nextLeaves).then(out =>{ - resolve(out) - }); - }, 50) - }) -} - -player.get_feats = function(){ - return this.root.position.get_feats(); -} - -player.best_n = function(n){ - var arr = this.root.child_N.slice(); - var min = Math.min(...arr); - var best = []; - for(var i =0; i< n; i++){ - var index = MCTS.argMax(arr); - best.push(index); - arr[index] = min; - } - return best; -} - -player.pick_move = function(){ - var fcoord; - - - if (this.root.position.n >= this.tau_threshold){ - fcoord = MCTS.argMax(this.root.child_N) + 1; - }else{ - var cdf = tf.tidy(() => tf.cumsum(tf.tensor(this.root.child_N)).dataSync()); - var n = cdf.slice(-2)[0]; - var o = cdf.length - for(var i =0; i< o; i++){ - cdf[i] = MCTS.safe_div(cdf[i], n); - } - selection = Math.random() - var m = MCTS.searchsortedfirst(cdf, selection); - var l = this.board_size* this.board_size; - m = m == -1 || m >= l ? Math.floor(Math.random()*l): m - fcoord = m + 1 - - } - // console.log("fcoord....", fcoord) - return MCTS.to_obj(fcoord, this.root.position.to_play, this.board_size); -} - -player.play_move = function(c){ - // console.log("play", c); - c = MCTS.to_flat(c, this.board_size); - - if (!this.two_player_mode){ - this.searches_pi.push( - this.root.children_as_pi(this.root.position.n <= this.tau_threshold)) - } - this.qs.push(this.root.Q()) - - this.root = this.root.maybe_add_child(c); - - this.position = this.root.position - this.root.set_dummy_parent(this.root.parent.child_N); - - return true -} - -})(window); \ No newline at end of file diff --git a/experiments/go/assets/js/MCTS/Position.js b/experiments/go/assets/js/MCTS/Position.js deleted file mode 100644 index f0064446..00000000 --- a/experiments/go/assets/js/MCTS/Position.js +++ /dev/null @@ -1,77 +0,0 @@ -(function(obj){ - -obj.MCTS = obj.MCTS || {} - -Object.assign(obj.MCTS, {Position}) - -var MCTS = obj.MCTS - -var pos_to_board = (pos, n) => partition(pos.schema.slice(), n) - -// MCTS's representation of env -function Position(env, stack, moves, turn, n=0){ - this.position = stack.slice(-1)[0]; - this.size = env.size(); - this.stack = stack.slice(); - this.to_play = turn; - this.n = n; - this.last_move = moves.slice(-1)[0]; - this.env = env; - this.store = {} - this.recent = moves.slice(-2) -} - -var pos = Position.prototype; - -// doesn't affect the real environment -pos.play_move = function(f){ - var k = this.env.next(this.stack, MCTS.to_obj(f, this.to_play, this.size)); - return new Position(this.env, k.stack, this.recent.concat(f), k.turn, this.n + 1) -}; - -pos.schema = function(){ - return this.position.schema.slice(); -} - -pos.legal_moves = function(){ - // since it needs to be calculated only once for this stack - return this.store["legal_moves"] ? this.store["legal_moves"] : (()=>{ - var l = this.env.all_legal_moves(this.stack, this.to_play) - this.store["legal_moves"] = l; - return l; - })(); -} - -pos.is_done = function(){ - return this.env.check_if_done(this.recent) -} -pos.score = function(){ - return this.env.find_score(this.position) -} - -pos.get_feats = function(last_eight){ - return tf.tidy(() => tf.concat([this.stone_features(last_eight),this.color_to_play_feature()])); -} - -pos.stone_features = function(last_eight){ - while(last_eight.length < 8){ - last_eight.push(last_eight.slice(-1)[0]); - } - - var features = last_eight.reduce((acc, e) =>{ - var p = e.slice(); - var o = e.slice(); - p = p.map(f => (f == this.to_play) + 0); - o = o.map(f => (f == -1 * this.to_play) + 0); - acc.push(p, o) - return acc - }, []) - return tf.tidy(() => tf.tensor(features, [16, 81]).reshape([16, 9, 9])); -} - -pos.color_to_play_feature = function() { - return tf.tidy(() =>tf.fill([1, this.size, this.size], this.to_play)); -}; - - -})(window) \ No newline at end of file diff --git a/experiments/go/assets/js/MCTS/utils.js b/experiments/go/assets/js/MCTS/utils.js deleted file mode 100644 index 2c2fba90..00000000 --- a/experiments/go/assets/js/MCTS/utils.js +++ /dev/null @@ -1,60 +0,0 @@ -(function(obj){ - -obj.MCTS = obj.MCTS || {} - - -var to_flat = (l, n) => l.type=="pass" ? n * n + 1 : l.y + l.x * n + 1; -var to_obj = (f, c, n) => f == n * n + 1? ({type:"pass", c}):({type: "stone", x: Math.floor((f - 1)/n), y: Math.floor((f - 1) % n), c }) -var safe_div = (n, d) => d == 0? n*1000/Math.random() : n/d; - -function argMax(arr){ - var i = 0; - for(var j = 0; j< arr.length; j++){ - if(arr[j]> arr[i]) - i = j; - } - return i -} - - -function partition(array, n){ - return partition_(array.slice(),n) -} - -function partition_ (array, n){ - if(isNaN(n))debugger; - - var l = array.length; - var m = l/n - if(m != Math.floor(m)) throw Error("Invalid partition size") - var res = new Array(m); - var acc = new Array(n); - for(var i = 0; i e > x) - return bs(arr, x, 0, arr.length) -} - -function bs(arr, nee, beg, end){ - if(beg >= end) return beg; - - var mid = Math.floor((beg + end)/2) - - if( arr[mid] == nee) return mid; - else if( arr[mid] > nee) return bs(arr, nee, beg, mid - 1) - else return bs(arr, nee, mid + 1, end) -} - -Object.assign(obj.MCTS, {to_flat, to_obj, safe_div, argMax, partition, searchsortedfirst}) - -})(window); \ No newline at end of file diff --git a/experiments/go/assets/js/base_net.js b/experiments/go/assets/js/base_net.js deleted file mode 100644 index 69bf30e6..00000000 --- a/experiments/go/assets/js/base_net.js +++ /dev/null @@ -1,152 +0,0 @@ -/*********************** -Generated using FluxJS.jl -************************/ - -let base_net = (function () { - let math = tf; - function porcupine(hummingbird) { - return hummingbird; - }; - function okapi(cod) { - let monkey = cod[String("shape")][String("length")]; - let mink = Array(monkey).fill(1) - let mammoth = cod[String("shape")]; - mink[monkey - 2] = mammoth[mammoth[String("length")] - (monkey - 1)]; - return math.add(math.mul(math.div(math.sub(cod, math.reshape(model.weights[0], [mink[3], mink[2], mink[1], mink[0]])), math.reshape(model.weights[1], [mink[3], mink[2], mink[1], mink[0]])), math.reshape(model.weights[2], [mink[3], mink[2], mink[1], mink[0]])), math.reshape(model.weights[3], [mink[3], mink[2], mink[1], mink[0]])); - }; - function kinkajou(porpoise) { - return math.add(math.transpose(math.conv2d(math.transpose(porpoise, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[4], [2, 3, 1, 0], porpoise), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[5]); - }; - function snake(caterpillar) { - let camel = caterpillar[String("shape")][String("length")]; - let raven = Array(camel).fill(1) - let snail = caterpillar[String("shape")]; - raven[camel - 2] = snail[snail[String("length")] - (camel - 1)]; - return math.add(math.mul(math.div(math.sub(caterpillar, math.reshape(model.weights[6], [raven[3], raven[2], raven[1], raven[0]])), math.reshape(model.weights[7], [raven[3], raven[2], raven[1], raven[0]])), math.reshape(model.weights[8], [raven[3], raven[2], raven[1], raven[0]])), math.reshape(model.weights[9], [raven[3], raven[2], raven[1], raven[0]])); - }; - function crab(pig) { - return math.add(math.transpose(math.conv2d(math.transpose(pig, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[10], [2, 3, 1, 0], pig), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[11]); - }; - function cattle(sealion) { - return math.relu(math.add(porcupine(sealion), okapi(kinkajou(math.relu(snake(crab(flux.slice(sealion)))))))); - }; - function ape(eagle) { - return eagle; - }; - function bison(jellyfish) { - let mandrill = jellyfish[String("shape")][String("length")]; - let ferret = Array(mandrill).fill(1) - let shrew = jellyfish[String("shape")]; - ferret[mandrill - 2] = shrew[shrew[String("length")] - (mandrill - 1)]; - return math.add(math.mul(math.div(math.sub(jellyfish, math.reshape(model.weights[12], [ferret[3], ferret[2], ferret[1], ferret[0]])), math.reshape(model.weights[13], [ferret[3], ferret[2], ferret[1], ferret[0]])), math.reshape(model.weights[14], [ferret[3], ferret[2], ferret[1], ferret[0]])), math.reshape(model.weights[15], [ferret[3], ferret[2], ferret[1], ferret[0]])); - }; - function dogfish(redpanda) { - return math.add(math.transpose(math.conv2d(math.transpose(redpanda, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[16], [2, 3, 1, 0], redpanda), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[17]); - }; - function toad(aardvark) { - let badger = aardvark[String("shape")][String("length")]; - let gnat = Array(badger).fill(1); - let sandpiper = aardvark[String("shape")]; - gnat[badger - 2] = sandpiper[sandpiper[String("length")] - (badger - 1)]; - return math.add(math.mul(math.div(math.sub(aardvark, math.reshape(model.weights[18], [gnat[3], gnat[2], gnat[1], gnat[0]])), math.reshape(model.weights[19], [gnat[3], gnat[2], gnat[1], gnat[0]])), math.reshape(model.weights[20], [gnat[3], gnat[2], gnat[1], gnat[0]])), math.reshape(model.weights[21], [gnat[3], gnat[2], gnat[1], gnat[0]])); - }; - function beaver(dunlin) { - return math.add(math.transpose(math.conv2d(math.transpose(dunlin, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[22], [2, 3, 1, 0], dunlin), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[23]); - }; - function kouprey(tapir) { - return math.relu(math.add(ape(tapir), bison(dogfish(math.relu(toad(beaver(flux.slice(tapir)))))))); - }; - function oyster(yak) { - return yak; - }; - function dog(reddeer) { - let ibex = reddeer[String("shape")][String("length")]; - let wombat = Array(ibex).fill(1); - let dragonfly = reddeer[String("shape")]; - wombat[ibex - 2] = dragonfly[dragonfly[String("length")] - (ibex - 1)]; - return math.add(math.mul(math.div(math.sub(reddeer, math.reshape(model.weights[24], [wombat[3], wombat[2], wombat[1], wombat[0]])), math.reshape(model.weights[25], [wombat[3], wombat[2], wombat[1], wombat[0]])), math.reshape(model.weights[26], [wombat[3], wombat[2], wombat[1], wombat[0]])), math.reshape(model.weights[27], [wombat[3], wombat[2], wombat[1], wombat[0]])); - }; - function cockroach(tarsier) { - return math.add(math.transpose(math.conv2d(math.transpose(tarsier, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[28], [2, 3, 1, 0], tarsier), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[29]); - }; - function alpaca(kudu) { - let komodo = kudu[String("shape")][String("length")]; - let narwhal = Array(komodo).fill(1); - let crow = kudu[String("shape")]; - narwhal[komodo - 2] = crow[crow[String("length")] - (komodo - 1)]; - return math.add(math.mul(math.div(math.sub(kudu, math.reshape(model.weights[30], [narwhal[3], narwhal[2], narwhal[1], narwhal[0]])), math.reshape(model.weights[31], [narwhal[3], narwhal[2], narwhal[1], narwhal[0]])), math.reshape(model.weights[32], [narwhal[3], narwhal[2], narwhal[1], narwhal[0]])), math.reshape(model.weights[33], [narwhal[3], narwhal[2], narwhal[1], narwhal[0]])); - }; - function guineapig(grouse) { - return math.add(math.transpose(math.conv2d(math.transpose(grouse, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[34], [2, 3, 1, 0], grouse), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[35]); - }; - function chinchilla(lark) { - return math.relu(math.add(oyster(lark), dog(cockroach(math.relu(alpaca(guineapig(flux.slice(lark)))))))); - }; - function spider(albatross) { - return albatross; - }; - function cobra(lion) { - let panther = lion[String("shape")][String("length")]; - let partridge = Array(panther).fill(1); - let chamois = lion[String("shape")]; - partridge[panther - 2] = chamois[chamois[String("length")] - (panther - 1)]; - return math.add(math.mul(math.div(math.sub(lion, math.reshape(model.weights[36], [partridge[3], partridge[2], partridge[1], partridge[0]])), math.reshape(model.weights[37], [partridge[3], partridge[2], partridge[1], partridge[0]])), math.reshape(model.weights[38], [partridge[3], partridge[2], partridge[1], partridge[0]])), math.reshape(model.weights[39], [partridge[3], partridge[2], partridge[1], partridge[0]])); - }; - function pony(chough) { - return math.add(math.transpose(math.conv2d(math.transpose(chough, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[40], [2, 3, 1, 0], chough), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[41]); - }; - function lemur(wren) { - let rhinoceros = wren[String("shape")][String("length")]; - let cheetah = Array(rhinoceros).fill(1); - let wildebeest = wren[String("shape")]; - cheetah[rhinoceros - 2] = wildebeest[wildebeest[String("length")] - (rhinoceros - 1)]; - return math.add(math.mul(math.div(math.sub(wren, math.reshape(model.weights[42], [cheetah[3], cheetah[2], cheetah[1], cheetah[0]])), math.reshape(model.weights[43], [cheetah[3], cheetah[2], cheetah[1], cheetah[0]])), math.reshape(model.weights[44], [cheetah[3], cheetah[2], cheetah[1], cheetah[0]])), math.reshape(model.weights[45], [cheetah[3], cheetah[2], cheetah[1], cheetah[0]])); - }; - function magpie(dove) { - return math.add(math.transpose(math.conv2d(math.transpose(dove, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[46], [2, 3, 1, 0], dove), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[47]); - }; - function hare(antelope) { - return math.relu(math.add(spider(antelope), cobra(pony(math.relu(lemur(magpie(flux.slice(antelope)))))))); - }; - function elk(moose) { - return moose; - }; - function gaur(curlew) { - let anteater = curlew[String("shape")][String("length")]; - let cassowary = Array(anteater).fill(1); - let swan = curlew[String("shape")]; - cassowary[anteater - 2] = swan[swan[String("length")] - (anteater - 1)]; - return math.add(math.mul(math.div(math.sub(curlew, math.reshape(model.weights[48], [cassowary[3], cassowary[2], cassowary[1], cassowary[0]])), math.reshape(model.weights[49], [cassowary[3], cassowary[2], cassowary[1], cassowary[0]])), math.reshape(model.weights[50], [cassowary[3], cassowary[2], cassowary[1], cassowary[0]])), math.reshape(model.weights[51], [cassowary[3], cassowary[2], cassowary[1], cassowary[0]])); - }; - function lapwing(goosander) { - return math.add(math.transpose(math.conv2d(math.transpose(goosander, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[52], [2, 3, 1, 0], goosander), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[53]); - }; - function jaguar(rook) { - let emu = rook[String("shape")][String("length")]; - let wolverine = Array(emu).fill(1); - let locust = rook[String("shape")]; - wolverine[emu - 2] = locust[locust[String("length")] - (emu - 1)]; - return math.add(math.mul(math.div(math.sub(rook, math.reshape(model.weights[54], [wolverine[3], wolverine[2], wolverine[1], wolverine[0]])), math.reshape(model.weights[55], [wolverine[3], wolverine[2], wolverine[1], wolverine[0]])), math.reshape(model.weights[56], [wolverine[3], wolverine[2], wolverine[1], wolverine[0]])), math.reshape(model.weights[57], [wolverine[3], wolverine[2], wolverine[1], wolverine[0]])); - }; - function ibis(hippopotamus) { - return math.add(math.transpose(math.conv2d(math.transpose(hippopotamus, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[58], [2, 3, 1, 0], hippopotamus), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[59]); - }; - function pelican(crane) { - return math.relu(math.add(elk(crane), gaur(lapwing(math.relu(jaguar(ibis(flux.slice(crane)))))))); - }; - function guanaco(barracuda) { - let dotterel = barracuda[String("shape")][String("length")]; - let goldfinch = Array(dotterel).fill(1); - let reindeer = barracuda[String("shape")]; - goldfinch[dotterel - 2] = reindeer[reindeer[String("length")] - (dotterel - 1)]; - return math.relu(math.add(math.mul(math.div(math.sub(barracuda, math.reshape(model.weights[60], [goldfinch[3], goldfinch[2], goldfinch[1], goldfinch[0]])), math.reshape(model.weights[61], [goldfinch[3], goldfinch[2], goldfinch[1], goldfinch[0]])), math.reshape(model.weights[62], [goldfinch[3], goldfinch[2], goldfinch[1], goldfinch[0]])), math.reshape(model.weights[63], [goldfinch[3], goldfinch[2], goldfinch[1], goldfinch[0]]))); - }; - function rabbit(whale) { - return math.add(math.transpose(math.conv2d(math.transpose(whale, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[64], [2, 3, 1, 0], whale), [0, 1]), [1, 1], 1), [0, 3, 1, 2]), model.weights[65]); - }; - function model(falcon) { - return cattle(kouprey(chinchilla(hare(pelican(guanaco(rabbit(falcon))))))); - }; - model.weights = []; - return model; -})(); diff --git a/experiments/go/assets/js/config.js b/experiments/go/assets/js/config.js deleted file mode 100644 index 2d2520d7..00000000 --- a/experiments/go/assets/js/config.js +++ /dev/null @@ -1,8 +0,0 @@ -// config -var config = { - board_size: 9, - num_readouts: 64, - two_player_mode: true, - resign_threshold: -0.9, - max_game_length: 100 -} \ No newline at end of file diff --git a/experiments/go/assets/js/extensions.js b/experiments/go/assets/js/extensions.js deleted file mode 100644 index aad74a55..00000000 --- a/experiments/go/assets/js/extensions.js +++ /dev/null @@ -1,53 +0,0 @@ -WGo.Board.prototype.render = function(config){ - this.restoreState(config.state); -} - -Game.prototype.nextGameState = function(curr){ - // console.log("turn....", this.env.turn()) - if(this.env.turn() == WGo.B)return this.states.H; - return this.states.C; -} - -Game.prototype.defaultAction = () => ({x: -1, y: -1, c: 1, type:"stone"}) - -Game.prototype.play = function(){ - clearTimeout(this.playTimeout); - if(this.env.done())return; - - var scope = this; - switch(this.state){ - case this.states.H: - this.move(this.newAction); - // newAction = 0; - break; - case this.states.C: - var move = this.move.bind(this) - this.model(this.env.state()).then( a => move(a)) - break; - default: - console.log("Invalid state", this.state); - } -} - -Game.prototype.startState = function (){ - return this.states.H; -} - - -function getState(env){ - var n = env.size; - var k = env.position.schema.slice(); - - var objects = []; - for(var i = 0; i< n; i++){ - var o = []; - for(var j = 0; j< n; j++){ - var c = k[i*n + j]; - if(c != 0)o.push([{x: i, y: j, c }]) - else o.push([]) - } - objects.push(o); - } - - return ({ objects }); -} diff --git a/experiments/go/assets/js/model.js b/experiments/go/assets/js/model.js deleted file mode 100644 index ccb5dd21..00000000 --- a/experiments/go/assets/js/model.js +++ /dev/null @@ -1,32 +0,0 @@ -function Model(model, config){ - this.mctsPlayer = new MCTS.Player(this, config); - this.model = model; - - this.predict = async function(config, cb){ - var a = await this.mctsPlayer.suggest_move(); - return a; - } - this.predict = this.predict.bind(this) -} - -Model.prototype.process = function(input){ - var l= input.length; - var p = new Array(l); - var [pi, val] = tf.tidy(() =>{ - for(var i=0; i document.querySelector(e); - var doNothing = async function (e){ return e}; - - function tidyWrap(f){ - return (x) => tf.tidy(() => f(x)) - } - - for(var i in model){ - model[i] = tidyWrap(model[i]); - } - - - - var pBar = document.createElement("div"); - pBar.className = "pbar"; - var controls = $$("#controls"); - controls.appendChild(pBar); - - board = new WGo.Board(document.querySelector("#playground"), { - width: 500, - section: { - top: -1, - left: -1, - right: -1, - bottom: -1 - } - }); - board.setSize(9) - - - config.layer = add_best; - config.progress = function(val){ - var w = val * controls.offsetWidth; - pBar.style.width = w + "px" - } - - env = new Env(config.board_size, "KO"); - model = new Model(model, config); - - env.setModel(model); - env.reset(); - - game = new Game(env, new Board(board), model.predict.bind(this), { - mode: "async", - transform: { - state: doNothing, - action: doNothing - } - }) - - board.addEventListener("click", function(x, y){ - // console.log(x, y, env.turn()) - if(env.turn() == WGo.B){ - game.action({type: "stone", x, y, c: WGo.B}); - } - }) - - $$("#controls .pass").addEventListener("click", function(event){ - game.action({type: "pass", c:WGo.b}) - }) - - drawCoords(board); - drawBest(board); - drawIllegal(board); - game.display(); - - var inc = document.createElement('div'); - var input = document.createElement('input') - var label = document.createElement('label') - inc.appendChild(label) - inc.appendChild(input) - $$(".demo_wrapper").insertBefore(inc, $$(".instructions")); - label.innerText = "Number of searches"; - input.type = "number"; - input.className="num_readouts" - input.value = model.mctsPlayer.num_readouts; - input.onchange = function(){ - model.mctsPlayer.num_readouts = parseInt(event.target.value); - } - - -} - -function drawCoords(){ - - var coordinates = { - // draw on grid layer - grid: { - draw: function(args, board) { - - var ch, t, xright, xleft, ytop, ybottom; - - this.fillStyle = "rgba(0,0,0,0.7)"; - this.textBaseline="middle"; - this.textAlign="center"; - this.font = board.stoneRadius+"px "+(board.font || ""); - - xright = board.getX(-0.75); - xleft = board.getX(board.size-0.25); - ytop = board.getY(-0.75); - ybottom = board.getY(board.size-0.25); - - for(var i = 0; i < board.size; i++) { - ch = i+"A".charCodeAt(0); - if(ch >= "I".charCodeAt(0)) ch++; - - t = board.getY(i); - this.fillText(board.size-i, xright, t); - this.fillText(board.size-i, xleft, t); - - t = board.getX(i); - this.fillText(String.fromCharCode(ch), t, ytop); - this.fillText(String.fromCharCode(ch), t, ybottom); - } - - this.fillStyle = "black"; - } - } - } - board.addCustomObject(coordinates); -} - - -var container = { - best: [], - getBest: function(){ - return this.best; - }, - setBest: function(arr){ - this.best = arr; - } -} - -var colors = ["#009688"] - -function drawBest(board){ - var best_layer = { - grid: { - draw: function(args, board){ - $$(".pass").style.borderStyle = "solid"; - var best = container.getBest(); - if(best.length == 0) return - for(var i = 0; i< best.length; i++){ - var fmove = best[i] + 1; - var {x, y, type} = MCTS.to_obj(fmove, -1, board.size); - // console.log(type, x, y) - if(x == -1 || y == -1) continue; - if(type == "pass"){ - $$(".pass").style.borderStyle = "dashed"; - continue - } - - var xr = board.getX(x), - yr = board.getY(y), - sr = ((board.stoneRadius - 2)/(i + 1)); - - this.beginPath(); - this.strokeStyle = colors[i] || colors[colors.length - 1]; - this.lineWidth = 2; - this.setLineDash([2]) - this.arc(xr, yr, sr, 0, 2*Math.PI, true); - this.stroke(); - this.setLineDash([]) - container.setBest([]); - } - } - } - } - board.addCustomObject(best_layer); -} - -function add_best (arr) { - container.setBest(arr) - board.redraw() -} - -function drawIllegal(board){ - var iLayer = { - grid:{ - draw:function(){ - var illegal = model.mctsPlayer.root.legal_moves() - .map((e,i)=> [e, i]).filter((e)=> e[0] == 0); - - if(illegal.length == 0) return - for(var i = 0; i< illegal.length; i++){ - var fmove = illegal[i][1] + 1; - var {x, y, type} = MCTS.to_obj(fmove, -1, board.size); - // console.log(type, x, y) - if(x == -1 || y == -1) continue; - - var xr = board.getX(x), - yr = board.getY(y), - sr = ((board.stoneRadius - 2)/(i + 1)); - - this.beginPath(); - this.fillStyle = "#8a1c1c"; - this.arc(xr, yr, 3, 0, 2*Math.PI, true); - this.fill(); - } - } - } - } - board.addCustomObject(iLayer); -} - - -}()); \ No newline at end of file diff --git a/experiments/go/assets/js/value.js b/experiments/go/assets/js/value.js deleted file mode 100644 index 1e058bc8..00000000 --- a/experiments/go/assets/js/value.js +++ /dev/null @@ -1,39 +0,0 @@ -/*********************** -Generated using FluxJS.jl -************************/ - -let value = (function () { - let math = tf; - function porcupine(hummingbird) { - return math.tanh(math.add(math.matMul(hummingbird, model.weights[0]), model.weights[1])); - }; - function okapi(cod) { - return math.relu(math.add(math.matMul(cod, model.weights[2]), model.weights[3])); - }; - function monkey(mink, mammoth) { - return (mink[String("size")]/mammoth); - }; - function kinkajou(porpoise, snake) { - return (porpoise*snake); - }; - function caterpillar(camel) { - let raven = camel[String("shape")]; - let snail = raven[raven[String("length")] - 4]; - return math.reshape(camel, [snail, monkey(camel, kinkajou(1, snail))]); - }; - function crab(pig) { - let cattle = pig[String("shape")][String("length")]; - let sealion = Array(cattle).fill(1); - let ape = pig[String("shape")]; - sealion[cattle - 2] = ape[ape[String("length")] - (cattle - 1)]; - return math.relu(math.add(math.mul(math.div(math.sub(pig, math.reshape(model.weights[4], [sealion[3], sealion[2], sealion[1], sealion[0]])), math.reshape(model.weights[5], [sealion[3], sealion[2], sealion[1], sealion[0]])), math.reshape(model.weights[6], [sealion[3], sealion[2], sealion[1], sealion[0]])), math.reshape(model.weights[7], [sealion[3], sealion[2], sealion[1], sealion[0]]))); - }; - function eagle(bison) { - return math.add(math.transpose(math.conv2d(math.transpose(bison, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[8], [2, 3, 1, 0], bison), [0, 1]), [1, 1], 0), [0, 3, 1, 2]), model.weights[9]); - }; - function model(jellyfish) { - return porcupine(okapi(caterpillar(crab(eagle(jellyfish))))); - }; - model.weights = []; - return model; -})(); diff --git a/experiments/go/assets/wgo/black_128.png b/experiments/go/assets/wgo/black_128.png deleted file mode 100644 index cc257497..00000000 Binary files a/experiments/go/assets/wgo/black_128.png and /dev/null differ diff --git a/experiments/go/assets/wgo/black_64.png b/experiments/go/assets/wgo/black_64.png deleted file mode 100644 index cd158a27..00000000 Binary files a/experiments/go/assets/wgo/black_64.png and /dev/null differ diff --git a/experiments/go/assets/wgo/wgo.min.js b/experiments/go/assets/wgo/wgo.min.js deleted file mode 100644 index 5eeb6cbc..00000000 --- a/experiments/go/assets/wgo/wgo.min.js +++ /dev/null @@ -1,51 +0,0 @@ -/*! MIT license, more info: wgo.waltheri.net */(function(v,q){var m=document.getElementsByTagName("script"),g={version:"2.3.1",B:1,W:-1,ERROR_REPORT:!0,DIR:m[m.length-1].src.split("?")[0].split("/").slice(0,-1).join("/")+"/",lang:"en",i18n:{en:{}}};g.opera=-1!=navigator.userAgent.search(/(opera)(?:.*version)?[ \/]([\w.]+)/i);g.webkit=-1!=navigator.userAgent.search(/(webkit)[ \/]([\w.]+)/i);g.msie=-1!=navigator.userAgent.search(/(msie) ([\w.]+)/i);g.mozilla=-1!=navigator.userAgent.search(/(mozilla)(?:.*? rv:([\w.]+))?/i)&&!g.webkit&&!g.msie;g.t= -function(a){var b=g.i18n[g.lang][a]||g.i18n.en[a];if(b){for(var c=1;c/g,">"):a};var h=function(a,b){b=b||{};for(var c in b)this[c]=b[c];for(c in g.Board.default)this[c]===q&&(this[c]=g.Board.default[c]);for(c in h.themes.default)this.theme[c]===q&&(this.theme[c]=h.themes.default[c]);this.tx=this.section.left;this.ty=this.section.top;this.bx=this.size-1-this.section.right;this.by=this.size-1-this.section.bottom;this.init();a.appendChild(this.element);this.pixelRatio=v.devicePixelRatio||1;this.width&&this.height? -this.setDimensions(this.width,this.height):this.width?this.setWidth(this.width):this.height&&this.setHeight(this.height)};h.themes={};h.themes.old={shadowColor:"rgba(32,32,32,0.5)",shadowTransparentColor:"rgba(32,32,32,0)",shadowBlur:0,shadowSize:function(a){return a.shadowSize},markupBlackColor:"rgba(255,255,255,0.8)",markupWhiteColor:"rgba(0,0,0,0.8)",markupNoneColor:"rgba(0,0,0,0.8)",markupLinesWidth:function(a){return a.autoLineWidth?a.stoneRadius/7:a.lineWidth},gridLinesWidth:1,gridLinesColor:function(a){return"rgba(0,0,0,"+ -Math.min(1,a.stoneRadius/15)+")"},starColor:"#000",starSize:function(a){return a.starSize*(a.width/300+1)},stoneSize:function(a){return a.stoneSize*Math.min(a.fieldWidth,a.fieldHeight)/2},coordinatesColor:"rgba(0,0,0,0.7)",font:function(a){return a.font},linesShift:.5};h.themes.default={shadowColor:"rgba(62,32,32,0.5)",shadowTransparentColor:"rgba(62,32,32,0)",shadowBlur:function(a){return.1*a.stoneRadius},shadowSize:1,markupBlackColor:"rgba(255,255,255,0.9)",markupWhiteColor:"rgba(0,0,0,0.7)",markupNoneColor:"rgba(0,0,0,0.7)", -markupLinesWidth:function(a){return a.stoneRadius/8},gridLinesWidth:function(a){return a.stoneRadius/15},gridLinesColor:"#654525",starColor:"#531",starSize:function(a){return a.stoneRadius/8+1},stoneSize:function(a){return Math.min(a.fieldWidth,a.fieldHeight)/2},coordinatesColor:"#531",variationColor:"rgba(0,32,128,0.8)",font:"calibri",linesShift:.25};var k=function(a,b){return"function"==typeof b.theme[a]?b.theme[a](b):b.theme[a]},m={draw:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius; -this.beginPath();var f=k("shadowBlur",b),d=Math.max(0,d-.5),n=this.createRadialGradient(c-b.ls,e-b.ls,d-1-f,c-b.ls,e-b.ls,d+f);n.addColorStop(0,k("shadowColor",b));n.addColorStop(1,k("shadowTransparentColor",b));this.fillStyle=n;this.arc(c-b.ls,e-b.ls,d+f,0,2*Math.PI,!0);this.fill()},clear:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius;this.clearRect(c-1.1*d-b.ls,e-1.1*d-b.ls,2.2*d,2.2*d)}},p=function(a,b,c){return a.obj_arr[b][c][0].c==g.B?k("markupBlackColor",a):a.obj_arr[b][c][0].c== -g.W?k("markupWhiteColor",a):k("markupNoneColor",a)},D=function(a,b,c){return a.obj_arr[b][c][0]&&a.obj_arr[b][c][0].c==g.W||a.obj_arr[b][c][0].c==g.B},w,y=function(a){for(var b=a.angle,c=a.angle,e=0;el?(k=(n-h)/(f-l),r=Math.atan(k)):f==l?r=Math.PI/2:(k=(n-h)/(f-l),r=Math.atan(k)-Math.PI);g*=m;k=Math.sin(r)*g;r=Math.cos(r)*g;g=l+k;m=h-r;k=f+k;r=n-r;d.moveTo(l,h);d.bezierCurveTo(g,m,k,r,f,n);d.stroke()}};h.drawHandlers={NORMAL:{stone:{draw:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius,f;a.c==g.W?(f=this.createRadialGradient(c-2*d/5,e-2*d/5,d/3,c-d/5,e-d/5,5*d/5),f.addColorStop(0,"#fff"),f.addColorStop(1,"#aaa")):(f=this.createRadialGradient(c- -2*d/5,e-2*d/5,1,c-d/5,e-d/5,4*d/5),f.addColorStop(0,"#666"),f.addColorStop(1,"#000"));this.beginPath();this.fillStyle=f;this.arc(c-b.ls,e-b.ls,Math.max(0,d-.5),0,2*Math.PI,!0);this.fill()}},shadow:m},PAINTED:{stone:{draw:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius,f;a.c==g.W?(f=this.createRadialGradient(c-2*d/5,e-2*d/5,2,c-d/5,e-d/5,4*d/5),f.addColorStop(0,"#fff"),f.addColorStop(1,"#ddd")):(f=this.createRadialGradient(c-2*d/5,e-2*d/5,1,c-d/5,e-d/5,4*d/5),f.addColorStop(0,"#111"), -f.addColorStop(1,"#000"));this.beginPath();this.fillStyle=f;this.arc(c-b.ls,e-b.ls,Math.max(0,d-.5),0,2*Math.PI,!0);this.fill();this.beginPath();this.lineWidth=d/6;a.c==g.W?(this.strokeStyle="#999",this.arc(c+d/8,e+d/8,d/2,0,Math.PI/2,!1)):(this.strokeStyle="#ccc",this.arc(c-d/8,e-d/8,d/2,Math.PI,1.5*Math.PI));this.stroke()}},shadow:m},GLOW:{stone:{draw:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius,f;a.c==g.W?(f=this.createRadialGradient(c-2*d/5,e-2*d/5,d/3,c-d/5,e-d/5,8*d/5),f.addColorStop(0, -"#fff"),f.addColorStop(1,"#666")):(f=this.createRadialGradient(c-2*d/5,e-2*d/5,1,c-d/5,e-d/5,3*d/5),f.addColorStop(0,"#555"),f.addColorStop(1,"#000"));this.beginPath();this.fillStyle=f;this.arc(c-b.ls,e-b.ls,Math.max(0,d-.5),0,2*Math.PI,!0);this.fill()}},shadow:m},SHELL:{stone:{draw:function(a,b){var c,e,d=b.stoneRadius;w=w||Math.ceil(9999999*Math.random());c=b.getX(a.x);e=b.getY(a.y);var f;f=a.c==g.W?"#aaa":"#000";this.beginPath();this.fillStyle=f;this.arc(c-b.ls,e-b.ls,Math.max(0,d-.5),0,2*Math.PI, -!0);this.fill();if(a.c==g.W){f=w%(3+a.x*b.size+a.y)%3;var n=b.size*b.size+a.x*b.size+a.y,n=2/n*(w%n);0==f?y({ctx:this,x:c,y:e,radius:d,angle:n,lines:[.1,.12,.11,.1,.09,.09,.09,.09],factor:.25,thickness:1.75}):1==f?y({ctx:this,x:c,y:e,radius:d,angle:n,lines:[.1,.09,.08,.07,.06,.06,.06,.06,.06,.06,.06],factor:.2,thickness:1.5}):y({ctx:this,x:c,y:e,radius:d,angle:n,lines:[.12,.14,.13,.12,.12,.12],factor:.3,thickness:2});f=this.createRadialGradient(c-2*d/5,e-2*d/5,d/3,c-d/5,e-d/5,5*d/5);f.addColorStop(0, -"rgba(255,255,255,0.9)");f.addColorStop(1,"rgba(255,255,255,0)")}else f=this.createRadialGradient(c+.4*d,e+.4*d,0,c+.5*d,e+.5*d,d),f.addColorStop(0,"rgba(32,32,32,1)"),f.addColorStop(1,"rgba(0,0,0,0)"),this.beginPath(),this.fillStyle=f,this.arc(c-b.ls,e-b.ls,Math.max(0,d-.5),0,2*Math.PI,!0),this.fill(),f=this.createRadialGradient(c-.4*d,e-.4*d,1,c-.5*d,e-.5*d,1.5*d),f.addColorStop(0,"rgba(64,64,64,1)"),f.addColorStop(1,"rgba(0,0,0,0)");this.beginPath();this.fillStyle=f;this.arc(c-b.ls,e-b.ls,Math.max(0, -d-.5),0,2*Math.PI,!0);this.fill()}},shadow:m},MONO:{stone:{draw:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius,f=k("markupLinesWidth",b)||1;this.fillStyle=a.c==g.W?"white":"black";this.beginPath();this.arc(c,e,Math.max(0,d-f),0,2*Math.PI,!0);this.fill();this.lineWidth=f;this.strokeStyle="black";this.stroke()}}},CR:{stone:{draw:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius;this.strokeStyle=a.c||p(b,a.x,a.y);this.lineWidth=a.lineWidth||k("markupLinesWidth",b)||1;this.beginPath(); -this.arc(c-b.ls,e-b.ls,d/2,0,2*Math.PI,!0);this.stroke()}}},LB:{stone:{draw:function(a,b){var c=b.getX(a.x),e=b.getY(a.y),d=b.stoneRadius,f=a.font||k("font",b)||"";this.fillStyle=a.c||p(b,a.x,a.y);this.font=1==a.text.length?Math.round(1.5*d)+"px "+f:2==a.text.length?Math.round(1.2*d)+"px "+f:Math.round(d)+"px "+f;this.beginPath();this.textBaseline="middle";this.textAlign="center";this.fillText(a.text,c,e,2*d)}},grid:{draw:function(a,b){if(!D(b,a.x,a.y)&&!a._nodraw){var c=b.getX(a.x),e=b.getY(a.y), -d=b.stoneRadius;this.clearRect(c-d,e-d,2*d,2*d)}},clear:function(a,b){if(!D(b,a.x,a.y)){a._nodraw=!0;var c;b.grid.clear();b.grid.draw(b);for(var e=0;e=this.size?-1:b,y:a>=this.size?-1:a}},C=function(){this.element.style.width=this.width/this.pixelRatio+"px";this.element.style.height= -this.height/this.pixelRatio+"px";this.stoneRadius=k("stoneSize",this);this.ls=k("linesShift",this);for(var a=0;aa||0>b||a>=this.size||b>=this.size?q:this.schema[a*this.size+b]},set:function(a,b,c){this.schema[a*this.size+b]=c;return this},clear:function(){for(var a=0;ac||c>=a.size||0>e||e>=a.size)return!0;if(0==a.get(c,e))return!1;if(!0==b.get(c,e)||a.get(c,e)==-d)return!0;b.set(c,e,!0);return u(a,b,c,e-1,d)&&u(a,b,c,e+1,d)&&u(a,b,c-1,e,d)&&u(a,b,c+1,e,d)},l=function(a,b,c,e){var d=[];if(0<=b&&b=m;p--)if(this.stack[p].get(a,b)==d.get(a,b)){for(var k=!0,q=0;q'+b.t("show")+""}};m.infoList="black white AN CP DT EV GN GC HA ON OT RE RO RU SO TM US PC KM".split(" "); -b.Kifu=m;var c=function(c,a,e){for(var h=0;h=a.size&&"tt"==k[0]?{pass:!0,c:"B"==e?b.B:b.W}:{x:k[0].charCodeAt(0)-97,y:k[0].charCodeAt(1)-97,c:"B"==e?b.B:b.W}};f.AB=f.AW=function(a,d,k,e){for(var c in k)d.addSetup({x:k[c].charCodeAt(0)-97,y:k[c].charCodeAt(1)-97,c:"AB"==e?b.B:b.W})};f.AE=function(a,d,b){for(var e in b)d.addSetup({x:b[e].charCodeAt(0)-97,y:b[e].charCodeAt(1)- -97})};f.PL=function(a,d,k){d.turn="b"==k[0]||"B"==k[0]?b.B:b.W};f.C=function(a,d,b){d.comment=b.join()};f.LB=function(a,d,b){for(var e in b)d.addMarkup({x:b[e].charCodeAt(0)-97,y:b[e].charCodeAt(1)-97,type:"LB",text:b[e].substr(3)})};f.CR=f.SQ=f.TR=f.SL=f.MA=function(a,d,b,e){for(var c in b)d.addMarkup({x:b[c].charCodeAt(0)-97,y:b[c].charCodeAt(1)-97,type:e})};f.SZ=function(a,d,b){a.size=parseInt(b[0])};f.BR=f.WR=g.bind(this,"rank","BR");f.PB=f.PW=g.bind(this,"name","PB");f.BT=f.WT=g.bind(this,"team", -"BT");f.TM=function(a,d,b,e){a.info[e]=b[0];d.BL=b[0];d.WL=b[0]};var l=/\(|\)|(;(\s*[A-Z]+(\s*((\[\])|(\[(.|\s)*?([^\\]\]))))+)*)/g,d=/[A-Z]+(\s*((\[\])|(\[(.|\s)*?([^\\]\]))))+/g,k=/[A-Z]+/,a=/(\[\])|(\[(.|\s)*?([^\\]\]))/g;b.SGF.parse=function(h){var f=[],g,e,c,q=new b.Kifu,r=null;h=h.match(l);for(var p in h)if("("==h[p])f.push(r);else if(")"==h[p])r=f.pop();else{r&&q.nodeCount++;r=r?r.appendChild(new b.KNode):q.root;g=h[p].match(d)||[];q.propertyCount+=g.length;for(var w in g){c=k.exec(g[w])[0]; -e=g[w].match(a);for(var v in e)e[v]=e[v].substring(1,e[v].length-1).replace(/\\(?!\\)/g,"");if(b.SGF.properties[c])b.SGF.properties[c](q,r,e,c);else 1>=e.length&&(e=e[0]),r.parent?r[c]=e:q.info[c]=e}}return q}})(WGo);(function(b){var p=function(c,a){this.name="FileError";this.message=1==a?"File '"+c+"' is empty.":2==a?"Network error. It is not possible to read '"+c+"'.":"File '"+c+"' hasn't been found on server."};p.prototype=Error();p.prototype.constructor=p;b.FileError=p;var g=b.loadFromUrl=function(c,a){var e=new XMLHttpRequest;e.onreadystatechange=function(){if(4==e.readyState)if(200==e.status){if(0==e.responseText.length)throw new p(c,1);a(e.responseText)}else throw new p(c);};try{e.open("GET",c,!0),e.send()}catch(d){throw new p(c, -2);}},f=function(c){c.change&&this.board.update(c.change);this.temp_marks&&this.board.removeObject(this.temp_marks);var a=[];this.notification();c.node.move&&this.config.markLastMove&&(c.node.move.pass?this.notification(b.t((c.node.move.c==b.B?"b":"w")+"pass")):a.push({type:"CR",x:c.node.move.x,y:c.node.move.y}));if(1c.offsetHeight&&"auto"==window.getComputedStyle(c).overflow?!0:d(c.parentNode,a)},k=function(c){var a=c.wheelDelta||-1*c.detail;return d(c.target,this)?!0:0>a?(this.next(),this.config.lockScroll&&c.preventDefault&&c.preventDefault(),!this.config.lockScroll):0WGo.js Player 2.0

WGo.js Player is extension of WGo.js, HTML5 library for purposes of game of go. It allows to replay go game records and it has many features like score counting. It is also designed to be easily extendable.

WGo.js is open source licensed under MIT license. You can use and modify any code from this project.

You can find more information at wgo.waltheri.net/player

Copyright © 2013 Jan Prokop

", -black:"Black",white:"White",DT:"Date",KM:"Komi",HA:"Handicap",AN:"Annotations",CP:"Copyright",GC:"Game comments",GN:"Game name",ON:"Fuseki",OT:"Overtime",TM:"Basic time",RE:"Result",RO:"Round",RU:"Rules",US:"Recorder",PC:"Place",EV:"Event",SO:"Source",none:"none",bpass:"Black passed.",wpass:"White passed."},e;for(e in m)b.i18n.en[e]=m[e]})(WGo);(function(b){var p=0,g=function(d,b,a){var h={};h.element=document.createElement("div");h.element.className="wgo-player-"+d;h.wrapper=document.createElement("div");h.wrapper.className="wgo-player-"+d+"-wrapper";h.element.appendChild(h.wrapper);b.appendChild(h.element);a||(h.element.style.display="none");return h},f=function(d){var b;if(b=this.currentLayout.layout?this.currentLayout.layout[d]:this.currentLayout[d]){this.regions[d].element.style.display="block";b.constructor!=Array&&(b=[b]);for(var a in b)this.components[b[a]]|| -(this.components[b[a]]=new l.component[b[a]](this)),this.components[b[a]].appendTo(this.regions[d].wrapper),this.components[b[a]]._detachFromPlayer=!1}else this.regions[d].element.style.display="none"},l=b.extendClass(b.Player,function(d,k){this.config=k;for(var a in l.default)void 0===this.config[a]&&void 0!==l.default[a]&&(this.config[a]=l.default[a]);for(a in b.Player.default)void 0===this.config[a]&&void 0!==b.Player.default[a]&&(this.config[a]=b.Player.default[a]);this.element=d;this.element.innerHTML= -"";this.classes=(this.element.className?this.element.className+" ":"")+"wgo-player-main";this.element.className=this.classes;this.element.id||(this.element.id="wgo_"+p++);this.dom={};this.dom.center=document.createElement("div");this.dom.center.className="wgo-player-center";this.dom.board=document.createElement("div");this.dom.board.className="wgo-player-board";this.regions={};this.regions.left=g("left",this.element);this.element.appendChild(this.dom.center);this.regions.right=g("right",this.element); -this.regions.top=g("top",this.dom.center);this.dom.center.appendChild(this.dom.board);this.regions.bottom=g("bottom",this.dom.center);this.board=new b.Board(this.dom.board,this.config.board);this.init();this.components={};window.addEventListener("resize",function(){this.noresize||this.updateDimensions()}.bind(this));this.updateDimensions();this.initGame()});l.prototype.appendTo=function(d){d.appendChild(this.element);this.updateDimensions()};l.prototype.updateDimensions=function(){for(var d=window.getComputedStyle(this.element), -b=[];this.element.firstChild;)b.push(this.element.firstChild),this.element.removeChild(this.element.firstChild);for(var a=parseInt(d.width),h=parseInt(d.height),n=parseInt(d.maxHeight)||0,d=0;d=this.width)||b[h].conditions.maxHeight&&a&&!(b[h].conditions.maxHeight>=a)||b[h].conditions.custom&&!b[h].conditions.custom.call(this))){b=b[h];break a}b=void 0}if((this.currentLayout=b)&&this.lastLayout!=this.currentLayout){this.element.className=this.currentLayout.className?this.classes+" "+this.currentLayout.className:this.classes;for(var g in this.components)this.components[g]._detachFromPlayer= -!0;f.call(this,"left");f.call(this,"right");f.call(this,"top");f.call(this,"bottom");for(g in this.components)this.components[g]._detachFromPlayer&&this.components[g].element.parentNode&&this.components[g].element.parentNode.removeChild(this.components[g].element);this.lastLayout=this.currentLayout}b=this.dom.board.clientWidth;(g=this.height||this.maxHeight)&&(g-=this.regions.top.element.offsetHeight+this.regions.bottom.element.offsetHeight);g&&g"+d.name+"

"+d.message+'

If this message isn\'t correct, please report it by clicking here, otherwise contact maintainer of this site.

'); -break;case "FileError":this.showMessage("

"+d.name+"

"+d.message+"

Please contact maintainer of this site. Note: it is possible to read files only from this host.

");break;default:this.showMessage("

"+d.name+"

"+d.message+"

"+d.stacktrace+'

Please contact maintainer of this site. You can also report it here.

')}};l.component={};l.layouts={one_column:{top:[],bottom:[]},no_comment:{top:[],bottom:[]},right_top:{top:[],right:[]},right:{right:[]}, -minimal:{bottom:[]}};l.dynamicLayout=[{conditions:{minWidth:650},layout:l.layouts.right_top,className:"wgo-twocols wgo-large"},{conditions:{minWidth:550,minHeight:600},layout:l.layouts.one_column,className:"wgo-medium"},{conditions:{minWidth:350},layout:l.layouts.no_comment,className:"wgo-small"},{layout:l.layouts.no_comment,className:"wgo-xsmall"}];l.default={layout:l.dynamicLayout};b.i18n.en["BP:closemsg"]="click anywhere to close this window";l.attributes={"data-wgo":function(b){b&&("("==b[0]? -this.sgf=b:this.sgfFile=b)},"data-wgo-board":function(b){this.board=eval("({"+b+"})")},"data-wgo-onkifuload":function(b){this.kifuLoaded=new Function(b)},"data-wgo-onupdate":function(b){this.update=new Function(b)},"data-wgo-onfrozen":function(b){this.frozen=new Function(b)},"data-wgo-onunfrozen":function(b){this.unfrozen=new Function(b)},"data-wgo-layout":function(b){this.layout=eval("({"+b+"})")},"data-wgo-enablewheel":function(b){"false"==b.toLowerCase()&&(this.enableWheel=!1)},"data-wgo-lockscroll":function(b){"false"== -b.toLowerCase()&&(this.lockScroll=!1)},"data-wgo-enablekeys":function(b){"false"==b.toLowerCase()&&(this.enableKeys=!1)},"data-wgo-rememberpath":function(b){"false"==b.toLowerCase()&&(this.rememberPath=!1)},"data-wgo-allowillegal":function(b){"false"!=b.toLowerCase()&&(this.allowIllegalMoves=!0)},"data-wgo-move":function(b){var f=parseInt(b);this.move=f?f:eval("({"+b+"})")},"data-wgo-marklastmove":function(b){"false"==b.toLowerCase()&&(this.markLastMove=!1)},"data-wgo-diagram":function(b){b&&("("== -b[0]?this.sgf=b:this.sgfFile=b,this.enableWheel=this.enableKeys=this.markLastMove=!1,this.layout={top:[],right:[],left:[],bottom:[]})}};b.BasicPlayer=l;window.addEventListener("load",function(){for(var b=document.querySelectorAll("[data-wgo],[data-wgo-diagram]"),f=0;fa.offsetHeight)for(d-=2;a.scrollHeight>a.offsetHeight&&1a.offsetHeight&&(a.style.fontSize=d-4+"px")}},l=function(a){a.node.BL&&this.setPlayerTime("black",a.node.BL);a.node.WL&&this.setPlayerTime("white",a.node.WL);void 0!==a.position.capCount.black&&(this.black.info.caps.val.innerHTML= -a.position.capCount.black);void 0!==a.position.capCount.white&&(this.white.info.caps.val.innerHTML=a.position.capCount.white)},d=WGo.extendClass(WGo.BasicPlayer.component.Component,function(a){this.super(a);this.element.className="wgo-infobox";b.call(this,"white");b.call(this,"black");this.element.appendChild(this.white.box);this.element.appendChild(this.black.box);a.addEventListener("kifuLoaded",g.bind(this));a.addEventListener("update",l.bind(this))});d.prototype.setPlayerTime=function(a,b){var d= -Math.floor(b/60),f=Math.round(b)%60;this[a].info.time.val.innerHTML=d+":"+(10>f?"0"+f:f)};d.prototype.updateDimensions=function(){f(this.black.name);f(this.white.name)};var k=WGo.BasicPlayer.layouts;k.right_top.right.push("InfoBox");k.right.right.push("InfoBox");k.one_column.top.push("InfoBox");k.no_comment.top.push("InfoBox");WGo.i18n.en.rank="Rank";WGo.i18n.en.caps="Caps";WGo.i18n.en.time="Time";WGo.BasicPlayer.component.InfoBox=d})(WGo);(function(b,p){var g=function(a){var b,d;b=a.charCodeAt(0)-97;0>b&&(b+=32);7");for(var g in a)f+='
'+g+''+a[g]+"
";return f+"
"},k=b.extendClass(b.BasicPlayer.component.Component,function(a){this.super(a);this.player=a;this.element.className="wgo-commentbox";this.box=document.createElement("div"); -this.box.className="wgo-box-wrapper wgo-comments-wrapper";this.element.appendChild(this.box);this.comments_title=document.createElement("div");this.comments_title.className="wgo-box-title";this.comments_title.innerHTML=b.t("comments");this.box.appendChild(this.comments_title);this.comments=document.createElement("div");this.comments.className="wgo-comments-content";this.box.appendChild(this.comments);this.help=document.createElement("div");this.help.className="wgo-help";this.help.style.display="none"; -this.comments.appendChild(this.help);this.notification=document.createElement("div");this.notification.className="wgo-notification";this.notification.style.display="none";this.comments.appendChild(this.notification);this.comment_text=document.createElement("div");this.comment_text.className="wgo-comment-text";this.comments.appendChild(this.comment_text);a.addEventListener("kifuLoaded",function(h){h.kifu.hasComments()?(this.comments_title.innerHTML=b.t("comments"),this.element.className="wgo-commentbox", -this._update=function(a){this.setComments(a)}.bind(this),a.addEventListener("update",this._update)):(this.comments_title.innerHTML=b.t("gameinfo"),this.element.className="wgo-commentbox wgo-gameinfo",this._update&&(a.removeEventListener("update",this._update),delete this._update),this.comment_text.innerHTML=d(h.target.getGameInfo()))}.bind(this));a.notification=function(a){a?(this.notification.style.display="block",this.notification.innerHTML=a,this.is_notification=!0):(this.notification.style.display= -"none",this.is_notification=!1)}.bind(this);a.help=function(a){a?(this.help.style.display="block",this.help.innerHTML=a,this.is_help=!0):(this.help.style.display="none",this.is_help=!1)}.bind(this)});k.prototype.setComments=function(a){this.player._tmp_mark&&f.call(this.player);var b="";a.node.parent||(b=d(a.target.getGameInfo(),!0));this.comment_text.innerHTML=b+this.getCommentText(a.node.comment,this.player.config.formatNicks,this.player.config.formatMoves);this.player.config.formatMoves&&this.comment_text.childNodes&& -this.comment_text.childNodes.length&&l(this.comment_text.childNodes,this.player)};k.prototype.getCommentText=function(a,d,f){return a?(a="

"+b.filterHTML(a).replace(/\n/g,"

")+"

",d&&(a=a.replace(/(

)([^:]{3,}:)\s/g,'

$2 ')),f&&(a=a.replace(/\b[a-zA-Z]1?\d\b/g,'$&')),a):""};b.BasicPlayer.default.formatNicks=!0;b.BasicPlayer.default.formatMoves=!0;b.BasicPlayer.attributes["data-wgo-formatnicks"]= -function(a){"false"==a.toLowerCase()&&(this.formatNicks=!1)};b.BasicPlayer.attributes["data-wgo-formatmoves"]=function(a){"false"==a.toLowerCase()&&(this.formatMoves=!1)};b.BasicPlayer.layouts.right_top.right.push("CommentBox");b.BasicPlayer.layouts.right.right.push("CommentBox");b.BasicPlayer.layouts.one_column.bottom.push("CommentBox");b.i18n.en.comments="Comments";b.i18n.en.gameinfo="Game info";b.BasicPlayer.component.CommentBox=k})(WGo);(function(b,p){var g=b.extendClass(b.BasicPlayer.component.Component,function(a){this.super(a);this.widgets=[];this.element.className="wgo-player-control";this.iconBar=document.createElement("div");this.iconBar.className="wgo-control-wrapper";this.element.appendChild(this.iconBar);var b,d;for(d in g.widgets)b=new g.widgets[d].constructor(a,g.widgets[d].args),b.appendTo(this.iconBar),this.widgets.push(b)});g.prototype.updateDimensions=function(){this.element.className=340>this.element.clientWidth? -"wgo-player-control wgo-340":440>this.element.clientWidth?"wgo-player-control wgo-440":"wgo-player-control"};var f=b.BasicPlayer.control={},l=function(a){a.node.parent||this.disabled?a.node.parent&&this.disabled&&this.enable():this.disable()},d=function(a){a.node.children.length||this.disabled?a.node.children.length&&this.disabled&&this.enable():this.disable()},k=function(a){(this._disabled=this.disabled)||this.disable()},a=function(a){this._disabled||this.enable();delete this._disabled};f.Widget= -function(a,b){this.element=this.element||document.createElement(b.type||"div");this.element.className="wgo-widget-"+b.name;this.init(a,b)};f.Widget.prototype={constructor:f.Widget,init:function(a,b){b&&(b.disabled&&this.disable(),b.init&&b.init.call(this,a))},appendTo:function(a){a.appendChild(this.element)},disable:function(){this.disabled=!0;-1==this.element.className.search("wgo-disabled")&&(this.element.className+=" wgo-disabled")},enable:function(){this.disabled=!1;this.element.className=this.element.className.replace(" wgo-disabled", -"");this.element.disabled=""}};f.Group=b.extendClass(f.Widget,function(a,b){this.element=document.createElement("div");this.element.className="wgo-ctrlgroup wgo-ctrlgroup-"+b.name;var d,f;for(f in b.widgets)d=new b.widgets[f].constructor(a,b.widgets[f].args),d.appendTo(this.element)});f.Clickable=b.extendClass(f.Widget,function(a,b){this.super(a,b)});f.Clickable.prototype.init=function(a,b){var d,f=this;d=b.togglable?function(){f.disabled||(b.click.call(f,a)?f.select():f.unselect())}:function(){f.disabled|| -b.click.call(f,a)};this.element.addEventListener("click",d);this.element.addEventListener("touchstart",function(a){a.preventDefault();d();b.multiple&&(f._touch_i=0,f._touch_int=window.setInterval(function(){500"+b.t("RE")+"

";m=d.length+n.length+this.originalPosition.capCount.black;e=f.length+h.length+this.originalPosition.capCount.white+parseFloat(this.komi);a+="

"+b.t("black")+": "+d.length+" + "+(n.length+this.originalPosition.capCount.black)+ -" = "+m+"
";a+=b.t("white")+": "+f.length+" + "+(h.length+this.originalPosition.capCount.white)+" + "+this.komi+" = "+e+"

";a=m>e?a+("

"+b.t("bwin",m-e)+"

"):a+("

"+b.t("wwin",e-m)+"

");this.output(a)};p.prototype.calculate=function(){var b,f,a,h,n,m;b=this.position;for(m=!0;m;){m=!1;for(var e=0;el;l++)a[l]==g.BLACK_STONE||a[l]==g.BLACK_CANDIDATE?h=!0:a[l]==g.WHITE_STONE||a[l]==g.WHITE_CANDIDATE?n=!0:a[l]==g.NEUTRAL&&(n=h=!0);a=!1;h&&n?a=g.NEUTRAL:h?a=g.BLACK_CANDIDATE:n&&(a=g.WHITE_CANDIDATE);a&&f!=a&&(m=!0,b.set(c,e,a))}}};b.ScoreMode=p;b.BasicPlayer&&b.BasicPlayer.component.Control&&b.BasicPlayer.component.Control.menu.push({constructor:b.BasicPlayer.control.MenuItem,args:{name:"scoremode",togglable:!0,click:function(d){if(this.selected)return d.setFrozen(!1), -this._score_mode.end(),delete this._score_mode,d.notification(),d.help(),!1;d.setFrozen(!0);d.help("

"+b.t("help_score")+"

");this._score_mode=new b.ScoreMode(d.kifuReader.game.position,d.board,d.kifu.info.KM||.5,d.notification);this._score_mode.start();return!0}}});b.i18n.en.scoremode="Count score";b.i18n.en.score="Score";b.i18n.en.bwin="Black wins by $ points.";b.i18n.en.wwin="White wins by $ points.";b.i18n.en.help_score="Click on stones to mark them dead or alive. You can also set and unset territory points by clicking on them. Territories must be completely bordered."})(WGo);(function(b,p){var g={active:!0,query:{}},f=function(b){try{g.query=JSON.parse('{"'+window.location.hash.substr(1).replace("=",'":')+"}")}catch(f){g.query={}}};window.addEventListener("hashchange",function(){if(""!=window.location.hash&&g.active){f();for(var b in g.query){var k=document.getElementById(b);k&&k._wgo_player&&k._wgo_player.goTo(l)}}});window.addEventListener("DOMContentLoaded",function(){""!=window.location.hash&&g.active&&f()});window.addEventListener("load",function(){if(""!=window.location.hash&& -g.active)for(var b in g.query){var f=document.getElementById(b);if(f&&f._wgo_player){f.scrollIntoView();break}}});var l=function(){if(g.query[this.element.id])return g.query[this.element.id].goto};b.Player.default.move=l;b.BasicPlayer&&b.BasicPlayer.component.Control&&b.BasicPlayer.component.Control.menu.push({constructor:b.BasicPlayer.control.MenuItem,args:{name:"permalink",click:function(d){var f=location.href.split("#")[0]+"#"+d.element.id+'={"goto":'+JSON.stringify(d.kifuReader.path)+"}";d.showMessage("

"+ -b.t("permalink")+'

')}}});b.Player.permalink=g;b.i18n.en.permalink="Permanent link"})(WGo); diff --git a/experiments/go/assets/wgo/white_128.png b/experiments/go/assets/wgo/white_128.png deleted file mode 100644 index 5d3a6acb..00000000 Binary files a/experiments/go/assets/wgo/white_128.png and /dev/null differ diff --git a/experiments/go/assets/wgo/white_64.png b/experiments/go/assets/wgo/white_64.png deleted file mode 100644 index 38bc59eb..00000000 Binary files a/experiments/go/assets/wgo/white_64.png and /dev/null differ diff --git a/experiments/go/assets/wgo/wood1.jpg b/experiments/go/assets/wgo/wood1.jpg deleted file mode 100644 index e3a88a9a..00000000 Binary files a/experiments/go/assets/wgo/wood1.jpg and /dev/null differ diff --git a/experiments/go/assets/wgo/wood_1024.jpg b/experiments/go/assets/wgo/wood_1024.jpg deleted file mode 100644 index 278e1f51..00000000 Binary files a/experiments/go/assets/wgo/wood_1024.jpg and /dev/null differ diff --git a/experiments/go/assets/wgo/wood_512.jpg b/experiments/go/assets/wgo/wood_512.jpg deleted file mode 100644 index 5c2c8e1d..00000000 Binary files a/experiments/go/assets/wgo/wood_512.jpg and /dev/null differ diff --git a/experiments/go/index.html b/experiments/go/index.html deleted file mode 100644 index d79deb52..00000000 --- a/experiments/go/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: default -game: go ---- - -{% include experiments/game/headers.html %} - - - - - -{% assign game = site.data.experiments[page.game] %} -{% include experiments/game/content.html game=game %} - - -{% include experiments/game/footer.html %} - - - - - - - - - - - - - \ No newline at end of file diff --git a/experiments/index.html b/experiments/index.html deleted file mode 100644 index bf354d22..00000000 --- a/experiments/index.html +++ /dev/null @@ -1,17 +0,0 @@ ---- -layout: default -title: Experiments ---- - - -
-
-

Flux Experiments

- -
-
diff --git a/experiments/mnist/assets/bson/mnist-conv.bson b/experiments/mnist/assets/bson/mnist-conv.bson deleted file mode 100644 index 322b86e2..00000000 Binary files a/experiments/mnist/assets/bson/mnist-conv.bson and /dev/null differ diff --git a/experiments/mnist/assets/bson/mnist-mlp.bson b/experiments/mnist/assets/bson/mnist-mlp.bson deleted file mode 100644 index d0a0fafc..00000000 Binary files a/experiments/mnist/assets/bson/mnist-mlp.bson and /dev/null differ diff --git a/experiments/mnist/assets/css/style.css b/experiments/mnist/assets/css/style.css deleted file mode 100644 index 4ee8ad47..00000000 --- a/experiments/mnist/assets/css/style.css +++ /dev/null @@ -1,110 +0,0 @@ -/* basic styles */ -*{ - margin: 0; - padding: 0; - -} - -.heading{ - font-size: 30px; - background: #555; - color: #fff; - padding: 30px 50px; - z-index: 3; - box-shadow: 0 3px 5px #aaa; - height: 11vh; - box-sizing: border-box; -} - -.options{ - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; -} - -.demo_wrapper{ - display: flex; -} - -#number{ - transform: scale(1); - margin: 20px 0; - -} -#editor{ - border: 16px solid var(--dark); - background: var(--light); -} - -.render_editor{ - flex:1; - padding: 50px; - box-sizing: border-box; - position:relative; -} - -.options button{ - font-size: 16px; - margin: 30px 0; - margin-right: 10px; - padding: 10px 20px; - border-radius: 6px; - background: var(--light); - color: #000; - cursor: pointer; - border: 2px solid var(--dark); - transition: all .5s linear; - width: 110px; -} - -.options button:hover{ - background: #eee; -} - -.options button:active, -.options button:focus{ - outline: none; -} - -.render_editor h1, .render_image h1{ - /*padding: 30px 0;*/ - /*border-bottom: 1px solid #000;*/ -} - -.render_editor > div{ - display: flex; - justify-content: center; -} - -.render_editor > div > div{ - margin: 0 50px; -} - -@media only screen and (max-width: 768px){ - .render_editor{ - /*width: 100vw;*/ - height: auto; - padding: 20px 0; - } - - .demo_wrapper{ - flex-direction: column; - text-align: center; - } - - .options button{ - margin: 30px auto; - } - - .render_editor > div{ - flex-direction:column; - } - - #result{ - margin-top:0px; - } - -} - - diff --git a/experiments/mnist/assets/js/Editor.js b/experiments/mnist/assets/js/Editor.js deleted file mode 100644 index a1983a3d..00000000 --- a/experiments/mnist/assets/js/Editor.js +++ /dev/null @@ -1,175 +0,0 @@ -(function(){ - -Object.assign(window, {Editor}) - -// editor -function Editor(ele, - { - strokeWidth=15, - // color="#555", - color=getComputedStyle(document.body).getPropertyValue('--medium'), - scale=1 - }={}) -{ - this.canvas = ele; - this.ctx = ele.getContext('2d'); - this.strokeWidth = strokeWidth; - this.color = color; - this.prevPoint = null; - - this.ctx.scale(scale, scale); - this.ctx.clearRect(0,0, this.canvas.width, this.canvas.height); - this.callback = null; -} - -Editor.prototype = Object.create(EventTarget.prototype) - -Editor.prototype.draw = function({clientX, clientY}={}){ - // event end might trigger clientX = 0 and clientY = 0 - if(clientX == 0 && clientY == 0)return; - - var editorOffsets = this.canvas.getClientRects()[0]; - var dx = clientX - editorOffsets.left - 16; - var dy = clientY - editorOffsets.top - 16; - if(this.prevPoint){ - this.ctx.beginPath(); - this.ctx.strokeStyle = this.color; - this.ctx.moveTo(this.prevPoint.dx, this.prevPoint.dy); - this.ctx.lineWidth = this.strokeWidth; - var xc = (this.prevPoint.dx + dx) / 2; - var yc = (this.prevPoint.dy + dy) / 2; - this.ctx.quadraticCurveTo(xc, yc, dx, dy); - this.ctx.stroke(); - this.ctx.beginPath(); - this.ctx.fillStyle = this.color; - this.ctx.arc(dx, dy, this.strokeWidth*.5, 0, Math.PI * 2, true); - this.ctx.fill(); - } - this.prevPoint = {dx, dy}; -} - -Editor.prototype.handleDrawEvent = function(event){ - event.preventDefault(); - var scope = this; - if(event instanceof MouseEvent){ - this.draw(event); - }else if(event instanceof TouchEvent){ - Array.prototype.forEach.call(event.touches,( t ) => scope.draw(t)) - } -} - -Editor.prototype.setUp = function(){ - var scope = this; - scope.handleDrawEvent = scope.handleDrawEvent.bind(scope); - if(window.innerWidth > 768){ - scope.canvas.addEventListener('mousedown', function(event){ - scope.canvas.addEventListener('mousemove',scope.handleDrawEvent, true) - }) - - scope.canvas.addEventListener('mouseup', function(event){ - scope.canvas.removeEventListener('mousemove',scope.handleDrawEvent, true) - scope.prevPoint = null; - scope.drawEnd(); - }) - }else{ - scope.canvas.addEventListener('touchstart', function(event){ - scope.canvas.addEventListener('touchmove',scope.handleDrawEvent, true) - }) - - scope.canvas.addEventListener('touchend', function(event){ - scope.canvas.removeEventListener('touchmove',scope.handleDrawEvent, true) - scope.prevPoint = null; - scope.drawEnd(); - }) - } -} - -Editor.prototype.setDrawEndCallback = function(callback){ - this.callback = callback; -} - -Editor.prototype.drawEnd = function(){ - if(this.callback != null){ - var image = this.getImage(); - this.callback(image) - } -} - -Editor.prototype.clear = function(){ - var scope = this; - scope.ctx.clearRect(0, 0, scope.canvas.width, scope.canvas.height); - scope.prevPoint = null; -} - -Editor.prototype.getImage = function() { - var cropped = cropToCenter(this.canvas); - return scale(cropped, 28, 28); -}; - -function scale(imgSrc, nwidth, nheight){ - // create a hidden canvas, render the image as 28*28 and then extract data - var hiddenCanvas = document.createElement('canvas'); - hiddenCanvas.width = nwidth; - hiddenCanvas.height = nheight; - var hctx = hiddenCanvas.getContext('2d'); - hctx.drawImage(imgSrc,0, 0, imgSrc.width, imgSrc.height,0, 0, nwidth, nheight); - return hctx.getImageData(0, 0, nwidth, nheight); -} - - -function cropToCenter(imgSrc) { - var imgData = imgSrc.getContext("2d").getImageData(0, 0, imgSrc.width, imgSrc.height) - var { data, width, height } = imgData - - let [xmin, ymin] = [width, height] - let [xmax, ymax] = [-1, -1] - for (var i = 0; i < width; i++) { - for (var j = 0; j < height; j++) { - var idx = i + j * width - if (data[4 * idx + 3] > 0) { - if (i < xmin) xmin = i - if (i > xmax) xmax = i - if (j < ymin) ymin = j - if (j > ymax) ymax = j - } - } - } - - xmin -= 10 - xmax += 10 - ymin -= 10 - ymax += 10 - - let [widthNew, heightNew] = [xmax - xmin + 1, ymax - ymin + 1] - if (widthNew < heightNew) { - var half = Math.floor((heightNew - widthNew) / 2) - xmax += heightNew - widthNew - half - xmin -= half - widthNew = xmax - xmin + 1 - } else if (widthNew > heightNew) { - var half = Math.floor((widthNew - heightNew) / 2) - ymax += widthNew - heightNew - half - ymin -= half - heightNew = ymax - ymin + 1 - } - var dataNew = new Uint8ClampedArray(widthNew * heightNew * 4) - for (var i = xmin; i <= xmax; i++) { - for (var j = ymin; j <= ymax; j++) { - if (i >= 0 && i < width && j >= 0 && j < height) { - var idx = i + j * width - var idxNew = i - xmin + (j - ymin) * widthNew - dataNew[4 * idxNew + 3] = data[4 * idx + 3] - } - } - } - - var nImgData = new ImageData(dataNew, widthNew, heightNew) - var nImgSrc = document.createElement("canvas"); - nImgSrc.height = nImgData.height; - nImgSrc.width = nImgData.width; - nImgSrc.getContext("2d").putImageData(nImgData, 0, 0); - return nImgSrc; - -} - -})(window); \ No newline at end of file diff --git a/experiments/mnist/assets/js/Model.js b/experiments/mnist/assets/js/Model.js deleted file mode 100644 index 1d92e40d..00000000 --- a/experiments/mnist/assets/js/Model.js +++ /dev/null @@ -1,58 +0,0 @@ -(function(obj){ - - Object.assign(obj, {Model}) - - function Model(editor, result, model){ - this.editor = editor; - this.result = result; - this.model = model; - - var scope = this; - this.editor.setDrawEndCallback(callback.bind(scope)) - - function callback(image){ - this.findResult(image) - } - } - - Model.prototype.findResult = function(image){ - var scope = this; - var input = this.blackAndWhite(image.data); - - var output = tf.tidy(() => { - var tensor = tf.tensor(input, [28, 28]).transpose().reshape([1, 1, 28,28]); - return this.model(tensor); - }); - - output.data().then(function(val){ - (scope.showResult.bind(scope))(val); - tf.dispose(output); - }) - } - - // 28*28*4 rgba Unit8 array into 28*28 grayscale Float32Array - Model.prototype.blackAndWhite = function(imageData){ - return ( - (new Float32Array(784)).fill(0.0) - .map((_, i) => imageData[i*4 + 3]) - .map(reduceToGrayScale) - ); - } - - Model.prototype.showResult = function(val){ - this.result.update(val) - } - -})(window) - - -Float32Array.prototype.group = Array.prototype.group = function group(size){ - return this.reduce((acc, e)=>{ - acc.a.push(e); - if(acc.a.length == size){ - acc.b.push(acc.a); - acc.a = [] - } - return acc - }, {a:[], b:[]}).b -} \ No newline at end of file diff --git a/experiments/mnist/assets/js/Result.js b/experiments/mnist/assets/js/Result.js deleted file mode 100644 index dddb1e5a..00000000 --- a/experiments/mnist/assets/js/Result.js +++ /dev/null @@ -1,82 +0,0 @@ -(function(){ - -Object.assign(window, {Result}); - -function Result (ele, - { - labels=[...Array(10).keys()], // default labels from 0 to 9 - max=1, - maxHeight=100, - barWidth=10, - horizontalSpacing=10, - color=getComputedStyle(document.body).getPropertyValue('--medium'), - fontSize=16, - fontFamily="arial", - verticalSpacing=20, - highlight=getComputedStyle(document.body).getPropertyValue('--dark'), - padding=20 - }={}) -{ - this.canvas = ele; - this.ctx = this.canvas.getContext('2d'); - this.labels = labels; - this.max = max; - this.maxHeight = maxHeight; - this.barWidth = barWidth; - this.horizontalSpacing = horizontalSpacing; - this.color = color; - this.fontSize = fontSize; - this.fontFamily = fontFamily; - this.verticalSpacing = verticalSpacing; - this.highlight = highlight; - this.padding = padding; - this.topMargin = this.canvas.height - (2*this.padding + this.fontSize + this.maxHeight + this.verticalSpacing); -} - -Result.prototype.setUp = function(){ - var labelTopOffset = this.topMargin + this.maxHeight + this.verticalSpacing + this.padding; - var labelLeftOffset = this.padding; - this.ctx.fillStyle = this.color; - this.ctx.font = this.fontSize + "px " + this.fontFamily; - - for(var label of this.labels){ - this.ctx.fillText(label, labelLeftOffset, labelTopOffset); - labelLeftOffset += this.barWidth + this.horizontalSpacing; - } -} - -Result.prototype.update = function(values){ - var scope = this; - var max_i = 0; - - scope.ctx.clearRect(0, 0, scope.canvas.width, scope.canvas.height); - this.setUp(); // write the labels again ( remove highlighting ) - - // draw as histogram - values.forEach((val, i)=>{ - fill(val, i, scope.color); - if(val> values[max_i]){ - max_i = i; - } - }) - - // highlight highest bar - fill(values[max_i], max_i, scope.highlight); - var labelTopOffset = this.topMargin + this.maxHeight + this.verticalSpacing + this.padding; - var labelLeftOffset = max_i * ( this.barWidth + this.horizontalSpacing ) + this.padding; - this.ctx.fillStyle = this.highlight; - this.ctx.font = this.fontSize + "px " + this.fontFamily; - this.ctx.fillText(this.labels[max_i], labelLeftOffset, labelTopOffset); - - // for filling each bar - function fill(val, i, color){ - var height = scope.maxHeight * (val/scope.max); - var leftOffset = i*(scope.horizontalSpacing + scope.barWidth) + scope.padding; - var topOffset = scope.topMargin + (scope.maxHeight - height) + scope.padding; - - scope.ctx.fillStyle = color; - scope.ctx.fillRect(leftOffset, topOffset, scope.barWidth, height); - } -} - -})(window) \ No newline at end of file diff --git a/experiments/mnist/assets/js/flux.js b/experiments/mnist/assets/js/flux.js deleted file mode 100644 index f82dec35..00000000 --- a/experiments/mnist/assets/js/flux.js +++ /dev/null @@ -1,99 +0,0 @@ -flux = (function () { - -let Buffer = new BSON().serialize({}).constructor - -function blobAsArrayBuffer(blob) { - return new Promise((resolve, reject) => { - let reader = new FileReader(); - reader.addEventListener("loadend", function() { - resolve(reader.result); - }); - reader.readAsArrayBuffer(blob); - }); -} - -async function fetchBytes(url) { - let resp = await fetch(url); - if (!resp.ok) throw(resp); - let blob = await resp.blob(); - let buf = await blobAsArrayBuffer(blob); - return new Buffer(buf); -} - -async function fetchData(url) { - let buf = await fetchBytes(url); - return new BSON().deserialize(buf); -} - -// `buf` is a Uint8Array from BSON -function readFloat32(buf) { - let view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); - let data = new Float32Array(view.byteLength/4); - for (let i = 0; i < data.length; i++) { - data[i] = view.getFloat32(i*4, true); - } - return data; -} - -function readInt32(buf) { - let view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); - let data = new Int32Array(view.byteLength/4); - for (let i = 0; i < data.length; i++) { - data[i] = view.getInt32(i*4, true); - } - return data; -} - -function toTensor_(spec) { - let type = spec.type.name; - type = type[type.length-1]; - if (type == 'Float32') spec.data = readFloat32(spec.data.buffer); - else if (type == 'Int32') spec.data = readInt32(spec.data.buffer); - else throw `Array type ${spec.type.name} not supported.`; - let array = tf.tensor(spec.data, spec.size.reverse()); - return array -} - -function convertArrays_(data) { - if (!(typeof data == "object")) return data - if (data.tag == "array") { - return toTensor_(data); - } else { - for (let k of Object.keys(data)) { - data[k] = convertArrays_(data[k]) - } - } - return data; -} - -async function fetchBlob(url) { - data = await fetchData(url); - return convertArrays_(data) -} - -async function fetchWeights(url) { - ws = await fetchBlob(url); - return ws.weights; -} - -const _data = t => (t instanceof tf.Tensor)? t.dataSync(): t; -const slice = t => (t instanceof tf.Tensor)? t.clone():( - t instanceof Array ? t.slice() : t); -const iterate = (arr, i=1) => ([arr[i - 1], i + 1]); -function getindex(arr, ...i){ - if(arr instanceof tf.Tensor){ - return arr.dataSync()[i - 1] - }else if(arr instanceof Array){ - return arr[i - 1]; - } -} - -function invindex(arr, ...i){ - if(arr instanceof Array){ - return arr[arr.length - i]; - } -} - -return {fetchData, fetchWeights, fetchBlob, data: _data, slice, convertArrays_, iterate, invindex, getindex}; - -})(); diff --git a/experiments/mnist/assets/js/mnist-conv.js b/experiments/mnist/assets/js/mnist-conv.js deleted file mode 100644 index 1de381dd..00000000 --- a/experiments/mnist/assets/js/mnist-conv.js +++ /dev/null @@ -1,59 +0,0 @@ -let model = (function () { - let math = tf; - model.weights = []; - function starling(sanddollar) { - return sanddollar; - }; - function flamingo(fish) { - return starling(math.add(math.matMul(fish, model.weights[0]), model.weights[1])); - }; - function bat(giraffe) { - return giraffe[String("shape")]; - }; - function cassowary(chinchilla, penguin) { - return (chinchilla[String("size")]/penguin); - }; - function narwhal(seahorse, quetzal) { - return (seahorse*quetzal); - }; - function salmon(donkey) { - let redpanda = flux.invindex(bat(donkey), 4); - return math.reshape(donkey, [redpanda, cassowary(donkey, narwhal(1, redpanda))]); - }; - function monkey(reddeer) { - return math.transpose(math.maxPool(math.transpose(reddeer, [0, 2, 3, 1]), [2, 2], [2, 2], 0, "floor"), [0, 3, 1, 2]); - }; - function quail(cheetah) { - return cheetah; - }; - function echidna(kangaroo) { - return quail(math.relu(math.add(math.transpose(math.conv2d(math.transpose(kangaroo, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[2], [2, 3, 1, 0], kangaroo), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[3]))); - }; - function llama(crow) { - return math.transpose(math.maxPool(math.transpose(crow, [0, 2, 3, 1]), [2, 2], [2, 2], 0, "floor"), [0, 3, 1, 2]); - }; - function baboon(crocodile) { - return crocodile; - }; - function termite(kinkajou) { - return baboon(math.relu(math.add(math.transpose(math.conv2d(math.transpose(kinkajou, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[4], [2, 3, 1, 0], kinkajou), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[5]))); - }; - function snake(kouprey) { - return math.transpose(math.maxPool(math.transpose(kouprey, [0, 2, 3, 1]), [2, 2], [2, 2], 0, "floor"), [0, 3, 1, 2]); - }; - function louse(seal) { - return seal; - }; - function reindeer(lyrebird) { - return louse(math.relu(math.add(math.transpose(math.conv2d(math.transpose(lyrebird, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[6], [2, 3, 1, 0], lyrebird), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[7]))); - }; - function model(elk) { - return math.softmax(flamingo(salmon(monkey(echidna(llama(termite(snake(reindeer(elk))))))))); - }; - model.setWeights = (function (ws) { - model.weights = ws; - return; - }); - return model; -})(); -loadWeights('assets/bson/mnist-conv.bson', document.querySelector('.render_editor'), __init__, model) diff --git a/experiments/mnist/assets/js/mnist-mlp.js b/experiments/mnist/assets/js/mnist-mlp.js deleted file mode 100644 index 390c650e..00000000 --- a/experiments/mnist/assets/js/mnist-mlp.js +++ /dev/null @@ -1,16 +0,0 @@ -let model = (function () { - let math = tf; - function seal(otter) { - return math.add(math.matrixTimesVector(model.weights[0], otter), model.weights[1]); - }; - function hare(snake) { - return math.relu(math.add(math.matrixTimesVector(model.weights[2], snake), model.weights[3])); - }; - function model(kangaroo) { - return math.softmax(seal(hare(kangaroo))); - }; - model.weights = []; - return model; -})(); - -loadWeights('assets/bson/mnist-mlp.bson', document.querySelector('.render_editor'), __init__) \ No newline at end of file diff --git a/experiments/mnist/assets/js/script.js b/experiments/mnist/assets/js/script.js deleted file mode 100644 index 7552bdf3..00000000 --- a/experiments/mnist/assets/js/script.js +++ /dev/null @@ -1,62 +0,0 @@ -var editor, result; - -// initial setup -function __init__(){ - editor = new Editor(document.querySelector("#editor")); - editor.setUp(); - - result = new Result(document.querySelector("#result")); - result.setUp(); - - document.querySelector("#clearEditor").addEventListener('click', function(){ - editor.clear(); - }); - - model = new Model(editor, result, model); -} - -// draw a number from grayscale float data -function drawImage(numberCanvas, data){ - var ctx = numberCanvas.getContext('2d'); - ctx.clearRect(0, 0, 28, 28); - var rgbaArray = floatToUint8Clamped(data.map(i=> i*255)); - var imgData = ctx.createImageData(28,28); - imgData.data.map((e, i)=>{ - imgData.data[i] = rgbaArray[i]; - }) - ctx.putImageData(imgData, 0, 0); - return [imgData.width, imgData.height]; -} - -//convert float array into rgba Unit8ClampedArray -function floatToUint8Clamped(floatArray){ - var uint8Array = new Uint8ClampedArray(floatArray); - var rgbaArray = new Uint8ClampedArray(uint8Array.length * 4); - uint8Array.forEach((e, i)=>{ - rgbaArray[i*4] = e; - rgbaArray[i*4 + 1] = e; - rgbaArray[i*4 + 2] = e; - rgbaArray[i*4 + 3] = 255; - }) - return rgbaArray; -} - -// invert color value -function invertColor(color){ - return 255 - color -} - -// grayscale for mnist classifier -function reduceToGrayScale(i){ - return i/255; -} - -// returns index in the transposed matrix -function transpose(i, row, col){ - return ((i%col)*row + Math.floor(i/row)) -} - -// for reverse traversal -function reverse(i, size){ - return size - i - 1; -} diff --git a/experiments/mnist/index.html b/experiments/mnist/index.html deleted file mode 100644 index b15f2852..00000000 --- a/experiments/mnist/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -layout: default ---- - - - - - - - - -
-
-

Flux Experiment: MNIST Classifier

-
-
-
-
- -
- - -
-
-
- -
-
-
- -
-
-
- - - - - - - - - - diff --git a/experiments/pong/assets/js/Board.js b/experiments/pong/assets/js/Board.js deleted file mode 100644 index 12c8f573..00000000 --- a/experiments/pong/assets/js/Board.js +++ /dev/null @@ -1,15 +0,0 @@ -function Board(container, {env}={}){ - this.container = container - this.render = ()=>{ - env.render(); - if(env.done()){ - show($$(".overlay #gameOver")) - }else{ - hide($$(".overlay #gameOver")) - } - }; - - this.removeStartScreen = ()=>{ - hide($$(".overlay #start")); - } -} diff --git a/experiments/pong/assets/js/Pong.js b/experiments/pong/assets/js/Pong.js deleted file mode 100644 index 1671233f..00000000 --- a/experiments/pong/assets/js/Pong.js +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************** -======================================================= -Pong Game -======================================================= -******************************************************/ -function Pong(canvas,{width=500, height=400, paddle_width=10, paddle_height=50, ball_radius=5}={}){ - var score = 0; - canvas.width = width; - canvas.height = height; - var components = { - - paddles: new PaddleCollection( - [ - new Vector(0, Math.floor(height/2)), - new Vector(width-paddle_width, Math.floor(height/2)) - ], { - width:paddle_width, - height:paddle_height, - total_height: height, - color: "#fff" - }), - ball: new Ball(new Vector(Math.floor(width/2), Math.floor(height/2)), new Vector(5, 0), {radius:ball_radius, color: "#fff"}) - } - - var paddleController = new PaddleController(components.paddles.collection[0]); - - this.draw = ()=>{ - var ctx = canvas.getContext('2d'); - //background - ctx.fillStyle = "#000"; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - ctx.strokeStyle = "#fff"; - ctx.lineWidth = 5; - ctx.beginPath(); - ctx.setLineDash([10, 15]); - ctx.moveTo(width/2, 0); - ctx.lineTo(width/2, height); - ctx.stroke(); - - for( var c in components){ - components[c].draw(canvas); - } - - ctx.fillStyle = "#fff"; - ctx.font = "48px sans-serif" - ctx.textBaseline = "top"; - ctx.textAlign = "right"; - ctx.fillText(components.paddles.collection[0].score, width/2 - 20, 20); - ctx.textAlign = "left"; - ctx.fillText(components.paddles.collection[1].score, width/2 + 20, 20); - } - - - this.play = ()=>{ - score += this.step(); - if(!this.done()) - requestAnimationFrame(this.play); - } - - this.step = (dir)=>{ - components.ball.move(); - - this.action(1, dir); - paddleController.next(components.ball); - this.movePaddles(); - - this.collisionDetector(); - this.draw(); - - if(components.ball.pos.x < 0) { - components.paddles.incScore(1); - return 1; - } - if(components.ball.pos.x > width){ - components.paddles.incScore(0); - return -1; - } - return 0; - } - - this.collisionDetector = function(){ - var ball = components.ball; - - var paddleHit = components.paddles.detectCollision(ball); // collision with paddle - if(paddleHit){ - paddleHit.rebound(ball); - } - var wallHit = components.ball.detectCollision(width, height); // collision with walls - wallHit.forEach(w=> ball.rebound(w)); - - } - - this.done = function(){ - var cond = components.ball.pos.x < 0 || components.ball.pos.x > width; - return cond; - } - - this.movePaddles = ()=> components.paddles.move(); - - this.action = (id, dir)=>{ - // console.log(id, dir) - components.paddles.setDirection(id, dir); - } - - this.reset = () => { - components.ball.pos.x = Math.floor(width/2); - components.ball.pos.y = Math.floor(height/2); - components.ball.speed.x = Math.sign(components.ball.speed.x)*5; - components.ball.speed.y = 0; - } - - this.render = this.draw; - this.config = ()=>{return null}; -} \ No newline at end of file diff --git a/experiments/pong/assets/js/components.js b/experiments/pong/assets/js/components.js deleted file mode 100644 index 73c9e258..00000000 --- a/experiments/pong/assets/js/components.js +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************** -======================================================= -Components -======================================================= -******************************************************/ - -function PaddleCollection(positions, config){ - this.collection = positions.map(e=>new Paddle(e, config)); - - this.move = ()=>{ - this.collection.forEach(p => p.move()); - } - - this.setDirection = (id, dir)=>{ - this.collection[id].setDirection(dir); - } - - this.detectCollision = (ball)=>{ - for (var paddle of this.collection) - if(paddle.detectCollision(ball))return paddle; - - return null; - } - - this.draw = (canvas)=>{ - this.collection.forEach(paddle=>paddle.draw(canvas)); - } - - this.incScore = (id)=>{ - this.collection[id].score += 1; - } -} - - -function PaddleController(paddle){ - - this.next = (ball)=>{ - if(Math.sign(ball.pos.x - paddle.pos.x) == Math.sign(ball.speed.x))return; // ball is moving away - - if(ball.pos.y >= paddle.pos.y && ball.pos.y <= paddle.pos.y + paddle.height) - return paddle.setDirection(0) - - var dir = Math.sign(ball.pos.y - paddle.height/2 - paddle.pos.y); - paddle.setDirection(dir); - } -} - -/*** overriding a few functions ***/ -Ball.prototype.detectCollision = function(width, height) { // with top & bottom walls - var collisions = []; - if(this.pos.y - this.radius < 0 || this.pos.y + this.radius > height)collisions.push([1, -1]); - - return collisions; -}; - -Paddle.prototype.move = function (){ - this.pos.add(new Vector(0, this.dir*5)); - if(this.pos.y < 0)this.pos.y = 0; - else if(this.pos.y + this.height > this.total_height) this.pos.y = this.total_height - this.height; -} - -Paddle.prototype.detectCollision = function (ball) { - if(ball.pos.x + ball.radius > this.pos.x && ball.pos.y + ball.radius > this.pos.y && ball.pos.x < this.pos.x + this.width && ball.pos.y - ball.radius < this.pos.y + this.height){ - return this - } - return null -} - -Paddle.prototype.rebound = function (ball){ - var diff = this.pos.y + this.height/2 - ball.pos.y; - ball.rebound([-1, 1]); - ball.speed.x += Math.sign(ball.speed.x); - ball.speed.y = ball.speed.x*diff/this.height; -} - -Paddle.prototype.score = 0; \ No newline at end of file diff --git a/experiments/pong/assets/js/script.js b/experiments/pong/assets/js/script.js deleted file mode 100644 index b3581ab3..00000000 --- a/experiments/pong/assets/js/script.js +++ /dev/null @@ -1,33 +0,0 @@ -(function(){ - - var env = new Pong(document.querySelector("#playground")); - var board = new Board(document.querySelector(".board"), {env}); - var game = new Game(env, board, null); - - document.addEventListener('keydown', event => { - - var code = event.keyCode; - - if(code == 13){ - board.removeStartScreen(); - return game.play(); - } - - if(code == 38 || code == 40){ - event.preventDefault(); - game.action(code - 39); - return; - } - }) - - document.addEventListener('keyup', event => { - var code = event.keyCode; - - if(code == 38 || code == 40){ - game.action(0); - return; - } - }) - - env.draw(); -})() \ No newline at end of file diff --git a/experiments/pong/index.html b/experiments/pong/index.html deleted file mode 100644 index 9dc7991f..00000000 --- a/experiments/pong/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -layout: default -game: pong ---- - -{% include experiments/game/headers.html %} - -{% assign game = site.data.experiments[page.game] %} -{% include experiments/game/content.html game=game %} - - -{% include experiments/game/footer.html %} - - - - - - - \ No newline at end of file diff --git a/experiments/styleTransfer/assets/bson/abstract_art_fluxjs.bson b/experiments/styleTransfer/assets/bson/abstract_art_fluxjs.bson deleted file mode 100644 index 435e7559..00000000 Binary files a/experiments/styleTransfer/assets/bson/abstract_art_fluxjs.bson and /dev/null differ diff --git a/experiments/styleTransfer/assets/bson/popsty_fluxjs.bson b/experiments/styleTransfer/assets/bson/popsty_fluxjs.bson deleted file mode 100644 index 48647d91..00000000 Binary files a/experiments/styleTransfer/assets/bson/popsty_fluxjs.bson and /dev/null differ diff --git a/experiments/styleTransfer/assets/bson/starry_night_fluxjs.bson b/experiments/styleTransfer/assets/bson/starry_night_fluxjs.bson deleted file mode 100644 index e71c9617..00000000 Binary files a/experiments/styleTransfer/assets/bson/starry_night_fluxjs.bson and /dev/null differ diff --git a/experiments/styleTransfer/assets/css/style.css b/experiments/styleTransfer/assets/css/style.css deleted file mode 100644 index 46d66dfd..00000000 --- a/experiments/styleTransfer/assets/css/style.css +++ /dev/null @@ -1,238 +0,0 @@ -.tree{ - margin: 50px; -} - -h4{ - line-height: 2em; -} - -.level{ - /*min-height: 100px;*/ - /*background: #ebf5eb;*/ - margin: 0 10px; - display: flex; - -webkit-justify-content: center; - justify-content: center; - - /*height: 50%;*/ -} - -.tree .level:nth-of-type(2) img, -.tree .level:nth-of-type(4) img{ - width: 200px; - height: 200px; - border: none; - box-shadow: none; - outline: none; - background: #ddd; - border-radius: 3px; -} - -.element{ - min-height: 300px; - /*min-width: 300px;*/ - - margin: 0 10px; - border-radius: 6px; - position: relative; - display: flex; - justify-content: center; - align-items: flex-end; -} - -.sibling{ - display: flex; - flex-direction: column; - justify-content: center; - -} - -.connector{ - min-height: 100px; - position:relative; - margin: 0 10px; - flex:2; -} - -.connector *{ - position: absolute; - background: #aaa; - transition: all .4s linear; -} - -.connector.two div:first-child{ - width: 50%; - height: 2px; - left: 25%; - top: 50%; -} - -.connector.two div:nth-child(2){ - width: 2px; - height: 50%; - left: 25%; - top: 0; -} - -.connector.two div:nth-child(3){ - width: 2px; - height: 50%; - left: 75%; - top: 0; -} - -.connector.two div:nth-child(4){ - width: 2px; - height: 50%; - left: 50%; - top: 50%; -} - -.connector.one div{ - width: 2px; - height: 100%; - left: 50%; - top: 0; -} - - -.select_style ul{ - display: flex; - justify-content: center; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - flex-wrap: wrap; - padding: 0; - margin: 0; -} - -.select_style li{ - margin: 5px 3px; - padding:0; - flex: 1; - text-align: center; - background: transparent; - cursor: pointer; - width: fit-content; -} - -.select_style img{ - width: 70px; - height: 70px; - /*border: 5px solid transparent;*/ -} - - -.pane{ - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-justify-content: center; - justify-content: center; - -webkit-align-items: center; - align-items: center; - height: fit-content; - padding: 20px; - background: var(--light); -} - -.pane.disabled { - background: #dddddd; -} - -.pane.disabled video{ - background: #eeeeee; -} - -.pretty_button{ - border-radius: 3px; - border: none; - background: #fff; - margin: 10px 0; - padding: 10px; - cursor: pointer; -} - -.pretty_button.disabled{ - cursor: initial; -} - -.pretty_button:not(.disabled), -.select_style img{ - transition: all .4s linear; - box-shadow: 2px 2px 5px #333; -} - -.pretty_button:not(.disabled):active, -.pretty_button:not(.disabled):focus{ - outline: none; - border: none; - box-shadow: none; -} - -.pretty_button:not(.disabled):hover, -.select_style li:hover img{ - box-shadow: 0px 0px 0px #333; - transform: translate(2px, 2px); -} - - -.down{ - margin: 30px 5px 10px !important; -} - -.fade.in{ - opacity: 1; -} - -.msg{ - text-align: center; -} - -li{ - list-style: none; -} - -.tree[green=true] .connector *{ - box-shadow: 2px 2px 2px var(--medium); -} -.pane{ - border: 1px solid transparent; - transition: all .4s linear; -} - -.tree[green=true] .pane{ - border: 1px solid var(--medium); -} - -@media only screen and (max-width: 768px){ - .connector{ - display: none; - } - - .w-50{ - width: 100% !important; - } - - .tree{ - margin: 20px 5px; - } - - .level{ - flex-direction:column; - } - .element{ - min-height: 0px; - margin: 10px 0 !important; - } - - .pane{ - width: 100%; - } - - .select_style ul{ - flex-direction: column; - } -} \ No newline at end of file diff --git a/experiments/styleTransfer/assets/img/abstract.jpg b/experiments/styleTransfer/assets/img/abstract.jpg deleted file mode 100644 index f348d79c..00000000 Binary files a/experiments/styleTransfer/assets/img/abstract.jpg and /dev/null differ diff --git a/experiments/styleTransfer/assets/img/popsty.jpg b/experiments/styleTransfer/assets/img/popsty.jpg deleted file mode 100644 index 8ea6ca12..00000000 Binary files a/experiments/styleTransfer/assets/img/popsty.jpg and /dev/null differ diff --git a/experiments/styleTransfer/assets/img/starry-night.jpg b/experiments/styleTransfer/assets/img/starry-night.jpg deleted file mode 100644 index f5fdd1fc..00000000 Binary files a/experiments/styleTransfer/assets/img/starry-night.jpg and /dev/null differ diff --git a/experiments/styleTransfer/assets/img/weeping-woman.jpg b/experiments/styleTransfer/assets/img/weeping-woman.jpg deleted file mode 100644 index 3864edc7..00000000 Binary files a/experiments/styleTransfer/assets/img/weeping-woman.jpg and /dev/null differ diff --git a/experiments/styleTransfer/assets/js/fluxjs/abstract_art_fluxjs.js b/experiments/styleTransfer/assets/js/fluxjs/abstract_art_fluxjs.js deleted file mode 100644 index aaf66e0a..00000000 --- a/experiments/styleTransfer/assets/js/fluxjs/abstract_art_fluxjs.js +++ /dev/null @@ -1,221 +0,0 @@ -let abstract_art = (function () { - let math = tf; - function rhinoceros(koala) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(koala, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[0], [2, 3, 1, 0], koala), [0, 1]), flux.ctOutSize(koala, model.weights[1], [1, 1], [1, 1], [1, 1], [0, 0]), [1, 1], 1, "floor"), [0, 3, 1, 2]), model.weights[2]); - }; - let walrus = math.tensor(1.0e-5); - function turkey(porcupine) { - let guineafowl = porcupine[String("shape")][String("length")]; - let bison = [].fill.apply(Array(guineafowl), [1]); - let squirrel = [].concat.call(flux.range(1, (guineafowl-2)), guineafowl); - let eland = math.mean(porcupine, [(porcupine[String("shape")][String("length")]-squirrel[0]), (porcupine[String("shape")][String("length")]-squirrel[1]), (porcupine[String("shape")][String("length")]-squirrel[2])], true); - let flamingo = math.pow(math.sub(porcupine, eland), model.weights[4]); - bison[(guineafowl-2)] = porcupine[String("shape")][(porcupine[String("shape")][String("length")]-(guineafowl-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[3], [bison[3], bison[2], bison[1], bison[0]]), math.div(math.sub(porcupine, eland), tf.sqrt(math.add(math.mean(flamingo, [(flamingo[String("shape")][String("length")]-squirrel[0]), (flamingo[String("shape")][String("length")]-squirrel[1]), (flamingo[String("shape")][String("length")]-squirrel[2])], true), walrus)))), math.reshape(model.weights[5], [bison[3], bison[2], bison[1], bison[0]]))); - }; - function tapir(donkey) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(donkey, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[6], [2, 3, 1, 0], donkey), [0, 1]), flux.ctOutSize(donkey, model.weights[7], [2, 2], [1, 1], [1, 1], [1, 1]), [2, 2], 1, "floor"), [0, 3, 1, 2]), model.weights[8]); - }; - let shrew = math.tensor(1.0e-5); - function yak(dog) { - let butterfly = dog[String("shape")][String("length")]; - let gnu = [].fill.apply(Array(butterfly), [1]); - let quetzal = [].concat.call(flux.range(1, (butterfly-2)), butterfly); - let skunk = math.mean(dog, [(dog[String("shape")][String("length")]-quetzal[0]), (dog[String("shape")][String("length")]-quetzal[1]), (dog[String("shape")][String("length")]-quetzal[2])], true); - let cassowary = math.pow(math.sub(dog, skunk), model.weights[10]); - gnu[(butterfly-2)] = dog[String("shape")][(dog[String("shape")][String("length")]-(butterfly-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[9], [gnu[3], gnu[2], gnu[1], gnu[0]]), math.div(math.sub(dog, skunk), tf.sqrt(math.add(math.mean(cassowary, [(cassowary[String("shape")][String("length")]-quetzal[0]), (cassowary[String("shape")][String("length")]-quetzal[1]), (cassowary[String("shape")][String("length")]-quetzal[2])], true), shrew)))), math.reshape(model.weights[11], [gnu[3], gnu[2], gnu[1], gnu[0]]))); - }; - function waterbuffalo(nightingale) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(nightingale, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[12], [2, 3, 1, 0], nightingale), [0, 1]), flux.ctOutSize(nightingale, model.weights[13], [2, 2], [1, 1], [1, 1], [1, 1]), [2, 2], 1, "floor"), [0, 3, 1, 2]), model.weights[14]); - }; - let penguin = math.tensor(1.0e-5); - function lobster(curlew) { - let mandrill = curlew[String("shape")][String("length")]; - let toad = [].fill.apply(Array(mandrill), [1]); - let polarbear = [].concat.call(flux.range(1, (mandrill-2)), mandrill); - let lion = math.mean(curlew, [(curlew[String("shape")][String("length")]-polarbear[0]), (curlew[String("shape")][String("length")]-polarbear[1]), (curlew[String("shape")][String("length")]-polarbear[2])], true); - let moose = math.pow(math.sub(curlew, lion), model.weights[16]); - toad[(mandrill-2)] = curlew[String("shape")][(curlew[String("shape")][String("length")]-(mandrill-1))]; - return math.add(math.mul(math.reshape(model.weights[15], [toad[3], toad[2], toad[1], toad[0]]), math.div(math.sub(curlew, lion), tf.sqrt(math.add(math.mean(moose, [(moose[String("shape")][String("length")]-polarbear[0]), (moose[String("shape")][String("length")]-polarbear[1]), (moose[String("shape")][String("length")]-polarbear[2])], true), penguin)))), math.reshape(model.weights[17], [toad[3], toad[2], toad[1], toad[0]])); - }; - function raven(starling) { - return math.add(math.transpose(math.conv2d(math.transpose(starling, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[18], [2, 3, 1, 0], starling), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[19]); - }; - let gull = math.tensor(1.0e-5); - function zebra(crane) { - let crocodile = crane[String("shape")][String("length")]; - let mosquito = [].fill.apply(Array(crocodile), [1]); - let ape = [].concat.call(flux.range(1, (crocodile-2)), crocodile); - let lapwing = math.mean(crane, [(crane[String("shape")][String("length")]-ape[0]), (crane[String("shape")][String("length")]-ape[1]), (crane[String("shape")][String("length")]-ape[2])], true); - let goosander = math.pow(math.sub(crane, lapwing), model.weights[21]); - mosquito[(crocodile-2)] = crane[String("shape")][(crane[String("shape")][String("length")]-(crocodile-1))]; - return math.add(math.mul(math.reshape(model.weights[20], [mosquito[3], mosquito[2], mosquito[1], mosquito[0]]), math.div(math.sub(crane, lapwing), tf.sqrt(math.add(math.mean(goosander, [(goosander[String("shape")][String("length")]-ape[0]), (goosander[String("shape")][String("length")]-ape[1]), (goosander[String("shape")][String("length")]-ape[2])], true), gull)))), math.reshape(model.weights[22], [mosquito[3], mosquito[2], mosquito[1], mosquito[0]])); - }; - function goldfinch(dogfish) { - return math.add(math.transpose(math.conv2d(math.transpose(dogfish, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[23], [2, 3, 1, 0], dogfish), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[24]); - }; - function giraffe(komodo) { - return math.add(komodo, lobster(raven(math.relu(zebra(goldfinch(komodo)))))); - }; - let chamois = math.tensor(1.0e-5); - function tiger(sardine) { - let hare = sardine[String("shape")][String("length")]; - let caribou = [].fill.apply(Array(hare), [1]); - let ram = [].concat.call(flux.range(1, (hare-2)), hare); - let sheep = math.mean(sardine, [(sardine[String("shape")][String("length")]-ram[0]), (sardine[String("shape")][String("length")]-ram[1]), (sardine[String("shape")][String("length")]-ram[2])], true); - let snail = math.pow(math.sub(sardine, sheep), model.weights[26]); - caribou[(hare-2)] = sardine[String("shape")][(sardine[String("shape")][String("length")]-(hare-1))]; - return math.add(math.mul(math.reshape(model.weights[25], [caribou[3], caribou[2], caribou[1], caribou[0]]), math.div(math.sub(sardine, sheep), tf.sqrt(math.add(math.mean(snail, [(snail[String("shape")][String("length")]-ram[0]), (snail[String("shape")][String("length")]-ram[1]), (snail[String("shape")][String("length")]-ram[2])], true), chamois)))), math.reshape(model.weights[27], [caribou[3], caribou[2], caribou[1], caribou[0]])); - }; - function sandpiper(lyrebird) { - return math.add(math.transpose(math.conv2d(math.transpose(lyrebird, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[28], [2, 3, 1, 0], lyrebird), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[29]); - }; - let wildebeest = math.tensor(1.0e-5); - function emu(pheasant) { - let guanaco = pheasant[String("shape")][String("length")]; - let anteater = [].fill.apply(Array(guanaco), [1]); - let salmon = [].concat.call(flux.range(1, (guanaco-2)), guanaco); - let mouse = math.mean(pheasant, [(pheasant[String("shape")][String("length")]-salmon[0]), (pheasant[String("shape")][String("length")]-salmon[1]), (pheasant[String("shape")][String("length")]-salmon[2])], true); - let manatee = math.pow(math.sub(pheasant, mouse), model.weights[31]); - anteater[(guanaco-2)] = pheasant[String("shape")][(pheasant[String("shape")][String("length")]-(guanaco-1))]; - return math.add(math.mul(math.reshape(model.weights[30], [anteater[3], anteater[2], anteater[1], anteater[0]]), math.div(math.sub(pheasant, mouse), tf.sqrt(math.add(math.mean(manatee, [(manatee[String("shape")][String("length")]-salmon[0]), (manatee[String("shape")][String("length")]-salmon[1]), (manatee[String("shape")][String("length")]-salmon[2])], true), wildebeest)))), math.reshape(model.weights[32], [anteater[3], anteater[2], anteater[1], anteater[0]])); - }; - function jay(quail) { - return math.add(math.transpose(math.conv2d(math.transpose(quail, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[33], [2, 3, 1, 0], quail), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[34]); - }; - function dragonfly(sealion) { - return math.add(sealion, tiger(sandpiper(math.relu(emu(jay(sealion)))))); - }; - let raccoon = math.tensor(1.0e-5); - function okapi(swan) { - let mink = swan[String("shape")][String("length")]; - let duck = [].fill.apply(Array(mink), [1]); - let heron = [].concat.call(flux.range(1, (mink-2)), mink); - let chough = math.mean(swan, [(swan[String("shape")][String("length")]-heron[0]), (swan[String("shape")][String("length")]-heron[1]), (swan[String("shape")][String("length")]-heron[2])], true); - let jaguar = math.pow(math.sub(swan, chough), model.weights[36]); - duck[(mink-2)] = swan[String("shape")][(swan[String("shape")][String("length")]-(mink-1))]; - return math.add(math.mul(math.reshape(model.weights[35], [duck[3], duck[2], duck[1], duck[0]]), math.div(math.sub(swan, chough), tf.sqrt(math.add(math.mean(jaguar, [(jaguar[String("shape")][String("length")]-heron[0]), (jaguar[String("shape")][String("length")]-heron[1]), (jaguar[String("shape")][String("length")]-heron[2])], true), raccoon)))), math.reshape(model.weights[37], [duck[3], duck[2], duck[1], duck[0]])); - }; - function monkey(chimpanzee) { - return math.add(math.transpose(math.conv2d(math.transpose(chimpanzee, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[38], [2, 3, 1, 0], chimpanzee), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[39]); - }; - let octopus = math.tensor(1.0e-5); - function wasp(oyster) { - let locust = oyster[String("shape")][String("length")]; - let ibis = [].fill.apply(Array(locust), [1]); - let wallaby = [].concat.call(flux.range(1, (locust-2)), locust); - let jackal = math.mean(oyster, [(oyster[String("shape")][String("length")]-wallaby[0]), (oyster[String("shape")][String("length")]-wallaby[1]), (oyster[String("shape")][String("length")]-wallaby[2])], true); - let gnat = math.pow(math.sub(oyster, jackal), model.weights[41]); - ibis[(locust-2)] = oyster[String("shape")][(oyster[String("shape")][String("length")]-(locust-1))]; - return math.add(math.mul(math.reshape(model.weights[40], [ibis[3], ibis[2], ibis[1], ibis[0]]), math.div(math.sub(oyster, jackal), tf.sqrt(math.add(math.mean(gnat, [(gnat[String("shape")][String("length")]-wallaby[0]), (gnat[String("shape")][String("length")]-wallaby[1]), (gnat[String("shape")][String("length")]-wallaby[2])], true), octopus)))), math.reshape(model.weights[42], [ibis[3], ibis[2], ibis[1], ibis[0]])); - }; - function kouprey(hummingbird) { - return math.add(math.transpose(math.conv2d(math.transpose(hummingbird, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[43], [2, 3, 1, 0], hummingbird), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[44]); - }; - function termite(otter) { - return math.add(otter, okapi(monkey(math.relu(wasp(kouprey(otter)))))); - }; - let fish = math.tensor(1.0e-5); - function cat(goshawk) { - let seal = goshawk[String("shape")][String("length")]; - let louse = [].fill.apply(Array(seal), [1]); - let ibex = [].concat.call(flux.range(1, (seal-2)), seal); - let cockroach = math.mean(goshawk, [(goshawk[String("shape")][String("length")]-ibex[0]), (goshawk[String("shape")][String("length")]-ibex[1]), (goshawk[String("shape")][String("length")]-ibex[2])], true); - let eel = math.pow(math.sub(goshawk, cockroach), model.weights[46]); - louse[(seal-2)] = goshawk[String("shape")][(goshawk[String("shape")][String("length")]-(seal-1))]; - return math.add(math.mul(math.reshape(model.weights[45], [louse[3], louse[2], louse[1], louse[0]]), math.div(math.sub(goshawk, cockroach), tf.sqrt(math.add(math.mean(eel, [(eel[String("shape")][String("length")]-ibex[0]), (eel[String("shape")][String("length")]-ibex[1]), (eel[String("shape")][String("length")]-ibex[2])], true), fish)))), math.reshape(model.weights[47], [louse[3], louse[2], louse[1], louse[0]])); - }; - function prairiedog(dolphin) { - return math.add(math.transpose(math.conv2d(math.transpose(dolphin, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[48], [2, 3, 1, 0], dolphin), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[49]); - }; - let kangaroo = math.tensor(1.0e-5); - function elk(falcon) { - let alpaca = falcon[String("shape")][String("length")]; - let caterpillar = [].fill.apply(Array(alpaca), [1]); - let panda = [].concat.call(flux.range(1, (alpaca-2)), alpaca); - let beaver = math.mean(falcon, [(falcon[String("shape")][String("length")]-panda[0]), (falcon[String("shape")][String("length")]-panda[1]), (falcon[String("shape")][String("length")]-panda[2])], true); - let boar = math.pow(math.sub(falcon, beaver), model.weights[51]); - caterpillar[(alpaca-2)] = falcon[String("shape")][(falcon[String("shape")][String("length")]-(alpaca-1))]; - return math.add(math.mul(math.reshape(model.weights[50], [caterpillar[3], caterpillar[2], caterpillar[1], caterpillar[0]]), math.div(math.sub(falcon, beaver), tf.sqrt(math.add(math.mean(boar, [(boar[String("shape")][String("length")]-panda[0]), (boar[String("shape")][String("length")]-panda[1]), (boar[String("shape")][String("length")]-panda[2])], true), kangaroo)))), math.reshape(model.weights[52], [caterpillar[3], caterpillar[2], caterpillar[1], caterpillar[0]])); - }; - function peafowl(cod) { - return math.add(math.transpose(math.conv2d(math.transpose(cod, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[53], [2, 3, 1, 0], cod), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[54]); - }; - function ferret(wombat) { - return math.add(wombat, cat(prairiedog(math.relu(elk(peafowl(wombat)))))); - }; - let dunlin = math.tensor(1.0e-5); - function donkey(kudu) { - let aardvark = kudu[String("shape")][String("length")]; - let elephant = [].fill.apply(Array(aardvark), [1]); - let bat = [].concat.call(flux.range(1, (aardvark-2)), aardvark); - let magpie = math.mean(kudu, [(kudu[String("shape")][String("length")]-bat[0]), (kudu[String("shape")][String("length")]-bat[1]), (kudu[String("shape")][String("length")]-bat[2])], true); - let pelican = math.pow(math.sub(kudu, magpie), model.weights[56]); - elephant[(aardvark-2)] = kudu[String("shape")][(kudu[String("shape")][String("length")]-(aardvark-1))]; - return math.add(math.mul(math.reshape(model.weights[55], [elephant[3], elephant[2], elephant[1], elephant[0]]), math.div(math.sub(kudu, magpie), tf.sqrt(math.add(math.mean(pelican, [(pelican[String("shape")][String("length")]-bat[0]), (pelican[String("shape")][String("length")]-bat[1]), (pelican[String("shape")][String("length")]-bat[2])], true), dunlin)))), math.reshape(model.weights[57], [elephant[3], elephant[2], elephant[1], elephant[0]])); - }; - function bee(seahorse) { - return math.add(math.transpose(math.conv2d(math.transpose(seahorse, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[58], [2, 3, 1, 0], seahorse), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[59]); - }; - let loris = math.tensor(1.0e-5); - function tarsier(fox) { - let salamander = fox[String("shape")][String("length")]; - let hedgehog = [].fill.apply(Array(salamander), [1]); - let mammoth = [].concat.call(flux.range(1, (salamander-2)), salamander); - let crab = math.mean(fox, [(fox[String("shape")][String("length")]-mammoth[0]), (fox[String("shape")][String("length")]-mammoth[1]), (fox[String("shape")][String("length")]-mammoth[2])], true); - let ant = math.pow(math.sub(fox, crab), model.weights[61]); - hedgehog[(salamander-2)] = fox[String("shape")][(fox[String("shape")][String("length")]-(salamander-1))]; - return math.add(math.mul(math.reshape(model.weights[60], [hedgehog[3], hedgehog[2], hedgehog[1], hedgehog[0]]), math.div(math.sub(fox, crab), tf.sqrt(math.add(math.mean(ant, [(ant[String("shape")][String("length")]-mammoth[0]), (ant[String("shape")][String("length")]-mammoth[1]), (ant[String("shape")][String("length")]-mammoth[2])], true), loris)))), math.reshape(model.weights[62], [hedgehog[3], hedgehog[2], hedgehog[1], hedgehog[0]])); - }; - function eagle(horse) { - return math.add(math.transpose(math.conv2d(math.transpose(horse, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[63], [2, 3, 1, 0], horse), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[64]); - }; - function goose(partridge) { - return math.add(partridge, donkey(bee(math.relu(tarsier(eagle(partridge)))))); - }; - let gerbil = math.tensor(1.0e-5); - function chinchilla(rook) { - let lark = rook[String("shape")][String("length")]; - let barracuda = [].fill.apply(Array(lark), [1]); - let herring = [].concat.call(flux.range(1, (lark-2)), lark); - let antelope = math.mean(rook, [(rook[String("shape")][String("length")]-herring[0]), (rook[String("shape")][String("length")]-herring[1]), (rook[String("shape")][String("length")]-herring[2])], true); - let mongoose = math.pow(math.sub(rook, antelope), model.weights[66]); - barracuda[(lark-2)] = rook[String("shape")][(rook[String("shape")][String("length")]-(lark-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[65], [barracuda[3], barracuda[2], barracuda[1], barracuda[0]]), math.div(math.sub(rook, antelope), tf.sqrt(math.add(math.mean(mongoose, [(mongoose[String("shape")][String("length")]-herring[0]), (mongoose[String("shape")][String("length")]-herring[1]), (mongoose[String("shape")][String("length")]-herring[2])], true), gerbil)))), math.reshape(model.weights[67], [barracuda[3], barracuda[2], barracuda[1], barracuda[0]]))); - }; - function narwhal(chicken) { - return math.add(math.transpose(math.conv2d(math.transpose(chicken, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[68], [2, 3, 1, 0], chicken), [0, 1]), [2, 2], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[69]); - }; - let hippopotamus = math.tensor(1.0e-5); - function coyote(finch) { - let reddeer = finch[String("shape")][String("length")]; - let cobra = [].fill.apply(Array(reddeer), [1]); - let pigeon = [].concat.call(flux.range(1, (reddeer-2)), reddeer); - let reindeer = math.mean(finch, [(finch[String("shape")][String("length")]-pigeon[0]), (finch[String("shape")][String("length")]-pigeon[1]), (finch[String("shape")][String("length")]-pigeon[2])], true); - let cormorant = math.pow(math.sub(finch, reindeer), model.weights[71]); - cobra[(reddeer-2)] = finch[String("shape")][(finch[String("shape")][String("length")]-(reddeer-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[70], [cobra[3], cobra[2], cobra[1], cobra[0]]), math.div(math.sub(finch, reindeer), tf.sqrt(math.add(math.mean(cormorant, [(cormorant[String("shape")][String("length")]-pigeon[0]), (cormorant[String("shape")][String("length")]-pigeon[1]), (cormorant[String("shape")][String("length")]-pigeon[2])], true), hippopotamus)))), math.reshape(model.weights[72], [cobra[3], cobra[2], cobra[1], cobra[0]]))); - }; - function gaur(weasel) { - return math.add(math.transpose(math.conv2d(math.transpose(weasel, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[73], [2, 3, 1, 0], weasel), [0, 1]), [2, 2], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[74]); - }; - let opossum = math.tensor(1.0e-5); - function fly(sloth) { - let whale = sloth[String("shape")][String("length")]; - let leopard = [].fill.apply(Array(whale), [1]); - let camel = [].concat.call(flux.range(1, (whale-2)), whale); - let cheetah = math.mean(sloth, [(sloth[String("shape")][String("length")]-camel[0]), (sloth[String("shape")][String("length")]-camel[1]), (sloth[String("shape")][String("length")]-camel[2])], true); - let pony = math.pow(math.sub(sloth, cheetah), model.weights[76]); - leopard[(whale-2)] = sloth[String("shape")][(sloth[String("shape")][String("length")]-(whale-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[75], [leopard[3], leopard[2], leopard[1], leopard[0]]), math.div(math.sub(sloth, cheetah), tf.sqrt(math.add(math.mean(pony, [(pony[String("shape")][String("length")]-camel[0]), (pony[String("shape")][String("length")]-camel[1]), (pony[String("shape")][String("length")]-camel[2])], true), opossum)))), math.reshape(model.weights[77], [leopard[3], leopard[2], leopard[1], leopard[0]]))); - }; - function frog(goat) { - return math.add(math.transpose(math.conv2d(math.transpose(goat, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[78], [2, 3, 1, 0], goat), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[79]); - }; - function model(grouse) { - return rhinoceros(turkey(tapir(yak(waterbuffalo(giraffe(dragonfly(termite(ferret(goose(chinchilla(narwhal(coyote(gaur(fly(frog(grouse)))))))))))))))); - }; - model.weights = []; - return model; -})(); \ No newline at end of file diff --git a/experiments/styleTransfer/assets/js/fluxjs/flux.js b/experiments/styleTransfer/assets/js/fluxjs/flux.js deleted file mode 100644 index 5a21b466..00000000 --- a/experiments/styleTransfer/assets/js/fluxjs/flux.js +++ /dev/null @@ -1,111 +0,0 @@ -flux = (function () { - -let Buffer = new BSON().serialize({}).constructor - -function blobAsArrayBuffer(blob) { - return new Promise((resolve, reject) => { - let reader = new FileReader(); - reader.addEventListener("loadend", function() { - resolve(reader.result); - }); - reader.readAsArrayBuffer(blob); - }); -} - -async function fetchBytes(url) { - let resp = await fetch(url); - if (!resp.ok) throw(resp); - let blob = await resp.blob(); - let buf = await blobAsArrayBuffer(blob); - return new Buffer(buf); -} - -async function fetchData(url) { - let buf = await fetchBytes(url); - return new BSON().deserialize(buf); -} - -// `buf` is a Uint8Array from BSON -function readFloat32(buf) { - let view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); - let data = new Float32Array(view.byteLength/4); - for (let i = 0; i < data.length; i++) { - data[i] = view.getFloat32(i*4, true); - } - return data; -} - -function readInt32(buf) { - let view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); - let data = new Int32Array(view.byteLength/4); - for (let i = 0; i < data.length; i++) { - data[i] = view.getInt32(i*4, true); - } - return data; -} - -function toTensor_(spec) { - let type = spec.type.name; - type = type[type.length-1]; - if (type == 'Float32') spec.data = readFloat32(spec.data.buffer); - else if (type == 'Int32') spec.data = readInt32(spec.data.buffer); - else throw `Array type ${spec.type.name} not supported.`; - let array = tf.tensor(spec.data, spec.size.reverse()); - return array -} - -function convertArrays_(data) { - if (!(typeof data == "object")) return data - if (data.tag == "array") { - return toTensor_(data); - } else { - for (let k of Object.keys(data)) { - data[k] = convertArrays_(data[k]) - } - } - return data; -} - -async function fetchBlob(url) { - data = await fetchData(url); - return convertArrays_(data) -} - -async function fetchWeights(url) { - ws = await fetchBlob(url); - return ws.weights; -} - -const _data = t => (t instanceof tf.Tensor)? t.dataSync(): t; -const slice = t => (t instanceof tf.Tensor)? t.clone():( - t instanceof Array ? t.slice() : t); -const tensor = t => (t instanceof tf.Tensor)? t : ( - t instanceof Array ? tf.tensor(t) : tf.tensor([t])); - -const range = (start, stop) => [...Array(stop - start + 1).keys()].map(i => i + start) - -return {fetchData, fetchWeights, fetchBlob, convertArrays_, data: _data, slice, range}; - -})(); - - -// for custom convTranspose layer in FastStyleTransfer.jl -function out_size(stride, pad, dilation, kernel, xdims, output_pad){ - var dims = [] - var n = (stride.length) - - for (k =0; k< n; k++) { - var i = [0, stride[k], pad[k], dilation[k], kernel[k], xdims[k], output_pad[k]] - dims.push(i[1] * (i[5] - 1) + (i[4] - 1) * i[3] - 2 * i[2] + 1 + i[6]) - } - return dims -} - -function ctos(x, w, stride, pad, dilation, output_pad){ - var a = out_size(stride, pad, dilation, w.shape.slice(2).reverse(), x.shape.slice(2).reverse(), output_pad) - var b = ([...a, w.shape[1], x.shape[0]]).reverse() - return [b[0], b[2], b[3], b[1]] - -} - -flux.ctOutSize = ctos diff --git a/experiments/styleTransfer/assets/js/fluxjs/popsty_fluxjs.js b/experiments/styleTransfer/assets/js/fluxjs/popsty_fluxjs.js deleted file mode 100644 index 208032f6..00000000 --- a/experiments/styleTransfer/assets/js/fluxjs/popsty_fluxjs.js +++ /dev/null @@ -1,221 +0,0 @@ -let popsty = (function () { - let math = tf; - function rhinoceros(koala) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(koala, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[0], [2, 3, 1, 0], koala), [0, 1]), flux.ctOutSize(koala, model.weights[1], [1, 1], [1, 1], [1, 1], [0, 0]), [1, 1], 1, "floor"), [0, 3, 1, 2]), model.weights[2]); - }; - let walrus = math.tensor(1.0e-5); - function turkey(porcupine) { - let guineafowl = porcupine[String("shape")][String("length")]; - let bison = [].fill.apply(Array(guineafowl), [1]); - let squirrel = [].concat.call(flux.range(1, (guineafowl-2)), guineafowl); - let eland = math.mean(porcupine, [(porcupine[String("shape")][String("length")]-squirrel[0]), (porcupine[String("shape")][String("length")]-squirrel[1]), (porcupine[String("shape")][String("length")]-squirrel[2])], true); - let flamingo = math.pow(math.sub(porcupine, eland), model.weights[4]); - bison[(guineafowl-2)] = porcupine[String("shape")][(porcupine[String("shape")][String("length")]-(guineafowl-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[3], [bison[3], bison[2], bison[1], bison[0]]), math.div(math.sub(porcupine, eland), tf.sqrt(math.add(math.mean(flamingo, [(flamingo[String("shape")][String("length")]-squirrel[0]), (flamingo[String("shape")][String("length")]-squirrel[1]), (flamingo[String("shape")][String("length")]-squirrel[2])], true), walrus)))), math.reshape(model.weights[5], [bison[3], bison[2], bison[1], bison[0]]))); - }; - function tapir(donkey) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(donkey, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[6], [2, 3, 1, 0], donkey), [0, 1]), flux.ctOutSize(donkey, model.weights[7], [2, 2], [1, 1], [1, 1], [1, 1]), [2, 2], 1, "floor"), [0, 3, 1, 2]), model.weights[8]); - }; - let shrew = math.tensor(1.0e-5); - function yak(dog) { - let butterfly = dog[String("shape")][String("length")]; - let gnu = [].fill.apply(Array(butterfly), [1]); - let quetzal = [].concat.call(flux.range(1, (butterfly-2)), butterfly); - let skunk = math.mean(dog, [(dog[String("shape")][String("length")]-quetzal[0]), (dog[String("shape")][String("length")]-quetzal[1]), (dog[String("shape")][String("length")]-quetzal[2])], true); - let cassowary = math.pow(math.sub(dog, skunk), model.weights[10]); - gnu[(butterfly-2)] = dog[String("shape")][(dog[String("shape")][String("length")]-(butterfly-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[9], [gnu[3], gnu[2], gnu[1], gnu[0]]), math.div(math.sub(dog, skunk), tf.sqrt(math.add(math.mean(cassowary, [(cassowary[String("shape")][String("length")]-quetzal[0]), (cassowary[String("shape")][String("length")]-quetzal[1]), (cassowary[String("shape")][String("length")]-quetzal[2])], true), shrew)))), math.reshape(model.weights[11], [gnu[3], gnu[2], gnu[1], gnu[0]]))); - }; - function waterbuffalo(nightingale) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(nightingale, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[12], [2, 3, 1, 0], nightingale), [0, 1]), flux.ctOutSize(nightingale, model.weights[13], [2, 2], [1, 1], [1, 1], [1, 1]), [2, 2], 1, "floor"), [0, 3, 1, 2]), model.weights[14]); - }; - let penguin = math.tensor(1.0e-5); - function lobster(curlew) { - let mandrill = curlew[String("shape")][String("length")]; - let toad = [].fill.apply(Array(mandrill), [1]); - let polarbear = [].concat.call(flux.range(1, (mandrill-2)), mandrill); - let lion = math.mean(curlew, [(curlew[String("shape")][String("length")]-polarbear[0]), (curlew[String("shape")][String("length")]-polarbear[1]), (curlew[String("shape")][String("length")]-polarbear[2])], true); - let moose = math.pow(math.sub(curlew, lion), model.weights[16]); - toad[(mandrill-2)] = curlew[String("shape")][(curlew[String("shape")][String("length")]-(mandrill-1))]; - return math.add(math.mul(math.reshape(model.weights[15], [toad[3], toad[2], toad[1], toad[0]]), math.div(math.sub(curlew, lion), tf.sqrt(math.add(math.mean(moose, [(moose[String("shape")][String("length")]-polarbear[0]), (moose[String("shape")][String("length")]-polarbear[1]), (moose[String("shape")][String("length")]-polarbear[2])], true), penguin)))), math.reshape(model.weights[17], [toad[3], toad[2], toad[1], toad[0]])); - }; - function raven(starling) { - return math.add(math.transpose(math.conv2d(math.transpose(starling, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[18], [2, 3, 1, 0], starling), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[19]); - }; - let gull = math.tensor(1.0e-5); - function zebra(crane) { - let crocodile = crane[String("shape")][String("length")]; - let mosquito = [].fill.apply(Array(crocodile), [1]); - let ape = [].concat.call(flux.range(1, (crocodile-2)), crocodile); - let lapwing = math.mean(crane, [(crane[String("shape")][String("length")]-ape[0]), (crane[String("shape")][String("length")]-ape[1]), (crane[String("shape")][String("length")]-ape[2])], true); - let goosander = math.pow(math.sub(crane, lapwing), model.weights[21]); - mosquito[(crocodile-2)] = crane[String("shape")][(crane[String("shape")][String("length")]-(crocodile-1))]; - return math.add(math.mul(math.reshape(model.weights[20], [mosquito[3], mosquito[2], mosquito[1], mosquito[0]]), math.div(math.sub(crane, lapwing), tf.sqrt(math.add(math.mean(goosander, [(goosander[String("shape")][String("length")]-ape[0]), (goosander[String("shape")][String("length")]-ape[1]), (goosander[String("shape")][String("length")]-ape[2])], true), gull)))), math.reshape(model.weights[22], [mosquito[3], mosquito[2], mosquito[1], mosquito[0]])); - }; - function goldfinch(dogfish) { - return math.add(math.transpose(math.conv2d(math.transpose(dogfish, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[23], [2, 3, 1, 0], dogfish), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[24]); - }; - function giraffe(komodo) { - return math.add(komodo, lobster(raven(math.relu(zebra(goldfinch(komodo)))))); - }; - let chamois = math.tensor(1.0e-5); - function tiger(sardine) { - let hare = sardine[String("shape")][String("length")]; - let caribou = [].fill.apply(Array(hare), [1]); - let ram = [].concat.call(flux.range(1, (hare-2)), hare); - let sheep = math.mean(sardine, [(sardine[String("shape")][String("length")]-ram[0]), (sardine[String("shape")][String("length")]-ram[1]), (sardine[String("shape")][String("length")]-ram[2])], true); - let snail = math.pow(math.sub(sardine, sheep), model.weights[26]); - caribou[(hare-2)] = sardine[String("shape")][(sardine[String("shape")][String("length")]-(hare-1))]; - return math.add(math.mul(math.reshape(model.weights[25], [caribou[3], caribou[2], caribou[1], caribou[0]]), math.div(math.sub(sardine, sheep), tf.sqrt(math.add(math.mean(snail, [(snail[String("shape")][String("length")]-ram[0]), (snail[String("shape")][String("length")]-ram[1]), (snail[String("shape")][String("length")]-ram[2])], true), chamois)))), math.reshape(model.weights[27], [caribou[3], caribou[2], caribou[1], caribou[0]])); - }; - function sandpiper(lyrebird) { - return math.add(math.transpose(math.conv2d(math.transpose(lyrebird, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[28], [2, 3, 1, 0], lyrebird), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[29]); - }; - let wildebeest = math.tensor(1.0e-5); - function emu(pheasant) { - let guanaco = pheasant[String("shape")][String("length")]; - let anteater = [].fill.apply(Array(guanaco), [1]); - let salmon = [].concat.call(flux.range(1, (guanaco-2)), guanaco); - let mouse = math.mean(pheasant, [(pheasant[String("shape")][String("length")]-salmon[0]), (pheasant[String("shape")][String("length")]-salmon[1]), (pheasant[String("shape")][String("length")]-salmon[2])], true); - let manatee = math.pow(math.sub(pheasant, mouse), model.weights[31]); - anteater[(guanaco-2)] = pheasant[String("shape")][(pheasant[String("shape")][String("length")]-(guanaco-1))]; - return math.add(math.mul(math.reshape(model.weights[30], [anteater[3], anteater[2], anteater[1], anteater[0]]), math.div(math.sub(pheasant, mouse), tf.sqrt(math.add(math.mean(manatee, [(manatee[String("shape")][String("length")]-salmon[0]), (manatee[String("shape")][String("length")]-salmon[1]), (manatee[String("shape")][String("length")]-salmon[2])], true), wildebeest)))), math.reshape(model.weights[32], [anteater[3], anteater[2], anteater[1], anteater[0]])); - }; - function jay(quail) { - return math.add(math.transpose(math.conv2d(math.transpose(quail, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[33], [2, 3, 1, 0], quail), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[34]); - }; - function dragonfly(sealion) { - return math.add(sealion, tiger(sandpiper(math.relu(emu(jay(sealion)))))); - }; - let raccoon = math.tensor(1.0e-5); - function okapi(swan) { - let mink = swan[String("shape")][String("length")]; - let duck = [].fill.apply(Array(mink), [1]); - let heron = [].concat.call(flux.range(1, (mink-2)), mink); - let chough = math.mean(swan, [(swan[String("shape")][String("length")]-heron[0]), (swan[String("shape")][String("length")]-heron[1]), (swan[String("shape")][String("length")]-heron[2])], true); - let jaguar = math.pow(math.sub(swan, chough), model.weights[36]); - duck[(mink-2)] = swan[String("shape")][(swan[String("shape")][String("length")]-(mink-1))]; - return math.add(math.mul(math.reshape(model.weights[35], [duck[3], duck[2], duck[1], duck[0]]), math.div(math.sub(swan, chough), tf.sqrt(math.add(math.mean(jaguar, [(jaguar[String("shape")][String("length")]-heron[0]), (jaguar[String("shape")][String("length")]-heron[1]), (jaguar[String("shape")][String("length")]-heron[2])], true), raccoon)))), math.reshape(model.weights[37], [duck[3], duck[2], duck[1], duck[0]])); - }; - function monkey(chimpanzee) { - return math.add(math.transpose(math.conv2d(math.transpose(chimpanzee, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[38], [2, 3, 1, 0], chimpanzee), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[39]); - }; - let octopus = math.tensor(1.0e-5); - function wasp(oyster) { - let locust = oyster[String("shape")][String("length")]; - let ibis = [].fill.apply(Array(locust), [1]); - let wallaby = [].concat.call(flux.range(1, (locust-2)), locust); - let jackal = math.mean(oyster, [(oyster[String("shape")][String("length")]-wallaby[0]), (oyster[String("shape")][String("length")]-wallaby[1]), (oyster[String("shape")][String("length")]-wallaby[2])], true); - let gnat = math.pow(math.sub(oyster, jackal), model.weights[41]); - ibis[(locust-2)] = oyster[String("shape")][(oyster[String("shape")][String("length")]-(locust-1))]; - return math.add(math.mul(math.reshape(model.weights[40], [ibis[3], ibis[2], ibis[1], ibis[0]]), math.div(math.sub(oyster, jackal), tf.sqrt(math.add(math.mean(gnat, [(gnat[String("shape")][String("length")]-wallaby[0]), (gnat[String("shape")][String("length")]-wallaby[1]), (gnat[String("shape")][String("length")]-wallaby[2])], true), octopus)))), math.reshape(model.weights[42], [ibis[3], ibis[2], ibis[1], ibis[0]])); - }; - function kouprey(hummingbird) { - return math.add(math.transpose(math.conv2d(math.transpose(hummingbird, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[43], [2, 3, 1, 0], hummingbird), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[44]); - }; - function termite(otter) { - return math.add(otter, okapi(monkey(math.relu(wasp(kouprey(otter)))))); - }; - let fish = math.tensor(1.0e-5); - function cat(goshawk) { - let seal = goshawk[String("shape")][String("length")]; - let louse = [].fill.apply(Array(seal), [1]); - let ibex = [].concat.call(flux.range(1, (seal-2)), seal); - let cockroach = math.mean(goshawk, [(goshawk[String("shape")][String("length")]-ibex[0]), (goshawk[String("shape")][String("length")]-ibex[1]), (goshawk[String("shape")][String("length")]-ibex[2])], true); - let eel = math.pow(math.sub(goshawk, cockroach), model.weights[46]); - louse[(seal-2)] = goshawk[String("shape")][(goshawk[String("shape")][String("length")]-(seal-1))]; - return math.add(math.mul(math.reshape(model.weights[45], [louse[3], louse[2], louse[1], louse[0]]), math.div(math.sub(goshawk, cockroach), tf.sqrt(math.add(math.mean(eel, [(eel[String("shape")][String("length")]-ibex[0]), (eel[String("shape")][String("length")]-ibex[1]), (eel[String("shape")][String("length")]-ibex[2])], true), fish)))), math.reshape(model.weights[47], [louse[3], louse[2], louse[1], louse[0]])); - }; - function prairiedog(dolphin) { - return math.add(math.transpose(math.conv2d(math.transpose(dolphin, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[48], [2, 3, 1, 0], dolphin), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[49]); - }; - let kangaroo = math.tensor(1.0e-5); - function elk(falcon) { - let alpaca = falcon[String("shape")][String("length")]; - let caterpillar = [].fill.apply(Array(alpaca), [1]); - let panda = [].concat.call(flux.range(1, (alpaca-2)), alpaca); - let beaver = math.mean(falcon, [(falcon[String("shape")][String("length")]-panda[0]), (falcon[String("shape")][String("length")]-panda[1]), (falcon[String("shape")][String("length")]-panda[2])], true); - let boar = math.pow(math.sub(falcon, beaver), model.weights[51]); - caterpillar[(alpaca-2)] = falcon[String("shape")][(falcon[String("shape")][String("length")]-(alpaca-1))]; - return math.add(math.mul(math.reshape(model.weights[50], [caterpillar[3], caterpillar[2], caterpillar[1], caterpillar[0]]), math.div(math.sub(falcon, beaver), tf.sqrt(math.add(math.mean(boar, [(boar[String("shape")][String("length")]-panda[0]), (boar[String("shape")][String("length")]-panda[1]), (boar[String("shape")][String("length")]-panda[2])], true), kangaroo)))), math.reshape(model.weights[52], [caterpillar[3], caterpillar[2], caterpillar[1], caterpillar[0]])); - }; - function peafowl(cod) { - return math.add(math.transpose(math.conv2d(math.transpose(cod, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[53], [2, 3, 1, 0], cod), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[54]); - }; - function ferret(wombat) { - return math.add(wombat, cat(prairiedog(math.relu(elk(peafowl(wombat)))))); - }; - let dunlin = math.tensor(1.0e-5); - function donkey(kudu) { - let aardvark = kudu[String("shape")][String("length")]; - let elephant = [].fill.apply(Array(aardvark), [1]); - let bat = [].concat.call(flux.range(1, (aardvark-2)), aardvark); - let magpie = math.mean(kudu, [(kudu[String("shape")][String("length")]-bat[0]), (kudu[String("shape")][String("length")]-bat[1]), (kudu[String("shape")][String("length")]-bat[2])], true); - let pelican = math.pow(math.sub(kudu, magpie), model.weights[56]); - elephant[(aardvark-2)] = kudu[String("shape")][(kudu[String("shape")][String("length")]-(aardvark-1))]; - return math.add(math.mul(math.reshape(model.weights[55], [elephant[3], elephant[2], elephant[1], elephant[0]]), math.div(math.sub(kudu, magpie), tf.sqrt(math.add(math.mean(pelican, [(pelican[String("shape")][String("length")]-bat[0]), (pelican[String("shape")][String("length")]-bat[1]), (pelican[String("shape")][String("length")]-bat[2])], true), dunlin)))), math.reshape(model.weights[57], [elephant[3], elephant[2], elephant[1], elephant[0]])); - }; - function bee(seahorse) { - return math.add(math.transpose(math.conv2d(math.transpose(seahorse, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[58], [2, 3, 1, 0], seahorse), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[59]); - }; - let loris = math.tensor(1.0e-5); - function tarsier(fox) { - let salamander = fox[String("shape")][String("length")]; - let hedgehog = [].fill.apply(Array(salamander), [1]); - let mammoth = [].concat.call(flux.range(1, (salamander-2)), salamander); - let crab = math.mean(fox, [(fox[String("shape")][String("length")]-mammoth[0]), (fox[String("shape")][String("length")]-mammoth[1]), (fox[String("shape")][String("length")]-mammoth[2])], true); - let ant = math.pow(math.sub(fox, crab), model.weights[61]); - hedgehog[(salamander-2)] = fox[String("shape")][(fox[String("shape")][String("length")]-(salamander-1))]; - return math.add(math.mul(math.reshape(model.weights[60], [hedgehog[3], hedgehog[2], hedgehog[1], hedgehog[0]]), math.div(math.sub(fox, crab), tf.sqrt(math.add(math.mean(ant, [(ant[String("shape")][String("length")]-mammoth[0]), (ant[String("shape")][String("length")]-mammoth[1]), (ant[String("shape")][String("length")]-mammoth[2])], true), loris)))), math.reshape(model.weights[62], [hedgehog[3], hedgehog[2], hedgehog[1], hedgehog[0]])); - }; - function eagle(horse) { - return math.add(math.transpose(math.conv2d(math.transpose(horse, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[63], [2, 3, 1, 0], horse), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[64]); - }; - function goose(partridge) { - return math.add(partridge, donkey(bee(math.relu(tarsier(eagle(partridge)))))); - }; - let gerbil = math.tensor(1.0e-5); - function chinchilla(rook) { - let lark = rook[String("shape")][String("length")]; - let barracuda = [].fill.apply(Array(lark), [1]); - let herring = [].concat.call(flux.range(1, (lark-2)), lark); - let antelope = math.mean(rook, [(rook[String("shape")][String("length")]-herring[0]), (rook[String("shape")][String("length")]-herring[1]), (rook[String("shape")][String("length")]-herring[2])], true); - let mongoose = math.pow(math.sub(rook, antelope), model.weights[66]); - barracuda[(lark-2)] = rook[String("shape")][(rook[String("shape")][String("length")]-(lark-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[65], [barracuda[3], barracuda[2], barracuda[1], barracuda[0]]), math.div(math.sub(rook, antelope), tf.sqrt(math.add(math.mean(mongoose, [(mongoose[String("shape")][String("length")]-herring[0]), (mongoose[String("shape")][String("length")]-herring[1]), (mongoose[String("shape")][String("length")]-herring[2])], true), gerbil)))), math.reshape(model.weights[67], [barracuda[3], barracuda[2], barracuda[1], barracuda[0]]))); - }; - function narwhal(chicken) { - return math.add(math.transpose(math.conv2d(math.transpose(chicken, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[68], [2, 3, 1, 0], chicken), [0, 1]), [2, 2], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[69]); - }; - let hippopotamus = math.tensor(1.0e-5); - function coyote(finch) { - let reddeer = finch[String("shape")][String("length")]; - let cobra = [].fill.apply(Array(reddeer), [1]); - let pigeon = [].concat.call(flux.range(1, (reddeer-2)), reddeer); - let reindeer = math.mean(finch, [(finch[String("shape")][String("length")]-pigeon[0]), (finch[String("shape")][String("length")]-pigeon[1]), (finch[String("shape")][String("length")]-pigeon[2])], true); - let cormorant = math.pow(math.sub(finch, reindeer), model.weights[71]); - cobra[(reddeer-2)] = finch[String("shape")][(finch[String("shape")][String("length")]-(reddeer-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[70], [cobra[3], cobra[2], cobra[1], cobra[0]]), math.div(math.sub(finch, reindeer), tf.sqrt(math.add(math.mean(cormorant, [(cormorant[String("shape")][String("length")]-pigeon[0]), (cormorant[String("shape")][String("length")]-pigeon[1]), (cormorant[String("shape")][String("length")]-pigeon[2])], true), hippopotamus)))), math.reshape(model.weights[72], [cobra[3], cobra[2], cobra[1], cobra[0]]))); - }; - function gaur(weasel) { - return math.add(math.transpose(math.conv2d(math.transpose(weasel, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[73], [2, 3, 1, 0], weasel), [0, 1]), [2, 2], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[74]); - }; - let opossum = math.tensor(1.0e-5); - function fly(sloth) { - let whale = sloth[String("shape")][String("length")]; - let leopard = [].fill.apply(Array(whale), [1]); - let camel = [].concat.call(flux.range(1, (whale-2)), whale); - let cheetah = math.mean(sloth, [(sloth[String("shape")][String("length")]-camel[0]), (sloth[String("shape")][String("length")]-camel[1]), (sloth[String("shape")][String("length")]-camel[2])], true); - let pony = math.pow(math.sub(sloth, cheetah), model.weights[76]); - leopard[(whale-2)] = sloth[String("shape")][(sloth[String("shape")][String("length")]-(whale-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[75], [leopard[3], leopard[2], leopard[1], leopard[0]]), math.div(math.sub(sloth, cheetah), tf.sqrt(math.add(math.mean(pony, [(pony[String("shape")][String("length")]-camel[0]), (pony[String("shape")][String("length")]-camel[1]), (pony[String("shape")][String("length")]-camel[2])], true), opossum)))), math.reshape(model.weights[77], [leopard[3], leopard[2], leopard[1], leopard[0]]))); - }; - function frog(goat) { - return math.add(math.transpose(math.conv2d(math.transpose(goat, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[78], [2, 3, 1, 0], goat), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[79]); - }; - function model(grouse) { - return rhinoceros(turkey(tapir(yak(waterbuffalo(giraffe(dragonfly(termite(ferret(goose(chinchilla(narwhal(coyote(gaur(fly(frog(grouse)))))))))))))))); - }; - model.weights = []; - return model; -})(); \ No newline at end of file diff --git a/experiments/styleTransfer/assets/js/fluxjs/starry_night_fluxjs.js b/experiments/styleTransfer/assets/js/fluxjs/starry_night_fluxjs.js deleted file mode 100644 index ada8158e..00000000 --- a/experiments/styleTransfer/assets/js/fluxjs/starry_night_fluxjs.js +++ /dev/null @@ -1,221 +0,0 @@ -let starry_night = (function () { - let math = tf; - function rhinoceros(koala) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(koala, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[0], [2, 3, 1, 0], koala), [0, 1]), flux.ctOutSize(koala, model.weights[1], [1, 1], [1, 1], [1, 1], [0, 0]), [1, 1], 1, "floor"), [0, 3, 1, 2]), model.weights[2]); - }; - let walrus = math.tensor(1.0e-5); - function turkey(porcupine) { - let guineafowl = porcupine[String("shape")][String("length")]; - let bison = [].fill.apply(Array(guineafowl), [1]); - let squirrel = [].concat.call(flux.range(1, (guineafowl-2)), guineafowl); - let eland = math.mean(porcupine, [(porcupine[String("shape")][String("length")]-squirrel[0]), (porcupine[String("shape")][String("length")]-squirrel[1]), (porcupine[String("shape")][String("length")]-squirrel[2])], true); - let flamingo = math.pow(math.sub(porcupine, eland), model.weights[4]); - bison[(guineafowl-2)] = porcupine[String("shape")][(porcupine[String("shape")][String("length")]-(guineafowl-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[3], [bison[3], bison[2], bison[1], bison[0]]), math.div(math.sub(porcupine, eland), tf.sqrt(math.add(math.mean(flamingo, [(flamingo[String("shape")][String("length")]-squirrel[0]), (flamingo[String("shape")][String("length")]-squirrel[1]), (flamingo[String("shape")][String("length")]-squirrel[2])], true), walrus)))), math.reshape(model.weights[5], [bison[3], bison[2], bison[1], bison[0]]))); - }; - function tapir(donkey) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(donkey, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[6], [2, 3, 1, 0], donkey), [0, 1]), flux.ctOutSize(donkey, model.weights[7], [2, 2], [1, 1], [1, 1], [1, 1]), [2, 2], 1, "floor"), [0, 3, 1, 2]), model.weights[8]); - }; - let shrew = math.tensor(1.0e-5); - function yak(dog) { - let butterfly = dog[String("shape")][String("length")]; - let gnu = [].fill.apply(Array(butterfly), [1]); - let quetzal = [].concat.call(flux.range(1, (butterfly-2)), butterfly); - let skunk = math.mean(dog, [(dog[String("shape")][String("length")]-quetzal[0]), (dog[String("shape")][String("length")]-quetzal[1]), (dog[String("shape")][String("length")]-quetzal[2])], true); - let cassowary = math.pow(math.sub(dog, skunk), model.weights[10]); - gnu[(butterfly-2)] = dog[String("shape")][(dog[String("shape")][String("length")]-(butterfly-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[9], [gnu[3], gnu[2], gnu[1], gnu[0]]), math.div(math.sub(dog, skunk), tf.sqrt(math.add(math.mean(cassowary, [(cassowary[String("shape")][String("length")]-quetzal[0]), (cassowary[String("shape")][String("length")]-quetzal[1]), (cassowary[String("shape")][String("length")]-quetzal[2])], true), shrew)))), math.reshape(model.weights[11], [gnu[3], gnu[2], gnu[1], gnu[0]]))); - }; - function waterbuffalo(nightingale) { - return math.add(math.transpose(math.conv2dTranspose(math.transpose(nightingale, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[12], [2, 3, 1, 0], nightingale), [0, 1]), flux.ctOutSize(nightingale, model.weights[13], [2, 2], [1, 1], [1, 1], [1, 1]), [2, 2], 1, "floor"), [0, 3, 1, 2]), model.weights[14]); - }; - let penguin = math.tensor(1.0e-5); - function lobster(curlew) { - let mandrill = curlew[String("shape")][String("length")]; - let toad = [].fill.apply(Array(mandrill), [1]); - let polarbear = [].concat.call(flux.range(1, (mandrill-2)), mandrill); - let lion = math.mean(curlew, [(curlew[String("shape")][String("length")]-polarbear[0]), (curlew[String("shape")][String("length")]-polarbear[1]), (curlew[String("shape")][String("length")]-polarbear[2])], true); - let moose = math.pow(math.sub(curlew, lion), model.weights[16]); - toad[(mandrill-2)] = curlew[String("shape")][(curlew[String("shape")][String("length")]-(mandrill-1))]; - return math.add(math.mul(math.reshape(model.weights[15], [toad[3], toad[2], toad[1], toad[0]]), math.div(math.sub(curlew, lion), tf.sqrt(math.add(math.mean(moose, [(moose[String("shape")][String("length")]-polarbear[0]), (moose[String("shape")][String("length")]-polarbear[1]), (moose[String("shape")][String("length")]-polarbear[2])], true), penguin)))), math.reshape(model.weights[17], [toad[3], toad[2], toad[1], toad[0]])); - }; - function raven(starling) { - return math.add(math.transpose(math.conv2d(math.transpose(starling, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[18], [2, 3, 1, 0], starling), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[19]); - }; - let gull = math.tensor(1.0e-5); - function zebra(crane) { - let crocodile = crane[String("shape")][String("length")]; - let mosquito = [].fill.apply(Array(crocodile), [1]); - let ape = [].concat.call(flux.range(1, (crocodile-2)), crocodile); - let lapwing = math.mean(crane, [(crane[String("shape")][String("length")]-ape[0]), (crane[String("shape")][String("length")]-ape[1]), (crane[String("shape")][String("length")]-ape[2])], true); - let goosander = math.pow(math.sub(crane, lapwing), model.weights[21]); - mosquito[(crocodile-2)] = crane[String("shape")][(crane[String("shape")][String("length")]-(crocodile-1))]; - return math.add(math.mul(math.reshape(model.weights[20], [mosquito[3], mosquito[2], mosquito[1], mosquito[0]]), math.div(math.sub(crane, lapwing), tf.sqrt(math.add(math.mean(goosander, [(goosander[String("shape")][String("length")]-ape[0]), (goosander[String("shape")][String("length")]-ape[1]), (goosander[String("shape")][String("length")]-ape[2])], true), gull)))), math.reshape(model.weights[22], [mosquito[3], mosquito[2], mosquito[1], mosquito[0]])); - }; - function goldfinch(dogfish) { - return math.add(math.transpose(math.conv2d(math.transpose(dogfish, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[23], [2, 3, 1, 0], dogfish), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[24]); - }; - function giraffe(komodo) { - return math.add(komodo, lobster(raven(math.relu(zebra(goldfinch(komodo)))))); - }; - let chamois = math.tensor(1.0e-5); - function tiger(sardine) { - let hare = sardine[String("shape")][String("length")]; - let caribou = [].fill.apply(Array(hare), [1]); - let ram = [].concat.call(flux.range(1, (hare-2)), hare); - let sheep = math.mean(sardine, [(sardine[String("shape")][String("length")]-ram[0]), (sardine[String("shape")][String("length")]-ram[1]), (sardine[String("shape")][String("length")]-ram[2])], true); - let snail = math.pow(math.sub(sardine, sheep), model.weights[26]); - caribou[(hare-2)] = sardine[String("shape")][(sardine[String("shape")][String("length")]-(hare-1))]; - return math.add(math.mul(math.reshape(model.weights[25], [caribou[3], caribou[2], caribou[1], caribou[0]]), math.div(math.sub(sardine, sheep), tf.sqrt(math.add(math.mean(snail, [(snail[String("shape")][String("length")]-ram[0]), (snail[String("shape")][String("length")]-ram[1]), (snail[String("shape")][String("length")]-ram[2])], true), chamois)))), math.reshape(model.weights[27], [caribou[3], caribou[2], caribou[1], caribou[0]])); - }; - function sandpiper(lyrebird) { - return math.add(math.transpose(math.conv2d(math.transpose(lyrebird, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[28], [2, 3, 1, 0], lyrebird), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[29]); - }; - let wildebeest = math.tensor(1.0e-5); - function emu(pheasant) { - let guanaco = pheasant[String("shape")][String("length")]; - let anteater = [].fill.apply(Array(guanaco), [1]); - let salmon = [].concat.call(flux.range(1, (guanaco-2)), guanaco); - let mouse = math.mean(pheasant, [(pheasant[String("shape")][String("length")]-salmon[0]), (pheasant[String("shape")][String("length")]-salmon[1]), (pheasant[String("shape")][String("length")]-salmon[2])], true); - let manatee = math.pow(math.sub(pheasant, mouse), model.weights[31]); - anteater[(guanaco-2)] = pheasant[String("shape")][(pheasant[String("shape")][String("length")]-(guanaco-1))]; - return math.add(math.mul(math.reshape(model.weights[30], [anteater[3], anteater[2], anteater[1], anteater[0]]), math.div(math.sub(pheasant, mouse), tf.sqrt(math.add(math.mean(manatee, [(manatee[String("shape")][String("length")]-salmon[0]), (manatee[String("shape")][String("length")]-salmon[1]), (manatee[String("shape")][String("length")]-salmon[2])], true), wildebeest)))), math.reshape(model.weights[32], [anteater[3], anteater[2], anteater[1], anteater[0]])); - }; - function jay(quail) { - return math.add(math.transpose(math.conv2d(math.transpose(quail, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[33], [2, 3, 1, 0], quail), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[34]); - }; - function dragonfly(sealion) { - return math.add(sealion, tiger(sandpiper(math.relu(emu(jay(sealion)))))); - }; - let raccoon = math.tensor(1.0e-5); - function okapi(swan) { - let mink = swan[String("shape")][String("length")]; - let duck = [].fill.apply(Array(mink), [1]); - let heron = [].concat.call(flux.range(1, (mink-2)), mink); - let chough = math.mean(swan, [(swan[String("shape")][String("length")]-heron[0]), (swan[String("shape")][String("length")]-heron[1]), (swan[String("shape")][String("length")]-heron[2])], true); - let jaguar = math.pow(math.sub(swan, chough), model.weights[36]); - duck[(mink-2)] = swan[String("shape")][(swan[String("shape")][String("length")]-(mink-1))]; - return math.add(math.mul(math.reshape(model.weights[35], [duck[3], duck[2], duck[1], duck[0]]), math.div(math.sub(swan, chough), tf.sqrt(math.add(math.mean(jaguar, [(jaguar[String("shape")][String("length")]-heron[0]), (jaguar[String("shape")][String("length")]-heron[1]), (jaguar[String("shape")][String("length")]-heron[2])], true), raccoon)))), math.reshape(model.weights[37], [duck[3], duck[2], duck[1], duck[0]])); - }; - function monkey(chimpanzee) { - return math.add(math.transpose(math.conv2d(math.transpose(chimpanzee, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[38], [2, 3, 1, 0], chimpanzee), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[39]); - }; - let octopus = math.tensor(1.0e-5); - function wasp(oyster) { - let locust = oyster[String("shape")][String("length")]; - let ibis = [].fill.apply(Array(locust), [1]); - let wallaby = [].concat.call(flux.range(1, (locust-2)), locust); - let jackal = math.mean(oyster, [(oyster[String("shape")][String("length")]-wallaby[0]), (oyster[String("shape")][String("length")]-wallaby[1]), (oyster[String("shape")][String("length")]-wallaby[2])], true); - let gnat = math.pow(math.sub(oyster, jackal), model.weights[41]); - ibis[(locust-2)] = oyster[String("shape")][(oyster[String("shape")][String("length")]-(locust-1))]; - return math.add(math.mul(math.reshape(model.weights[40], [ibis[3], ibis[2], ibis[1], ibis[0]]), math.div(math.sub(oyster, jackal), tf.sqrt(math.add(math.mean(gnat, [(gnat[String("shape")][String("length")]-wallaby[0]), (gnat[String("shape")][String("length")]-wallaby[1]), (gnat[String("shape")][String("length")]-wallaby[2])], true), octopus)))), math.reshape(model.weights[42], [ibis[3], ibis[2], ibis[1], ibis[0]])); - }; - function kouprey(hummingbird) { - return math.add(math.transpose(math.conv2d(math.transpose(hummingbird, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[43], [2, 3, 1, 0], hummingbird), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[44]); - }; - function termite(otter) { - return math.add(otter, okapi(monkey(math.relu(wasp(kouprey(otter)))))); - }; - let fish = math.tensor(1.0e-5); - function cat(goshawk) { - let seal = goshawk[String("shape")][String("length")]; - let louse = [].fill.apply(Array(seal), [1]); - let ibex = [].concat.call(flux.range(1, (seal-2)), seal); - let cockroach = math.mean(goshawk, [(goshawk[String("shape")][String("length")]-ibex[0]), (goshawk[String("shape")][String("length")]-ibex[1]), (goshawk[String("shape")][String("length")]-ibex[2])], true); - let eel = math.pow(math.sub(goshawk, cockroach), model.weights[46]); - louse[(seal-2)] = goshawk[String("shape")][(goshawk[String("shape")][String("length")]-(seal-1))]; - return math.add(math.mul(math.reshape(model.weights[45], [louse[3], louse[2], louse[1], louse[0]]), math.div(math.sub(goshawk, cockroach), tf.sqrt(math.add(math.mean(eel, [(eel[String("shape")][String("length")]-ibex[0]), (eel[String("shape")][String("length")]-ibex[1]), (eel[String("shape")][String("length")]-ibex[2])], true), fish)))), math.reshape(model.weights[47], [louse[3], louse[2], louse[1], louse[0]])); - }; - function prairiedog(dolphin) { - return math.add(math.transpose(math.conv2d(math.transpose(dolphin, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[48], [2, 3, 1, 0], dolphin), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[49]); - }; - let kangaroo = math.tensor(1.0e-5); - function elk(falcon) { - let alpaca = falcon[String("shape")][String("length")]; - let caterpillar = [].fill.apply(Array(alpaca), [1]); - let panda = [].concat.call(flux.range(1, (alpaca-2)), alpaca); - let beaver = math.mean(falcon, [(falcon[String("shape")][String("length")]-panda[0]), (falcon[String("shape")][String("length")]-panda[1]), (falcon[String("shape")][String("length")]-panda[2])], true); - let boar = math.pow(math.sub(falcon, beaver), model.weights[51]); - caterpillar[(alpaca-2)] = falcon[String("shape")][(falcon[String("shape")][String("length")]-(alpaca-1))]; - return math.add(math.mul(math.reshape(model.weights[50], [caterpillar[3], caterpillar[2], caterpillar[1], caterpillar[0]]), math.div(math.sub(falcon, beaver), tf.sqrt(math.add(math.mean(boar, [(boar[String("shape")][String("length")]-panda[0]), (boar[String("shape")][String("length")]-panda[1]), (boar[String("shape")][String("length")]-panda[2])], true), kangaroo)))), math.reshape(model.weights[52], [caterpillar[3], caterpillar[2], caterpillar[1], caterpillar[0]])); - }; - function peafowl(cod) { - return math.add(math.transpose(math.conv2d(math.transpose(cod, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[53], [2, 3, 1, 0], cod), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[54]); - }; - function ferret(wombat) { - return math.add(wombat, cat(prairiedog(math.relu(elk(peafowl(wombat)))))); - }; - let dunlin = math.tensor(1.0e-5); - function donkey(kudu) { - let aardvark = kudu[String("shape")][String("length")]; - let elephant = [].fill.apply(Array(aardvark), [1]); - let bat = [].concat.call(flux.range(1, (aardvark-2)), aardvark); - let magpie = math.mean(kudu, [(kudu[String("shape")][String("length")]-bat[0]), (kudu[String("shape")][String("length")]-bat[1]), (kudu[String("shape")][String("length")]-bat[2])], true); - let pelican = math.pow(math.sub(kudu, magpie), model.weights[56]); - elephant[(aardvark-2)] = kudu[String("shape")][(kudu[String("shape")][String("length")]-(aardvark-1))]; - return math.add(math.mul(math.reshape(model.weights[55], [elephant[3], elephant[2], elephant[1], elephant[0]]), math.div(math.sub(kudu, magpie), tf.sqrt(math.add(math.mean(pelican, [(pelican[String("shape")][String("length")]-bat[0]), (pelican[String("shape")][String("length")]-bat[1]), (pelican[String("shape")][String("length")]-bat[2])], true), dunlin)))), math.reshape(model.weights[57], [elephant[3], elephant[2], elephant[1], elephant[0]])); - }; - function bee(seahorse) { - return math.add(math.transpose(math.conv2d(math.transpose(seahorse, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[58], [2, 3, 1, 0], seahorse), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[59]); - }; - let loris = math.tensor(1.0e-5); - function tarsier(fox) { - let salamander = fox[String("shape")][String("length")]; - let hedgehog = [].fill.apply(Array(salamander), [1]); - let mammoth = [].concat.call(flux.range(1, (salamander-2)), salamander); - let crab = math.mean(fox, [(fox[String("shape")][String("length")]-mammoth[0]), (fox[String("shape")][String("length")]-mammoth[1]), (fox[String("shape")][String("length")]-mammoth[2])], true); - let ant = math.pow(math.sub(fox, crab), model.weights[61]); - hedgehog[(salamander-2)] = fox[String("shape")][(fox[String("shape")][String("length")]-(salamander-1))]; - return math.add(math.mul(math.reshape(model.weights[60], [hedgehog[3], hedgehog[2], hedgehog[1], hedgehog[0]]), math.div(math.sub(fox, crab), tf.sqrt(math.add(math.mean(ant, [(ant[String("shape")][String("length")]-mammoth[0]), (ant[String("shape")][String("length")]-mammoth[1]), (ant[String("shape")][String("length")]-mammoth[2])], true), loris)))), math.reshape(model.weights[62], [hedgehog[3], hedgehog[2], hedgehog[1], hedgehog[0]])); - }; - function eagle(horse) { - return math.add(math.transpose(math.conv2d(math.transpose(horse, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[63], [2, 3, 1, 0], horse), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[64]); - }; - function goose(partridge) { - return math.add(partridge, donkey(bee(math.relu(tarsier(eagle(partridge)))))); - }; - let gerbil = math.tensor(1.0e-5); - function chinchilla(rook) { - let lark = rook[String("shape")][String("length")]; - let barracuda = [].fill.apply(Array(lark), [1]); - let herring = [].concat.call(flux.range(1, (lark-2)), lark); - let antelope = math.mean(rook, [(rook[String("shape")][String("length")]-herring[0]), (rook[String("shape")][String("length")]-herring[1]), (rook[String("shape")][String("length")]-herring[2])], true); - let mongoose = math.pow(math.sub(rook, antelope), model.weights[66]); - barracuda[(lark-2)] = rook[String("shape")][(rook[String("shape")][String("length")]-(lark-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[65], [barracuda[3], barracuda[2], barracuda[1], barracuda[0]]), math.div(math.sub(rook, antelope), tf.sqrt(math.add(math.mean(mongoose, [(mongoose[String("shape")][String("length")]-herring[0]), (mongoose[String("shape")][String("length")]-herring[1]), (mongoose[String("shape")][String("length")]-herring[2])], true), gerbil)))), math.reshape(model.weights[67], [barracuda[3], barracuda[2], barracuda[1], barracuda[0]]))); - }; - function narwhal(chicken) { - return math.add(math.transpose(math.conv2d(math.transpose(chicken, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[68], [2, 3, 1, 0], chicken), [0, 1]), [2, 2], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[69]); - }; - let hippopotamus = math.tensor(1.0e-5); - function coyote(finch) { - let reddeer = finch[String("shape")][String("length")]; - let cobra = [].fill.apply(Array(reddeer), [1]); - let pigeon = [].concat.call(flux.range(1, (reddeer-2)), reddeer); - let reindeer = math.mean(finch, [(finch[String("shape")][String("length")]-pigeon[0]), (finch[String("shape")][String("length")]-pigeon[1]), (finch[String("shape")][String("length")]-pigeon[2])], true); - let cormorant = math.pow(math.sub(finch, reindeer), model.weights[71]); - cobra[(reddeer-2)] = finch[String("shape")][(finch[String("shape")][String("length")]-(reddeer-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[70], [cobra[3], cobra[2], cobra[1], cobra[0]]), math.div(math.sub(finch, reindeer), tf.sqrt(math.add(math.mean(cormorant, [(cormorant[String("shape")][String("length")]-pigeon[0]), (cormorant[String("shape")][String("length")]-pigeon[1]), (cormorant[String("shape")][String("length")]-pigeon[2])], true), hippopotamus)))), math.reshape(model.weights[72], [cobra[3], cobra[2], cobra[1], cobra[0]]))); - }; - function gaur(weasel) { - return math.add(math.transpose(math.conv2d(math.transpose(weasel, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[73], [2, 3, 1, 0], weasel), [0, 1]), [2, 2], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[74]); - }; - let opossum = math.tensor(1.0e-5); - function fly(sloth) { - let whale = sloth[String("shape")][String("length")]; - let leopard = [].fill.apply(Array(whale), [1]); - let camel = [].concat.call(flux.range(1, (whale-2)), whale); - let cheetah = math.mean(sloth, [(sloth[String("shape")][String("length")]-camel[0]), (sloth[String("shape")][String("length")]-camel[1]), (sloth[String("shape")][String("length")]-camel[2])], true); - let pony = math.pow(math.sub(sloth, cheetah), model.weights[76]); - leopard[(whale-2)] = sloth[String("shape")][(sloth[String("shape")][String("length")]-(whale-1))]; - return math.relu(math.add(math.mul(math.reshape(model.weights[75], [leopard[3], leopard[2], leopard[1], leopard[0]]), math.div(math.sub(sloth, cheetah), tf.sqrt(math.add(math.mean(pony, [(pony[String("shape")][String("length")]-camel[0]), (pony[String("shape")][String("length")]-camel[1]), (pony[String("shape")][String("length")]-camel[2])], true), opossum)))), math.reshape(model.weights[77], [leopard[3], leopard[2], leopard[1], leopard[0]]))); - }; - function frog(goat) { - return math.add(math.transpose(math.conv2d(math.transpose(goat, [0, 2, 3, 1]), math.reverse(math.transpose(model.weights[78], [2, 3, 1, 0], goat), [0, 1]), [1, 1], 1, "NHWC", [1, 1], "floor"), [0, 3, 1, 2]), model.weights[79]); - }; - function model(grouse) { - return rhinoceros(turkey(tapir(yak(waterbuffalo(giraffe(dragonfly(termite(ferret(goose(chinchilla(narwhal(coyote(gaur(fly(frog(grouse)))))))))))))))); - }; - model.weights = []; - return model; -})(); \ No newline at end of file diff --git a/experiments/styleTransfer/assets/js/helpers.js b/experiments/styleTransfer/assets/js/helpers.js deleted file mode 100644 index 2a475acc..00000000 --- a/experiments/styleTransfer/assets/js/helpers.js +++ /dev/null @@ -1,50 +0,0 @@ -// general -var $$ = (e)=> document.querySelector(e); - -function getImageCanvas(screen, width, height){ - var canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - canvas.getContext('2d').drawImage(screen, 0, 0, height, width); - return canvas -} - -function _transformInput(canvas){ - return canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height) -} - -function _transformOutput(res){ - return imagedata_to_image(res) -} - -var timeOut = null; - -function showErr(msg){ - $$(".msg").innerText = msg; - if(timeOut == null) - $$(".msg").className += " in"; - clearTimeout(timeOut); - timeOut = setTimeout(()=>{ - $$(".msg").className = $$(".msg").className.replace(" in", ""); - timeOut = null; - }, 3000); -} - -function getImageData(img){ - var canvas = document.createElement('canvas'); - var context = canvas.getContext('2d'); - var img = document.getElementById('myimg'); - canvas.width = img.width; - canvas.height = img.height; - context.drawImage(img, 0, 0 ); - return context.getImageData(0, 0, img.width, img.height); -} - -function imagedata_to_uri(imagedata) { - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - canvas.width = imagedata.width; - canvas.height = imagedata.height; - ctx.putImageData(imagedata, 0, 0); - return canvas.toDataURL(); -} \ No newline at end of file diff --git a/experiments/styleTransfer/assets/js/mediaStream.js b/experiments/styleTransfer/assets/js/mediaStream.js deleted file mode 100644 index 4e070f6c..00000000 --- a/experiments/styleTransfer/assets/js/mediaStream.js +++ /dev/null @@ -1,27 +0,0 @@ -// setup media stream -var constraints = { - video: {width: {exact: 256}, height: {exact: 256}} -}; - -function hasGetUserMedia() { - return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia); -} - -function handleSuccess(stream) { - $$('#screenshot-video').srcObject = stream; -} - -function handleError(error) { - console.log("media access rejected", error) - $$(".webcam_input").className += " disabled"; - $$(".webcam_input .pretty_button").className += " disabled"; - $$(".webcam_input .pretty_button").setAttribute("disabled", true) -} - -if (hasGetUserMedia()) { - navigator.mediaDevices.getUserMedia(constraints) - .then(handleSuccess) - .catch(handleError); -} else { - console.log('getUserMedia() is not supported by your browser'); -} diff --git a/experiments/styleTransfer/assets/js/model.js b/experiments/styleTransfer/assets/js/model.js deleted file mode 100644 index 5cc7d8a8..00000000 --- a/experiments/styleTransfer/assets/js/model.js +++ /dev/null @@ -1,86 +0,0 @@ -// dummy model -// var model = { -// predict : () => { return new Promise((a, b)=>{ setTimeout(() => a(null), 100) }) }, -// loadWeights: ()=> { } -// } -(function(obj){ - -var mean = [123.675 ,116.79, 104.04] - -function Model(name, model, loaded=false){ - var _input = null; - this.load = function(){ - if(loaded) return; - console.log("loading", name) - loadWeights('./assets/bson/' + name +'_fluxjs.bson', document.querySelector('.demo_wrapper'), this.onload.bind(this), model) - } - - this.onload = function(){ - console.log("loaded") - loaded = true; - model = wrap(model); - if(_input) this.predict(_input) - } - - this.predict = function(data){ - if(!loaded) { - _input = data - this.load(); - } - - var input = this.pre(data); - var out = model(input); - tf.dispose(input) - return out.data().then(res =>{ - tf.dispose(out) - _input = null - res = this.post(res, data.width, data.height) - - var i = new Uint8ClampedArray(res); - var idata = new ImageData(i, data.width, data.height) - return idata; - }) - - } - - this.pre = function(data){ - var rgb = data.data; - var input = [[], [], []]; - for(var i =0; i< data.height; i++){ - var r = []; - var g = []; - var b = []; - for(var j =0; j< data.width; j++){ - r.push(data.data[i*data.width*4 + j*4] - mean[0]) - g.push(data.data[i*data.width*4 + j*4 + 1] - mean[1]) - b.push(data.data[i*data.width*4 + j*4 + 2] - mean[2]) - } - input[0].push(r) - input[1].push(g) - input[2].push(b) - } - input = tf.tensor([input]) - return input; - } - - this.post = function(res, w,h){ - var t = new Array(w*h*4).fill(255); - for(var c = 0; c< 3; c++){ - for(var i = 0; i< h; i++){ - for(var j = 0; j< w; j++){ - t[i*w*4 + j*4 + c] = res[c*w*h + i*h + j] + mean[c]; - } - } - } - return t; - } - -} - -function wrap(m){ - return (x) => tf.tidy(() => m(x)) -} - -Object.assign(obj, {Model}) - -})(window); \ No newline at end of file diff --git a/experiments/styleTransfer/assets/js/script.js b/experiments/styleTransfer/assets/js/script.js deleted file mode 100644 index 6c3e52e0..00000000 --- a/experiments/styleTransfer/assets/js/script.js +++ /dev/null @@ -1,62 +0,0 @@ - -var __init__ = function (){ - var models = { abstract_art, popsty, starry_night } - - function wrap(n, x){ - return new Model(n, x); - } - - for(var i in models){ - models[i] = wrap(i, models[i]) - } - - // event listeners - $$('#screenshot-button').onclick = function() { - var video = $$('#screenshot-video'); - var canvas = getImageCanvas(video, video.videoWidth, video.videoHeight); - $$('#content-img').src = canvas.toDataURL('image/webp'); - }; - - Array.from($$(".select_style ul").children) - .forEach(e => { - e.onclick = (event)=>{ - $$("#style-img").setAttribute("src", e.querySelector("img").getAttribute("src")); - var name = e.querySelector("img").getAttribute("data-name"); - $$("#style-img").setAttribute("data-name", name); - models[name].load(); - } - }) - - $$("#upload_button").onclick = ()=>{ - $$('#imageReader').click(); - } - - - $$("#generate").onclick = ()=>{ - var conImg = $$("#content-img") - var conCanvas = getImageCanvas(conImg, conImg.width, conImg.height); - var styleName = $$("#style-img").getAttribute("data-name"); - if(conImg.src == ""){ - return showErr("Please choose a content image") - }else if(styleName == null){ - return showErr("Please choose a style image") - } - var model = models[styleName]; - var input = _transformInput(conCanvas); - model.predict(input).then((out)=>{ - if(out != null){ - $$("#output-img").src = imagedata_to_uri(out); - }else{ - console.log(out); - } - }) - } - - $$("#imageReader").onchange = function(){ - var file = this.files[0]; - $$("#content-img").src = window.URL.createObjectURL(file); - } - -} - -__init__(); \ No newline at end of file diff --git a/experiments/styleTransfer/index.html b/experiments/styleTransfer/index.html deleted file mode 100644 index 8c1934f5..00000000 --- a/experiments/styleTransfer/index.html +++ /dev/null @@ -1,119 +0,0 @@ ---- -layout: default ---- - - - - - - - - - - -
-
-

Flux Experiment: Style Transfer Demo

-
- -
-
-
-
-
-
- - -
- -
-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    -
  • -
  • -
  • - -
-
-
-
-
-
-
-
-
-
-
-
-

Content Image

- -
-
-
-
-

Style Image

- -
-
-
-
-
-
-
-
-
- -
-
-
-

Stylized Content

- -
- - -
-
- - -
-
-
-
- gvjhk -
-
-
-
- - - - - - - - - - - - diff --git a/getting_started.md b/getting_started.md index 25b9e510..c255f656 100644 --- a/getting_started.md +++ b/getting_started.md @@ -1,7 +1,6 @@ ---- -layout: page -title: Getting Started ---- ++++ +title = "Getting Started" ++++ Welcome! This section contains information on how to create your first machine learning model using Flux. @@ -18,21 +17,14 @@ After installing Julia, you can install Flux by running the following command in julia> ] add Flux ``` -
- - Alternatively, you can run the following: ```julia julia> using Pkg; Pkg.add("Flux") ``` -
- Flux provides GPU support. For more information on obtaining GPU support, see [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl) and [Flux documentation on GPU support](https://fluxml.ai/Flux.jl/stable/gpu/). -
- ## Getting Help If you run into any issues on your journey learning Flux.jl, please post on Stack Overflow under the [Flux.jl tag](https://stackoverflow.com/questions/tagged/flux.jl) or ask a question on the [Julia Discourse under the Machine Learning domain](https://discourse.julialang.org/c/domain/ml/). @@ -41,8 +33,6 @@ If you run into any issues on your journey learning Flux.jl, please post on Stac In this tutorial, you'll create your first machine learning model using Flux. This is a simple linear regression model that attempts to recover a linear function by looking at noisy examples. -
- ### Step 1: Import Flux To import Flux add the following: @@ -50,7 +40,6 @@ To import Flux add the following: ```julia using Flux ``` -
### Step 2: Create the training data First, we'll write a function that generates our "true" data. We'll use to use Flux to recover `W_truth` and `b_truth` by looking only at examples of the `ground_truth` function. @@ -61,7 +50,6 @@ W_truth = [1 2 3 4 5; b_truth = [-1.0; -2.0] ground_truth(x) = W_truth*x .+ b_truth ``` -
Next, we generate our training data by passing random vectors into the ground truth function. We'll also add Gaussian noise using `randn()` so that it's not *too* easy for Flux to figure out the model. @@ -84,7 +72,6 @@ Next, we define the model we want to use to learn the data. We'll use the same f ```julia model(x) = W*x .+ b ``` -
We need to set the parameters of the model (`W` and `b`) to some initial values. It's fairly common to use random values, so we'll do that: @@ -92,14 +79,14 @@ We need to set the parameters of the model (`W` and `b`) to some initial values. W = rand(2, 5) b = rand(2) ``` -
You can learn more about defining models in this video: +~~~
-
+~~~ ### Step 4: Define a loss function @@ -114,8 +101,6 @@ function loss(x, y) end ``` -
- ### Step 5: Set an optimiser You train a machine learning model by running an optimization algorithm (optimiser) that finds the best parameters (`W` and `b`). The best parameters for a model are the ones that achieve the best score of the `loss` function. Flux provides [Optimisers](https://fluxml.ai/Flux.jl/stable/training/optimisers/) that you can use to train a model. @@ -125,7 +110,6 @@ For this tutorial, we'll use a classic gradient descent optimiser with learning ```julia opt = Descent(0.01) ``` -
### Step 6: Train your model @@ -147,12 +131,7 @@ for (x,y) in train_data end ``` -
- - ->**Note:** With this pattern, it is easy to add more complex learning routines that make use of control flow, distributed compute, scheduling optimisations, etc. Note that the pattern above is a simple Julia *for loop* but it could also be replaced with a *while loop*. - -
+> **Note:** With this pattern, it is easy to add more complex learning routines that make use of control flow, distributed compute, scheduling optimisations, etc. Note that the pattern above is a simple Julia *for loop* but it could also be replaced with a *while loop*. While writing your own loop is powerful, sometimes you just want to do the simple thing without writing too much code. Flux lets you do this with [Flux.train!](https://fluxml.ai/Flux.jl/stable/training/training/#Training-1), which runs one training epoch over a dataset. `Flux.train!` computes gradients and updates model parameters for every sample or batch of samples. In our case, we could have replaced the above loop with the following statement: @@ -160,12 +139,8 @@ While writing your own loop is powerful, sometimes you just want to do the simpl Flux.train!(loss, Flux.params(W, b), train_data, opt) ``` -
- For more ways to train a model in Flux, see [Training](https://fluxml.ai/Flux.jl/stable/training/training/#Training-1). -
- ### Step 7: Examine the Results The training loop we ran modified `W` and `b` to be closer to the values used to generate the training data (`W` and `b`). We can see how well we did by printing out the difference between the learned and actual matrices. @@ -225,8 +200,6 @@ end @show maximum(abs, W .- W_truth) ``` -
- ## What's next diff --git a/governance.md b/governance.md index cb46688c..322a3582 100644 --- a/governance.md +++ b/governance.md @@ -1,9 +1,10 @@ ---- -layout: page -title: Governance ---- ++++ +title = "Governance" ++++ -# FluxML Governance +~~~ +

FluxML Governance

+~~~ The following contains the formal governance structure of the FluxML project. This document clarifies how decisions are made with respect @@ -25,25 +26,31 @@ handled on a case-by-case basis. ### Current Steering Council +@@tight-list - [Michael Abbott](https://github.com/mcabbott) - [Brian Chen](https://github.com/ToucheSir) - [Kyle Daruwalla](https://github.com/darsnack) - [Carlo Lucibello](https://github.com/CarloLucibello) - [Lorenz Ohly](https://github.com/lorenzoh) +@@ ### Advisory Committee +@@tight-list - [Frames Catherine White](https://github.com/oxinabox) +@@ ### Former Steering Council +@@tight-list - [Mike Innes](https://github.com/MikeInnes) (2016-2020) - [Dhairya Gandhi](https://github.com/DhairyaLGandhi) (2018-2020) - [Elliot Saba](https://github.com/staticfloat) (2018-2020) +@@ -# Governing Rules and Duties +## Governing Rules and Duties -## Steering Council +### Steering Council The Project has a Steering Council that consists of Project Contributors who have produced contributions that are substantial in @@ -81,7 +88,7 @@ Steering Council decisions are taken by simple majority, with the exception of changes to the Governance Documents which follow the procedure in the section 'Changing the Governance Documents'. -### Steering Council membership +#### Steering Council membership To become eligible for being a Steering Council Member, an individual must be a Project Contributor who has produced contributions that are @@ -120,14 +127,14 @@ The Council reserves the right to eject current Members if they are deemed to be actively harmful to the Project's well-being, and attempts at communication and conflict resolution have failed. -## Fiscal Decisions +### Fiscal Decisions All fiscal decisions are made by the steering council to ensure any funds are spent in a manner that furthers the mission of the Project. Fiscal decisions require majority approval by acting steering council members. -## Advisory Committee +### Advisory Committee The Project has an Advisory Committee that works to ensure the long-term well-being of the Project. The Committee advises the Steering Council and @@ -137,7 +144,7 @@ the Council, and the Committee will meet annually to review Project activities. Committee decisions are taken in consensus. Members of the Advisory Committee are appointed by the Steering Council. -## Conflict of interest +### Conflict of interest It is expected that Steering Council and Advisory Committee Members will be employed at a wide range of companies, universities and non-profit diff --git a/gsoc.md b/gsoc.md index cb626136..908017d5 100644 --- a/gsoc.md +++ b/gsoc.md @@ -1,28 +1,31 @@ ---- -layout: page -title: Google Summer of Code ---- ++++ +title = "Google Summer of Code" ++++ -# FluxML Projects - Summer of Code +~~~ +

FluxML Projects - Summer of Code

+~~~ Flux usually takes part in [Google Summer of Code](https://summerofcode.withgoogle.com) as a NumFocus organization. We follow the same [rules and application guidelines](https://julialang.org/jsoc/projects/) as Julia, so please check there for more information on applying. Below are a set of ideas for potential projects (though you are welcome to explore anything you are interested in). Flux projects are typically very competitive; we encourage you to get started early, as successful contributors typically have early PRs or working prototypes as part of the application. It is a good idea to simply start contributing via issue discussion and PRs and let a project grow from there; you can take a look at [this list of issues](https://github.com/FluxML/Flux.jl/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) for some starter contributions. -### Metalhead.jl Developement +## Metalhead.jl Developement **Difficulty:** Medium (175h) **Expected outcomes:** Help us improve [Metalhead.jl](https://github.com/FluxML/Metalhead.jl) by +@@tight-list - adding new models - porting pre-trained weights - extending the model interfaces to make them more customizable +@@ **Skills:** Familiarity with vision model architectures and Flux.jl **Mentors:** [Kyle Daruwalla](https://github.com/darsnack) -### FastAI.jl Time Series Development +## FastAI.jl Time Series Development **Difficulty:** Medium (350h) @@ -35,16 +38,18 @@ In this project, you will assist the [ML community team](https://julialang.zulip @@ **Expected outcomes:** You will +@@tight-list - load a working time series dataset using the FastAI.jl data registry - create new block methods for time series tasks - load at least one working time series model into a learner - develop an example tutorial that ties all the previous steps together +@@ **Skills:** Familiarity with deep learning pipelines, common practices, Flux.jl, and recurrent neural networks **Mentors:** [Lorenz Ohly](https://github.com/lorenzoh), [Kyle Daruwalla](https://github.com/darsnack), [Brian Chen](https://github.com/ToucheSir) -### FastAI.jl Text Development +## FastAI.jl Text Development **Difficulty:** Medium (350h) @@ -57,30 +62,34 @@ In this project, you will assist the [ML community team](https://julialang.zulip @@ **Expected outcomes:** You will +@@tight-list - load a working text dataset using the FastAI.jl data registry - create new block methods for textual tasks - load at least one working text model into a learner - develop an example tutorial that ties all the previous steps together +@@ **Skills:** Familiarity with deep learning pipelines, common practices, Flux.jl, and JuliaText **Mentors:** [Lorenz Ohly](https://github.com/lorenzoh), [Kyle Daruwalla](https://github.com/darsnack), [Brian Chen](https://github.com/ToucheSir) -### Differentiable Computer Vision +## Differentiable Computer Vision **Difficulty:** Hard (350h) Create a library of utility functions that can consume Julia's imaging libraries to make them differentiable. With Zygote.jl, we have the platform to take a general purpose package and apply automatic differentiation to it. **Expected outcomes:** You will +@@tight-list - write AD rules for functions in existing computer vision libraries - demonstrate the use of these newly differentiable libraries for tasks such as homography regression +@@ **Skills:** Familiarity with automatic differentiation, deep learning, and defining (a lot of) custom adjoints **Mentors:** [Dhairya Gandhi](https://github.com/DhairyaLGandhi/) -### FermiNets: Generative Synthesis for Automating the Choice of Neural Architectures +## FermiNets: Generative Synthesis for Automating the Choice of Neural Architectures **Difficulty:** Hard (175h) @@ -90,16 +99,18 @@ The application of machine learning requires a practitioner to understand how to **Mentors:** [Chris Rackauckas](https://github.com/ChrisRackauckas) and [Dhairya Gandhi](https://github.com/DhairyaLGandhi/) -### Differentiable Rendering +## Differentiable Rendering **Difficulty:** Hard (350h+) We have an existing package, [RayTracer.jl](https://github.com/avik-pal/RayTracer.jl), which is motivated by OpenDR and exists to do differentiable raytracing with Flux.jl and Zygote.jl. **Expected outcomes:** You will +@@tight-list - implement at least 2 alternative rendering models like NeRF, VolSDF, Neural Raytracing, etc. - make improvements to RayTracer.jl to use the latest Flux libraries - update RayTracer.jl for ChainRules.jl +@@ **Skills:** GPU programming, deep learning, familiarity with the literature, familiarity with defining custom adjoints diff --git a/gsod.md b/gsod.md deleted file mode 100644 index bca4e5a9..00000000 --- a/gsod.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: blog -title: Google Season of Docs ---- - -The Flux project is a participant in Google Season of Docs. In 2020, we had a technical writer work on [our website](https://www.youtube.com/watch?v=6s9J-ObQaAs&feature=emb_imp_woyt). The project was a success and we have since then build out various projects specifically for interested technical writers. - - -## Projects - -[Flux.jl](https://github.com/FluxML/Flux.jl) is an elegant approach to machine learning in Julia. It is designed to be hackable and flexible, extendable, and exposes powerful AD tools. It also provides abstractions over the popular layers and optimizers used in neural networks. It is built with differentiable programming in mind. The mentors for this project are [Dhairya Gandhi](https://github.com/DhairyaLGandhi). - -- #### Tutorials - - Flux is in dire need of complete tutorials in the [model-zoo](https://github.com/FluxML/model-zoo.git) as well as on the website. We can take inspiration from many existing projects that publish their tutorials, that take a look at common design patterns. This includes writing custom adjoints, new optimizers, transfer learning, and writing performance-sensitive code for many common kinds of networks that many people would be interested in writing. - This could also include cases that help users write custom loss functions, and even putting Flux models behind a web server. - -- ### Updated Documentation and DocTests - - Flux documentation needs a lot of rework since our generic approach to development means there are many general use cases that we support but might be a bit subtle to discover. So in that case, we need to highlight such common cases and make them known in the documentation. - We would like to use doc tests to also increase our coverage of and documentation of many of the common patterns we see in differentiating Julia code. - -#### Potential Impact - - Flux is an innovative approach to machine learning. This also means that not all the same patterns and assumptions truly hold when translating from a different framework. It also needs a way to communicate a compelling description of how to implement many of the user-facing niceties that one might need in the course of completing an ML project. Through this, we want to also find areas of improvement where we could offer a better user experience. - - This would also greatly benefit the adoption of Flux in the larger ML ecosystem, which we feel is currently held back due to not having enough of these simple patterns documented in an approachable form. We want to see an increase in the number of contributors to the various packages too since that would help us improve our stack better. Flux also utilizes simple to understand and performant code, made possible by Julia, and through this, we also want to bring awareness to how our ecosystem has matured, and increase its adoption in research and industry. diff --git a/index.html b/index.html deleted file mode 100755 index 34c47061..00000000 --- a/index.html +++ /dev/null @@ -1,323 +0,0 @@ ---- -layout: default -title: Elegant ML ---- - - - - -
-
- -

The Elegant Machine Learning Stack

- Flux is a 100% pure-Julia stack and provides lightweight abstractions on top of Julia's native GPU - and AD support. It makes the easy things easy while remaining fully hackable. - -
-
- - -
-
-
-
-

Features

- Flux has features that sets it apart among ML systems. -
-
-
-
-
Compiled Eager Code
-

- Flux provides a single, intuitive way to define models, just like mathematical notation. - Julia transparently compiles your code, optimising and fusing kernels for the GPU, for the best performance. -

-
- -
-
Differentiable Programming
-

- Existing Julia libraries are differentiable and can be incorporated directly into Flux models. - Cutting edge models such as Neural ODEs are first class, and Zygote enables overhead-free gradients. -

-
- -
-
First-class GPU support
-

- GPU kernels can be written directly in Julia via CUDA.jl. - Flux is uniquely hackable and any part can be tweaked, from GPU code to custom gradients and layers. -

-
-
-
-
-
The Model Zoo
-

- A rich collection of Flux scripts to learn from, or tweak to your own data. - Trained Flux models can be used from TextAnalysis or Metalhead. -

-
- -
-
TPUs & Colab
-

- Flux models can be compiled to TPUs for cloud supercomputing, and run from Google Colab notebooks. -

-
-
-
-
- -
-
-
-
-

- Ecosystem - See all -

- Flux has a diverse ecosystem that includes models available for reuse and other useful packages. -
-
-
- -
-
Probabilistic Programming
-

- The Turing.jl and Stheno libraries enable probabilistic programming, bayesian inference and Gaussian processes on top of Flux. -

-
- -
-
GeometricFlux
-

- GeometricFlux.jl is a geometric deep learning library for Flux and has support of CUDA GPU acceleration with CUDA. -

-
- -
-
Metalhead
-

- Metalhead.jl includes many state-of-the-art computer vision models which can easily be used for transfer learning. -

-
-
-
-
-
SciML
-

- The SciML ecosystem uses Flux and Zygote to mix neural nets with differential equations, to get the best of black box and mechanistic modelling. -

-
- -
-
Transformers
-

- Transformers.jl provides components for Transformer models for NLP, as well as providing several trained models out of the box. -

-
- -
-
DiffEqFlux
-

- DiffEqFlux.jl provides tools for creating Neural Differential Equations. -

-
-
- -
-
- -
-
-
-
-

Community

- Get in touch with the Flux community. -
-
-
-
-
Community team
-

- Join the group of community maintainers supporting the FluxML ecosystem. Talk to us on Zulip! 👉 -

-
- -
-
Slack
-

- Official Julia Slack for casual conversation. See #flux-bridged and #machine-learning. -

-
- -
-
Zulip
-

- Zulip server for the Julia programming language community. See #ml-contributors and #machine-learning. -

-
-
-
-
-
Discourse forum
-

- Machine Learning in Julia community. -

-
- -
-
Stack Overflow
-

- Ask questions about Flux.jl. -

-
-
- -
-
- -
-
-
-
-

Why Flux?

-
-
-
- -
-
-
- - -
-
-
-

Researchers, users, and developers of Flux

-
-
    -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
-
-
diff --git a/index.md b/index.md new file mode 100644 index 00000000..b15cbd6a --- /dev/null +++ b/index.md @@ -0,0 +1,266 @@ + +@@jumbotron,jumbotron-fluid,no-pad + @@container + ~~~ + +

The Elegant Machine Learning Stack

+ Flux is a 100% pure-Julia stack and provides lightweight abstractions on top of Julia's native GPU and AD support. It makes the easy things easy while remaining fully hackable. + ~~~ + + @@buttons + ~~~ + Try It Out + GitHub + Follow on Twitter + ~~~ + @@ + @@ +@@ + +@@features + @@container + @@row + @@col-md-12,feature-title + ~~~ +

Features

+ ~~~ + Flux has features that sets it apart among ML systems. + @@ + @@ + + @@row + @@col-md,feature + ~~~ +
Compiled Eager Code
+ ~~~ + Flux provides a single, intuitive way to define models, just like mathematical notation. Julia transparently [compiles your code](https://julialang.org/blog/2018/12/ml-language-compiler), optimising and fusing kernels for the GPU, for the best performance. + @@ + @@col-md,feature + ~~~ +
Differentiable Programming
+ ~~~ + Existing Julia libraries are differentiable and can be incorporated directly into Flux models. Cutting edge models such as [Neural ODEs](https://julialang.org/blog/2019/01/fluxdiffeq) are first class, and [Zygote](https://github.com/FluxML/Zygote.jl) enables overhead-free gradients. + @@ + @@col-md,feature + ~~~ +
First-class GPU support
+ ~~~ + GPU kernels can be written directly in Julia via [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl). Flux is uniquely hackable and any part can be tweaked, from GPU code to custom gradients and layers. + @@ + @@ + @@ +@@ + +@@features + @@container + @@row + @@col-md-12,feature-title + ~~~ +

+ Ecosystem +

+ ~~~ + Flux has a diverse ecosystem that includes models available for reuse and other useful packages. + @@ + @@col-md-12,feature-title + ~~~ + See all + ~~~ + @@ + @@ + + @@row + @@col-md,feature + ~~~ +
Probabilistic Programming
+ ~~~ + The [Turing.jl](https://github.com/TuringLang/Turing.jl) and [Stheno.jl](https://github.com/willtebbutt/Stheno.jl) libraries enable probabilistic programming, Bayesian inference and Gaussian processes on top of Flux. + @@ + @@col-md,feature + ~~~ +
Graph Neural Networks
+ ~~~ + [GraphNeuralNetworks.jl](https://github.com/CarloLucibello/GraphNeuralNetworks.jl) is a graph neural network library for Flux and supports CUDA GPU acceleration. + @@ + @@col-md,feature + ~~~ +
Computer Vision
+ ~~~ + [Metalhead.jl](https://github.com/FluxML/Metalhead.jl) includes many state-of-the-art computer vision models with pre-trained weights. + @@ + @@ + + @@row + @@col-md,feature + ~~~ +
SciML
+ ~~~ + The [SciML](https://sciml.ai/) ecosystem uses the FluxML stack to mix neural nets with differential equations, to get the best of black box and mechanistic modelling. + @@ + @@col-md,feature + ~~~ +
Natural Language Processing
+ ~~~ + [Transformers.jl](https://github.com/chengchingwen/Transformers.jl) provides components for transformer architectures for language modeling, as well as providing several trained models out of the box. + @@ + @@ + @@ +@@ + +@@features + @@container + @@row + @@col-md-12,feature-title + ~~~ +

Community

+ ~~~ + Get in touch with the Flux community. + @@ + @@ + + @@row + @@col-md,feature + ~~~ +
Community team
+ ~~~ + Flux is maintained by community team (see our [governance model](/governance)). + Join us or talk to us on Zulip! 👉 + @@ + @@col-md,feature + ~~~ +
Slack
+ ~~~ + [Official Julia Slack](https://julialang.org/slack/) for casual conversation. See `#flux-bridged` and `#machine-learning`. + @@ + @@col-md,feature + ~~~ +
Zulip
+ ~~~ + [Zulip server](https://julialang.zulipchat.com) for the Julia programming language community. See `#ml-contributors` and `#machine-learning`. + @@ + @@ + + @@row + @@col-md,feature + ~~~ +
Discourse forum
+ ~~~ + [Machine Learning in Julia](https://discourse.julialang.org/c/domain/ML/24) community. + @@ + @@col-md,feature + ~~~ +
Stack Overflow
+ ~~~ + [Ask questions](https://stackoverflow.com/questions/tagged/flux.jl) about Flux.jl. + @@ + @@col-md,feature + ~~~ +
Contribute!
+ ~~~ + Help us by [contributing code](https://github.com/FluxML/Flux.jl/blob/master/CONTRIBUTING.md)! + @@ + @@ + @@ +@@ + +@@features + @@container + @@row + @@col-md-12,feature-title + ~~~ +

Why Flux?

+ ~~~ + @@ + @@ + + @@row + ~~~ + + ~~~ + @@ + @@ +@@ + +@@friends + @@container + @@row + @@col-md-12,feature-title + ~~~ +

Researchers, users, and developers of Flux

+ ~~~ + @@ + @@ + + @@row + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@ + + @@row + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@ + + @@row + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@ + + @@row + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@col-md + ~~~ + + ~~~ + @@ + @@ + @@ +@@ diff --git a/poirot.png b/poirot.png deleted file mode 100644 index cbe43c44..00000000 Binary files a/poirot.png and /dev/null differ diff --git a/site.scss b/site.scss deleted file mode 100644 index c029241e..00000000 --- a/site.scss +++ /dev/null @@ -1,114 +0,0 @@ ---- ---- - -$light-green: rgb(235, 245, 235); - -@import url('https://fonts.googleapis.com/css?family=Lato:400,400i'); - -.octicon { - display: inline-block; - vertical-align: text-bottom; - fill: currentColor; -} - -body { - background: rgb(20,60,60); - font-family: Lato, "Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; - line-height: 1.7; -} - -.logo { - font-style: italic; -} - -.navbar .logo { - text-shadow: 2px 2px 5px rgba(0,0,0,0.1); -} - -.content { - background: rgb(240, 250, 250); - - .container { - background: white; - padding-top: 2em; - padding-bottom: 2em; - } - - h1 { - font-size: 20pt; - padding-bottom: 0.2em; - border-bottom: 3px solid $light-green; - text-align: center; - font-weight: bold; - margin-bottom:1em; - } - h2 { - font-size: 18pt; - text-align: right; - margin-top:2em; - } - h3 { - font-size: 12pt; - font-weight: bold; - } - - blockquote { - font-style: italic; - border-left: 5px solid $light-green; - padding-left: 1em; - margin-left: 1em; - } - - .author { - text-align: right; - font-style: italic; - color: rgb(0, 150, 150); - } - .attrib { - font-style: italic; - color: rgb(0, 50, 50); - } -} - -.lighter { - font-weight: 300; - letter-spacing: 1px; -} - -/*Links*/ -p a, p a:visited { border-bottom: 2px solid rgb(180, 220, 220); } -p a:hover, p a:visited:hover { color: rgb(0, 100, 100); text-decoration: none; } - -p a, p a:visited { color: rgb(0, 100, 100); } -p a:hover { border-bottom: 2px solid rgb(0, 170, 170); } - -/*Footer*/ -.call { - padding-top: 2em; - padding-bottom: 2em; - text-align: center; -} -.call p:last-child { - margin: 0; -} -.footer { - margin-top: 1.5rem; - margin-bottom: 3rem; - color: white; -} - -/*Code*/ -pre { - margin: 0; -} -pre code.hljs { - background: rgb(245, 255, 255); - border: 2px solid rgb(200, 240, 240); - border-radius: 5px; - padding-left: 1em; - padding-right: 1em; -} - -.navbar-collapse.collapse.in { - display: block!important; -} diff --git a/tools/colors/colors.css b/tools/colors/colors.css deleted file mode 100644 index 9cefab42..00000000 --- a/tools/colors/colors.css +++ /dev/null @@ -1,6 +0,0 @@ -/* define colors */ -:root{ - --dark: #213b3b; - --light: #f2faf9; - --medium: #478383; -} \ No newline at end of file diff --git a/tools/fluxjs/flux.js b/tools/fluxjs/flux.js deleted file mode 100644 index 38f05b78..00000000 --- a/tools/fluxjs/flux.js +++ /dev/null @@ -1,75 +0,0 @@ -flux = (function () { - -let Buffer = new BSON().serialize({}).constructor - -function blobAsArrayBuffer(blob) { - return new Promise((resolve, reject) => { - let reader = new FileReader(); - reader.addEventListener("loadend", function() { - resolve(reader.result); - }); - reader.readAsArrayBuffer(blob); - }); -} - -async function fetchBytes(url) { - let resp = await fetch(url); - if (!resp.ok) throw(resp); - let blob = await resp.blob(); - let buf = await blobAsArrayBuffer(blob); - return new Buffer(buf); -} - -async function fetchData(url) { - let buf = await fetchBytes(url); - return new BSON().deserialize(buf); -} - -// `buf` is a Uint8Array from BSON -function readFloat32(buf) { - let view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); - let data = new Float32Array(view.byteLength/4); - for (i = 0; i < data.length; i++) { - data[i] = view.getFloat32(i*4, true); - } - return data; -} - -function toTensor_(spec) { - let type = spec.type.name; - type = type[type.length-1]; - if (type == 'Float32') spec.data = readFloat32(spec.data.buffer); - else throw `Array type ${spec.type.name} not supported.`; - let array = tf.tensor(spec.data, spec.size.reverse()); - return array -} - -function convertArrays_(data) { - if (!(typeof data == "object")) return data - if (data.tag == "array") { - return toTensor_(data); - } else { - for (k of Object.keys(data)) { - data[k] = convertArrays_(data[k]) - } - } - return data; -} - -async function fetchBlob(url) { - data = await fetchData(url); - return convertArrays_(data) -} - -async function fetchWeights(url) { - ws = await fetchBlob(url); - return ws.weights; -} - -const _data = t => (t instanceof tf.Tensor)? t.dataSync(): t; -const slice = t => (t instanceof tf.Tensor)? t.clone():( - t instanceof Array ? t.slice() : t ); - -return {fetchData, fetchWeights, fetchBlob, convertArrays_, data: _data, slice}; - -})(); diff --git a/tools/game/css/overlay.css b/tools/game/css/overlay.css deleted file mode 100644 index e97b8782..00000000 --- a/tools/game/css/overlay.css +++ /dev/null @@ -1,34 +0,0 @@ -.overlay{ - pointer-events: none; -} - -.overlay > * { - top:0; - bottom: 0; - left: 0; - right: 0; - background: rgba(0, 0,0, .4); - transition: all .5s linear; - opacity: 1; - z-index: 999; - pointer-events: none; -} - -#start, #gameOver{ - display: flex; - -webkit-justify-content: center; - justify-content: center; - align-items: center; - flex-direction: column; -} - -#overlay p{ - height: fit-content; - font-size: 28px; -} - -.hidden{ - opacity: 0; - pointer-events: none; -} - diff --git a/tools/game/css/style.css b/tools/game/css/style.css deleted file mode 100644 index 65114327..00000000 --- a/tools/game/css/style.css +++ /dev/null @@ -1,138 +0,0 @@ -.demo_wrapper { - margin: 0px auto; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} - -.instructions{ - margin: 40px 0 0 0; - background: var(--light); - padding: 20px; - border-radius: 6px; - /* box-sizing: border-box; */ - text-align: justify; - width: 100%; -} - -.code_link{ - width: fit-content; - /* background: #ffffff; */ - border: 1px solid; - padding: 5px 10px; - border-radius: 3px; - color: var(--dark); - float: right; - font-weight: 900; -} - -.board{ - position: relative; - color: #fff; -} - -.board > *, .overlay > *{ - position: absolute; -} - -.board > *, .game-over{ - top:0; - left:0; - right: 0; - bottom: 0; -} - -.overlay .keyboard{ - - right: 10px !important; - top: 10px; - width: 100px; - height: 50px; - -} - -.game-over{ - display: flex; - justify-content: center; - align-items: center; - background: rgba(0,0,0,0.7); - transition: all .4s linear; - opacity: 1; -} - -.hidden-screen{ - opacity: 0; -} - -.game-over p{ - font-size: 2em; -} - -#controls{ - background: var(--light); - color: var(--dark); - /*margin: 10px;*/ - border-top-left-radius: 6px; - border-top-right-radius: 6px; - - box-sizing: border-box; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-justify-content: space-between; - justify-content: space-between; - -} - -#controls .heading{ - padding: 20px; - font-size: 1.2em; -} - -#controls .options{ - display: flex; - justify-content: space-between; - align-items: center; -} - - -#controls .comp{ - background: url("../img/comp.png") 0 0 no-repeat; - background-size: 20px; -} - -#controls .human{ - background: url("../img/human.png") 0 0 no-repeat; - background-size: 20px; -} - -#controls .comp, #controls .human{ - cursor: pointer; - width: 30px; - height: 30px; - margin: 10px 20px 10px 0; - background-position: center; - /*border-left: 1px solid #aaa;*/ -} - -#controls .option{ - border-radius: 50%; - background-color: #777; - /*transition: all .6s linear;*/ -} - -#controls .options .selected{ - background-color: var(--dark); - transform: scale(1.1); - box-shadow: 0 2px 2px #333; -} - -#game { - width: 500px; - margin: 30px auto; - box-shadow: 2px 3px 5px #aaa; - border-radius: 6px; - overflow: hidden; -} diff --git a/tools/game/img/comp.png b/tools/game/img/comp.png deleted file mode 100644 index 0f362b0f..00000000 Binary files a/tools/game/img/comp.png and /dev/null differ diff --git a/tools/game/img/human.png b/tools/game/img/human.png deleted file mode 100644 index 51d41f8b..00000000 Binary files a/tools/game/img/human.png and /dev/null differ diff --git a/tools/game/js/Ball.js b/tools/game/js/Ball.js deleted file mode 100644 index af9d3348..00000000 --- a/tools/game/js/Ball.js +++ /dev/null @@ -1,31 +0,0 @@ -function Ball(pos, speed, {color="#00f", radius=10}={}){ - this.pos = pos; - this.speed = speed; - this.radius = radius; - this.color = color; -} - -Ball.prototype.draw = function (canvas) { - var ctx = canvas.getContext('2d'); - ctx.beginPath(); - ctx.fillStyle = this.color; - ctx.arc(this.pos.x, this.pos.y, this.radius, 0, 2*Math.PI); - ctx.fill(); -} - -Ball.prototype.move = function () { - this.pos.add(this.speed); -} - -Ball.prototype.detectCollision = function (width, height) { // with top, left & right walls - var collisions = []; - if(this.pos.x - this.radius <= 0 || this.pos.x + this.radius >= width)collisions.push([-1, 1]); - if(this.pos.y - this.radius <= 0)collisions.push([1, -1]); - - return collisions; -} - -Ball.prototype.rebound = function ([mx, my]) { - this.speed.x *= mx; - this.speed.y *= my; -} \ No newline at end of file diff --git a/tools/game/js/Game.js b/tools/game/js/Game.js deleted file mode 100644 index 6eac7aaa..00000000 --- a/tools/game/js/Game.js +++ /dev/null @@ -1,180 +0,0 @@ -/***************** - -Game Controller -================ - -env : { - done : () => { done ? (bool) } - step : (action) => { go to next state } - state : () => { return state } - config : () => { rendering info } - reset : () => { reset env } -} - -out : { - render : () { draw } -} - -model : (input tf vector) => { output tf vector } - -*****************/ - - -// interact with env -function Game(env, out, model, { - state=0, - mode="timer", // mode: "async" | "timer" - timeInt=20, - callBacks={}, - transform={ - state: function(state){ - ({ x, xvel , theta, thetavel } = state); - return tf.tensor([x, xvel, theta, thetavel]) - }, - action: function(a){ - var b = tf.argMax(a) - return b.data().then(d => { - tf.dispose(b); - return d[0] + 1; - }); - } - }, - autoReset=false - }={}){ - this.state = state; - this.gameOver = false; - this.env = env; - this.out = out; - this.model = model; - this.mode = mode; - this.timeInt = timeInt; - this.callBacks = callBacks; - this.transform = transform; - this.states = { - H : 0, - C : 1, - "human": 0, - "computer": 1 - }; - this.playTimeout = null; - this.newAction = this.defaultAction(); - this.autoReset = autoReset; -} - -Game.prototype.setTimeInt = function(t){ - this.timeInt = t; -} - -Game.prototype.nextGameState = function(curr){ - return curr; -} - -Game.prototype.startState = function(){ - return this.state -} - -Game.prototype.gameOverHandler = function(){ - this.setState(this.startState()); - this.reset(); -} - -Game.prototype.isValidAction = function(action){ - return true; -} - -Game.prototype.turn = function(string){ - return this.state == this.states[string]; -} - -Game.prototype.action = function(a){ - if(this.gameOver) - return this.gameOverHandler(); - - if(!this.isValidAction(a))return false; - - this.newAction = a; - switch(this.state){ - case this.states.H: - if(this.mode == "async")this.move(this.newAction); // action initiates a move - break; - case this.states.C: - break; - } - - if(typeof(this.callBacks.action) == "function")return this.callBacks.action(a); - return true; -} - -Game.prototype.play = async function(){ - clearTimeout(this.playTimeout); - if(this.env.done())return; - - var scope = this; - switch(this.state){ - case this.states.H: - this.move(this.newAction); - // newAction = 0; - break; - case this.states.C: - var a = await this.predict(this.env.state()) - var action = await this.transform.action(a); - this.move(action); - tf.dispose(a); - break; - default: - console.log("Invalid state", this.state); - } -} - -Game.prototype.next = function(){ - this.state = this.nextGameState(this.state) - if(!this.env.done()){ - var play = this.play.bind(this); - if(this.mode=="timer" || this.state == this.states.C) // play initiates a move - this.playTimeout = setTimeout(play, this.timeInt); - }else{ - var scope = this; - if(this.autoReset)this.gameOverHandler(); - else{ - setTimeout(()=>{ - scope.gameOver = true; // wait 400 ms before resetting - }, 400) - } - } - -} - -Game.prototype.display = function(){ - this.out.render(this.env.config()); -} - -Game.prototype.move = function(a){ - this.env.step(a); - this.display(); - this.next(); -} -Game.prototype.predict = function(state){ - return tf.tidy(()=>{ - var input = this.transform.state(state); - return this.model(input); - }) -} -Game.prototype.reset = function(){ - this.env.reset(); - this.newAction = this.defaultAction(); - this.gameOver = false; - this.display(); -} - -Game.prototype.setState = function(newState){ - this.reset(); - if(typeof(newState) == "string") - this.state = this.states[newState]; - else - this.state = newState; - this.play(); -} - -Game.prototype.defaultAction = function(){ - return 0; -} \ No newline at end of file diff --git a/tools/game/js/Paddle.js b/tools/game/js/Paddle.js deleted file mode 100644 index 159bcf0d..00000000 --- a/tools/game/js/Paddle.js +++ /dev/null @@ -1,39 +0,0 @@ -function Paddle(pos, {color="#f00", width=50, height=10, total_width, total_height}={}){ - this.pos = pos; - this.dir = 0; - - this.total_width = total_width; - this.total_height = total_height; - this.width = width; - this.height = height; - this.color= color; -} - -Paddle.prototype.draw = function (canvas) { - var ctx = canvas.getContext('2d'); - ctx.fillStyle = this.color; - ctx.fillRect(this.pos.x, this.pos.y, this.width, this.height); -} - -Paddle.prototype.move = function () { - this.pos.add(new Vector(this.dir*10, 0)); - if(this.pos.x < 0)this.pos.x = 0; - else if(this.pos.x + this.width > this.total_width) this.pos.x = this.total_width - this.width; -} - -Paddle.prototype.detectCollision = function(ball){ - if(ball.pos.x + ball.radius >= this.pos.x && ball.pos.y + ball.radius >= this.pos.y && ball.pos.x - ball.radius <= this.pos.x + this.width && ball.pos.y <= this.pos.y + this.height){ - return this - } - return null -} - -Paddle.prototype.setDirection = function (d) {this.dir = d;} - -Paddle.prototype.rebound = function (ball) { - var diff = this.pos.x + this.width/2 - ball.pos.x; - ball.rebound([-1, 1]); - ball.speed.y += Math.sign(ball.speed.y); - ball.speed.x = ball.speed.y*diff/this.width; - -} diff --git a/tools/game/js/helpers.js b/tools/game/js/helpers.js deleted file mode 100644 index f2198538..00000000 --- a/tools/game/js/helpers.js +++ /dev/null @@ -1,53 +0,0 @@ -// general helper -function Vector(x, y){ - this.x = x; - this.y = y; - - this.add = (other)=>{ - this.x += other.x; - this.y += other.y; - } -} - -function CircBuf(size){ - this.size = size; - this.buf = new Array(size); - this.index = 0; -} -CircBuf.prototype.fill = function(n){this.buf.fill(n)} -CircBuf.prototype.set = function(n){ - this.buf[this.index] = n; -} -CircBuf.prototype.next = function() { - this.index = (this.index + 1) % this.size; -}; -CircBuf.prototype.sum = function(){ - return this.buf.reduce((acc, ele) => acc + ele, 0) -} - -function randColor(){ - return "#" + Math.floor(Math.random()*999); -} - -function show(ele){ - if(ele.className.match(" hidden") != null){ - ele.className = ele.className.replace(" hidden", ""); - } -} - -function hide(ele){ - if(ele.className.match(" hidden") == null){ - ele.className += " hidden"; - } -} - -var $$ = (s)=>document.querySelector(s); - -function highlight(el, container){ - var old = container.querySelector('.selected'); - if( old != el){ - if(old) - old.className = old.className.replace("selected", ""); - el.className += " selected"; - } -} \ No newline at end of file diff --git a/tools/img/comp.png b/tools/img/comp.png deleted file mode 100644 index 9b12bfe8..00000000 Binary files a/tools/img/comp.png and /dev/null differ diff --git a/tools/img/human.png b/tools/img/human.png deleted file mode 100644 index 09bee02c..00000000 Binary files a/tools/img/human.png and /dev/null differ diff --git a/tools/loadWeights/loadWeights.js b/tools/loadWeights/loadWeights.js deleted file mode 100644 index fc7f43fe..00000000 --- a/tools/loadWeights/loadWeights.js +++ /dev/null @@ -1,38 +0,0 @@ -function loadWeights(url, pc, func, model=null){ - return _loadWeights([{url, model: (model || window.model)}], pc, func); -} - -function _loadWeights(configArr, progressContainer, __init__){ - - let Buffer = new BSON().serialize({}).constructor - - // send an xhr Request so as to show event progress - var config = configArr.map((c)=>{ - var weightsRequest = new XMLHttpRequest(); - weightsRequest.open('GET', c.url); - weightsRequest.responseType = "arraybuffer"; - return Object.assign({}, c, {xhr: weightsRequest}) - }); - - // initialise progress bar - var pbar = new ProgressBar({ - config, - container: progressContainer, - done: function(results){ - results.forEach(({event, model})=>{ - { - var target = (event.currentTarget || event.target); - var response = new Buffer(target.response); - var data = new BSON().deserialize(response); - model.weights = flux.convertArrays_(data).weights; - } - }); - __init__() - }, - err: console.log - }) - - - pbar.start(); - config.forEach(({xhr}) => xhr.send()); -} \ No newline at end of file diff --git a/tools/progressBar/css/progressBar.css b/tools/progressBar/css/progressBar.css deleted file mode 100644 index 4dc8fc7d..00000000 --- a/tools/progressBar/css/progressBar.css +++ /dev/null @@ -1,46 +0,0 @@ -.progress-backdrop{ - position: absolute; - top: 0; - right: 0; - left:0; - bottom:0; - background: rgba(255, 255, 255, 0.7); - display: flex; - -webkit-justify-content: center; - justify-content: center; - align-items: center; -} - -.progress-lightbox{ - padding: 30px; - background: #fff; - box-shadow: 0px 3px 5px #aaa; - - border-radius: 6px; - width: 400px; - -} - -.progress-lightbox h3{ - color: #555; - font-size: 1em; -} - -.progress-bar-fill{ - position: absolute; - background: #555; - top: 0; - bottom: 0; - left: 0; - width: 0; - transition: all .5s linear; - border-radius: 3px; -} - -.progress-bar{ - width: 100%; - position: relative; - height: 5px; - margin: 20px 0; - background: #FFF; -} \ No newline at end of file diff --git a/tools/progressBar/js/ProgressBar.js b/tools/progressBar/js/ProgressBar.js deleted file mode 100644 index fbf67ca1..00000000 --- a/tools/progressBar/js/ProgressBar.js +++ /dev/null @@ -1,63 +0,0 @@ -(function(obj){ - - Object.assign(obj, {ProgressBar}); - - function ProgressBar({ config, container, done, err }){ - this.container = container; - this.progress = new Array(config.length).fill(0); - - var scope = this; - - var promises = config.map(({xhr, model, url}, index)=>{ - xhr.addEventListener('progress', (event)=>{ - if(event.currentTarget.status == 200){ - var p = event.loaded/event.total; - this.progress[index] = p; - scope.update(); - } - }) - - return new Promise((accept, reject)=>{ - xhr.addEventListener('load', function(event){ - if(event.currentTarget.readyState == 4 && event.currentTarget.status == 200){ - accept({ event, model}); - } - }); - xhr.addEventListener('error', (e)=> reject(url, e)); - }) - }) - - Promise.all(promises).then((results)=>{ - scope.dismiss(); - done(results) - }).catch(err); - } - - ProgressBar.prototype.start = function(){ - var backdrop = document.createElement('div'); - backdrop.className = 'progress-backdrop'; - backdrop.innerHTML = ('
\ -

Loading Weights ... 0%

\ -
\ -
\ -
\ -
') - - this.backdrop = backdrop; - this.container.appendChild(backdrop); - this.fill = backdrop.querySelector('.progress-bar-fill'); - this.status = backdrop.querySelector('.progress-status'); - } - - - ProgressBar.prototype.update = function(){ - var frac = Math.min(...this.progress) - this.total = this.backdrop.querySelector('.progress-bar').getClientRects()[0].width; - this.fill.style.width = (this.total*frac) + 'px'; - this.status.innerText = Math.round(frac*100); - } - - ProgressBar.prototype.dismiss = function(){ - this.container.removeChild(this.backdrop); - } -})(window) \ No newline at end of file diff --git a/tutorials/_posts/2020-09-15-deep-learning-flux.md b/tutorialposts/2020-09-15-deep-learning-flux.md similarity index 98% rename from tutorials/_posts/2020-09-15-deep-learning-flux.md rename to tutorialposts/2020-09-15-deep-learning-flux.md index fc7ba069..5747516b 100755 --- a/tutorials/_posts/2020-09-15-deep-learning-flux.md +++ b/tutorialposts/2020-09-15-deep-learning-flux.md @@ -1,9 +1,8 @@ ---- -title: Deep Learning with Flux - A 60 Minute Blitz -author: Saswat Das, Mike Innes, Andrew Dinhobl, Ygor Canalli, Sudhanshu Agrawal, João Felipe Santos -layout: blog -tag: Learning Flux ---- ++++ +title = "Deep Learning with Flux - A 60 Minute Blitz" +published = "15 November 2020" +author = "Saswat Das, Mike Innes, Andrew Dinhobl, Ygor Canalli, Sudhanshu Agrawal, João Felipe Santos" ++++ This is a quick intro to [Flux](https://github.com/FluxML/Flux.jl) loosely based on [PyTorch's tutorial](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html). It introduces basic Julia programming, as well Zygote, a source-to-source automatic differentiation (AD) framework in Julia. We'll use these tools to build a very simple neural network. @@ -275,7 +274,6 @@ We will do the following steps in order: ### Loading the Dataset - ```julia using Statistics using Flux, Flux.Optimise @@ -290,7 +288,6 @@ This image will give us an idea of what we are dealing with. ![title](https://pytorch.org/tutorials/_images/cifar10.png) - ```julia train_x, train_y = CIFAR10.traindata(Float32) labels = onehotbatch(train_y, 0:9) @@ -316,6 +313,7 @@ valY = labels[:, valset] |> gpu ``` ### Defining the Classifier + Now we can define our Convolutional Neural Network (CNN). A convolutional neural network is one which defines a kernel and slides it across a matrix to create an intermediate representation to extract features from. It creates higher order features as it goes into deeper layers, making it suitable for images, where the strucure of the subject is what will help us determine which class it belongs to. diff --git a/tutorials/_posts/2020-10-18-transfer-learning.md b/tutorialposts/2020-10-18-transfer-learning.md similarity index 96% rename from tutorials/_posts/2020-10-18-transfer-learning.md rename to tutorialposts/2020-10-18-transfer-learning.md index dfb4250e..95f16c40 100644 --- a/tutorials/_posts/2020-10-18-transfer-learning.md +++ b/tutorialposts/2020-10-18-transfer-learning.md @@ -1,9 +1,8 @@ ---- -title: Transfer Learning with Flux -author: Dhairya Gandhi -layout: blog -tag: Transfer learning ---- ++++ +title = "Transfer Learning with Flux" +published = "18 October 2020" +author = "Dhairya Gandhi" ++++ This article is intended to be a general guide to how transfer learning works in the Flux ecosystem. We assume a certain familiarity of the reader with the concept of transfer learning. Having said that, we will start off with a basic definition of the setup and what we are trying to achieve. There are many resources online that go in depth as to why transfer learning is an effective tool to solve many ML problems, and we recommend checking some of those out. @@ -23,7 +22,6 @@ using Flux: @epochs using Metalhead.Images resnet = ResNet().layers ``` -
If we intended to add a new class of objects in there, we need only `reshape` the output from the previous layers accordingly. Our model would look something like so: @@ -35,7 +33,6 @@ Our model would look something like so: Dense(reshaped_input_features, n_classes) ) ``` -
We will use the [Dogs vs. Cats](https://www.kaggle.com/c/dogs-vs-cats/data?select=train.zip) dataset from Kaggle for our use here. Make sure to download the `train.zip` file and extract it into a `train` folder. @@ -45,7 +42,6 @@ The [`dataloader.jl`](https://github.com/FluxML/model-zoo/blob/master/tutorials/ ```julia include("dataloader.jl") ``` -
Finally, the model looks something like: @@ -57,7 +53,6 @@ model = Chain( Dense(256, 2), # we get 2048 features out, and we have 2 classes ) ``` -
To speed up training, let’s move everything over to the GPU @@ -65,7 +60,6 @@ To speed up training, let’s move everything over to the GPU model = model |> gpu dataset = [gpu.(load_batch(10)) for i in 1:10] ``` -
After this, we only need to define the other parts of the training pipeline like we usually do. @@ -73,7 +67,6 @@ After this, we only need to define the other parts of the training pipeline like opt = ADAM() loss(x,y) = Flux.Losses.logitcrossentropy(model(x), y) ``` -
Now to train. As discussed earlier, we don’t need to pass all the parameters to our training loop. Only the ones we need to fine-tune. Note that we could have picked and chosen the layers we want to train individually as well, but this is sufficient for our use as of now. @@ -81,14 +74,12 @@ Now to train. As discussed earlier, we don’t need to pass all the parameters t ps = Flux.params(model) ``` **Note**: Normally, you would only re-train the dense layers via `model[2:end]` but in this case, the pre-trained models from Metalhead.jl are not currently available. This will change in the future once the pre-trained models are once again available. -
And now, let's train! ```julia @epochs 2 Flux.train!(loss, ps, dataset, opt) ``` -
And there you have it, a pretrained model, fine tuned to tell the the dogs from the cats. @@ -100,4 +91,3 @@ display(model(imgs)) labels ``` -
diff --git a/tutorials/_posts/2021-01-21-data-loader.md b/tutorialposts/2021-01-21-data-loader.md similarity index 93% rename from tutorials/_posts/2021-01-21-data-loader.md rename to tutorialposts/2021-01-21-data-loader.md index e67cc069..6352c20e 100755 --- a/tutorials/_posts/2021-01-21-data-loader.md +++ b/tutorialposts/2021-01-21-data-loader.md @@ -1,80 +1,73 @@ ---- -title: Using Flux DataLoader -author: Liliana Badillo, Dhairya Gandhi -layout: blog -tag: Learning Flux ---- - ++++ +title = "Using Flux DataLoader" +published = "21 January 2021" +author = "Liliana Badillo, Dhairya Gandhi" ++++ + In this tutorial, we show how to load image data in Flux DataLoader and process it in mini-batches. We use the [DataLoader](https://fluxml.ai/Flux.jl/stable/data/dataloader/#Flux.Data.DataLoader) type to handle iteration over mini-batches of data. For this example, we load the [MNIST dataset](https://juliaml.github.io/MLDatasets.jl/stable/datasets/MNIST/) using the [MLDatasets](https://juliaml.github.io/MLDatasets.jl/stable/) package. - + Before we start, make sure you have installed the following packages: - + * [Flux](https://github.com/FluxML/Flux.jl) * [MLDatasets](https://juliaml.github.io/MLDatasets.jl/stable/) - + To install these packages, run the following in the REPL: - + ```julia Pkg.add("Flux") Pkg.add("MLDatasets") ``` - -
- + Load the packages we'll need: - + ```julia using MLDatasets: MNIST using Flux.Data: DataLoader using Flux: onehotbatch ``` - + ## Step1: Loading the MNIST data set - + We load the MNIST train and test data from MLDatasets: - + ```julia train_x, train_y = MNIST(:train)[:] test_x, test_y = MNIST(:test)[:] ``` -
- + This code loads the MNIST train and test images as Float32 as well as their labels. The data set `train_x` is a 28×28×60000 multi-dimensional array. It contains 60000 elements and each one of it contains a 28x28 array. Each array represents a 28x28 image (in grayscale) of a handwritten digit. Moreover, each element of the 28x28 arrays is a pixel that represents the amount of light that it contains. On the other hand, `test_y` is a 60000 element vector and each element of this vector represents the label or actual value (0 to 9) of a handwritten digit. - + ## Step 2: Loading the dataset onto DataLoader - + Before we load the data onto a DataLoader, we need to reshape it so that it has the correct shape for Flux. For this example, the MNIST train data must be of the same dimension as our model's input and output layers. - + For example, if our model's input layer expects a 28x28x1 multi-dimensional array, we need to reshape the train and test data as follows: - + ```julia train_x = reshape(train_x, 28, 28, 1, :) test_x = reshape(test_x, 28, 28, 1, :) ``` -
- + Also, the MNIST labels must be encoded as a vector with the same dimension as the number of categories (unique handwritten digits) in the data set. To encode the labels, we use the [Flux's onehotbatch](https://fluxml.ai/Flux.jl/stable/data/onehot/#Batches-1) function: - + ```julia train_y, test_y = onehotbatch(train_y, 0:9), onehotbatch(test_y, 0:9) ``` -
- + >**Note:** For more information on other encoding methods, see [Handling Data in Flux](https://fluxml.ai/Flux.jl/stable/data/onehot/). - + Now, we load the train images and their labels onto a DataLoader object: - + ```julia data_loader = DataLoader((train_x, train_y); batchsize=128, shuffle=true) ``` -
- + Notice that we set the DataLoader `batchsize` to 128. This will enable us to iterate over the data in batches of size 128. Also, by setting `shuffle=true` the DataLoader will shuffle the observations each time that iterations are re-started. - + ## Step 3: Iterating over the data - -Finally, we can iterate over the 60000 MNIST train data in mini-batches (most of them of size 128) using the Dataloader that we created in the previous step. Each element of the DataLoader is a tuple `(x, y)` in which `x` represents a 28x28x1 array and `y` a vector that encodes the corresponding label of the image. - + +Finally, we can iterate over the 60000 MNIST train data in mini-batches (most of them of size 128) using the Dataloader that we created in the previous step. Each element of the DataLoader is a tuple `(x, y)` in which `x` represents a 28x28x1 array and `y` a vector that encodes the corresponding label of the image. + ```julia for (x, y) in data_loader @assert size(x) == (28, 28, 1, 128) || size(x) == (28, 28, 1, 96) @@ -82,8 +75,5 @@ for (x, y) in data_loader ... end ``` - -
- - + Now, we can create a model and train it using the `data_loader` we just created. For more information on building models in Flux, see [Model-Building Basics](https://fluxml.ai/Flux.jl/stable/models/basics/#Model-Building-Basics-1). diff --git a/tutorials/_posts/2021-01-26-mlp.md b/tutorialposts/2021-01-26-mlp.md similarity index 96% rename from tutorials/_posts/2021-01-26-mlp.md rename to tutorialposts/2021-01-26-mlp.md index da35d18c..2257c93b 100644 --- a/tutorials/_posts/2021-01-26-mlp.md +++ b/tutorialposts/2021-01-26-mlp.md @@ -1,9 +1,8 @@ ---- -title: Simple multi-layer perceptron -author: Adarsh Kumar, Mike J Innes, Andrew Dinhobl, Jerry Ling, natema, Zhang Shitian, Liliana Badillo, Dhairya Gandhi -layout: blog -tag: Examples from Flux Model Zoo ---- ++++ +title = "Simple multi-layer perceptron" +published = "26 January 2021" +author = "Adarsh Kumar, Mike J Innes, Andrew Dinhobl, Jerry Ling, natema, Zhang Shitian, Liliana Badillo, Dhairya Gandhi" ++++ In this example, we create a simple [multi-layer perceptron](https://en.wikipedia.org/wiki/Multilayer_perceptron#:~:text=A%20multilayer%20perceptron%20(MLP)%20is,artificial%20neural%20network%20(ANN).&text=An%20MLP%20consists%20of%20at,uses%20a%20nonlinear%20activation%20function.) (MLP) that classifies handwritten digits using the MNIST dataset. A MLP consists of at least *three layers* of stacked perceptrons: Input, hidden, and output. Each neuron of an MLP has parameters (weights and bias) and uses an [activation function](https://en.wikipedia.org/wiki/Activation_function) to compute its output. @@ -22,7 +21,6 @@ if has_cuda() # Check if CUDA is available CUDA.allowscalar(false) end ``` -
We set default values for learning rate, batch size, epochs, and the usage of a GPU (if available) for our model: @@ -35,7 +33,6 @@ We set default values for learning rate, batch size, epochs, and the usage of a end ``` -
If a GPU is available on our local system, then Flux uses it for computing the loss and updating the weights and biases when training our model. @@ -66,7 +63,6 @@ function getdata(args) end ``` -
`getdata` performs the following steps: @@ -94,7 +90,6 @@ function build_model(; imgsize=(28,28,1), nclasses=10) end ``` -
Note that we use the functions [Dense](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.Dense) so that our model is *densely* (or fully) connected and [Chain](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.Chain) to chain the computation of the three layers. @@ -112,7 +107,6 @@ function loss_all(dataloader, model) end ``` -
In addition, we define the function (`accuracy`) to report the accuracy of our model during the training process. To compute the accuray, we need to decode the output of our model using the [onecold](https://fluxml.ai/Flux.jl/stable/data/onehot/#Flux.onecold) function. @@ -125,7 +119,6 @@ function accuracy(data_loader, model) acc/length(data_loader) end ``` -
## Train our model @@ -159,7 +152,6 @@ function train(; kws...) end ``` -
`train` performs the following steps: diff --git a/tutorials/_posts/2021-02-07-convnet.md b/tutorialposts/2021-02-07-convnet.md similarity index 97% rename from tutorials/_posts/2021-02-07-convnet.md rename to tutorialposts/2021-02-07-convnet.md index 1c956daf..f13ba112 100644 --- a/tutorials/_posts/2021-02-07-convnet.md +++ b/tutorialposts/2021-02-07-convnet.md @@ -1,9 +1,8 @@ ---- -title: Simple ConvNet -author: Elliot Saba, Adarsh Kumar, Mike J Innes, Dhairya Gandhi, Sudhanshu Agrawal, Sambit Kumar Dash, fps.io, Carlo Lucibello, Andrew Dinhobl, Liliana Badillo -layout: blog -tag: Computer vision ---- ++++ +title = "Simple ConvNet" +published = "7 February 2021" +author = "Elliot Saba, Adarsh Kumar, Mike J Innes, Dhairya Gandhi, Sudhanshu Agrawal, Sambit Kumar Dash, fps.io, Carlo Lucibello, Andrew Dinhobl, Liliana Badillo" ++++ In this tutorial, we build a simple Convolutional Neural Network (ConvNet) to classify the MNIST dataset. This model has a simple architecture with three feature detection layers (Conv -> ReLU -> MaxPool) followed by a final dense layer that classifies MNIST handwritten digits. Note that this model, while simple, should hit around 99% test accuracy after training for approximately 20 epochs. @@ -21,7 +20,6 @@ using Parameters: @with_kw using CUDA CUDA.allowscalar(false) ``` -
We set default values for learning rate, batch size, number of epochs, and path for saving the file `mnist_conv.bson`: @@ -33,7 +31,6 @@ We set default values for learning rate, batch size, number of epochs, and path savepath::String = "./" end ``` -
To train our model, we need to bundle images together with their labels and group them into mini-batches (makes the training process faster). We define the function `make_minibatch` that takes as inputs the images (`X`) and their labels (`Y`) as well as the indices for the mini-batches (`idx`): @@ -47,7 +44,6 @@ function make_minibatch(X, Y, idxs) return (X_batch, Y_batch) end ``` -
`make_minibatch` takes the following steps: @@ -75,7 +71,6 @@ function get_processed_data(args) end ``` -
Now, we define the `build_model` function that creates a ConvNet model which is composed of *three* convolution layers (feature detection) and *one* classification layer. The input layer size is `28x28`. The images are grayscale, which means there is only *one* channel (compared to 3 for RGB) in every data point. Combined together, the convolutional layer structure would look like `Conv(kernel, input_channels => output_channels, ...)`. Each convolution layer reduces the size of the image by applying the Rectified Linear unit (ReLU) and MaxPool operations. @@ -104,7 +99,6 @@ function build_model(args; imgsize = (28,28,1), nclasses = 10) Dense(prod(cnn_output_size), 10)) end ``` -
To chain the layers of a model we use the Flux function [Chain](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.Chain). It enables us to call the layers in sequence on a given input. Also, we use the function [flatten](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.flatten) to reshape the output image from the last convolution layer. Finally, we call the [Dense](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.Dense) function to create the classification layer. @@ -117,7 +111,6 @@ Before training our model, we need to define a few functions that will be helpfu ```julia augment(x) = x .+ gpu(0.1f0*randn(eltype(x), size(x))) ``` -
* `anynan` checks whether any element of the params is NaN or not: @@ -125,14 +118,12 @@ Before training our model, we need to define a few functions that will be helpfu ```julia anynan(x) = any(y -> any(isnan, y), x) ``` -
* `accuracy` computes the accuracy of our ConvNet: ```julia accuracy(x, y, model) = mean(onecold(cpu(model(x))) .== onecold(cpu(y))) ``` -
Finally, we define the `train` function: @@ -216,7 +207,6 @@ function train(; kws...) end end ``` -
`train` calls the functions we defined above and trains our model. It stops when the model achieves 99% accuracy (early-exiting) or after performing 20 steps. More specifically, it performs the following steps: @@ -258,7 +248,6 @@ function test(; kws...) @show accuracy(test_set...,model) end ``` -
`test` loads the MNIST test data set, reconstructs the model, and loads the saved parameters (in `mnist_conv.bson`) onto it. Finally, it computes our model's predictions for the test set and shows the test accuracy (around 99%). diff --git a/tutorials/_posts/2021-10-8-dcgan-mnist.md b/tutorialposts/2021-10-08-dcgan-mnist.md similarity index 97% rename from tutorials/_posts/2021-10-8-dcgan-mnist.md rename to tutorialposts/2021-10-08-dcgan-mnist.md index 2bb58e9b..55533cf0 100644 --- a/tutorials/_posts/2021-10-8-dcgan-mnist.md +++ b/tutorialposts/2021-10-08-dcgan-mnist.md @@ -1,9 +1,8 @@ ---- -title: Deep Convolutional Generative Adversarial Network(DCGAN) -author: Deeptendu Santra -layout: blog -tag: Generative Adversarial Neural Networks ---- ++++ +title = "Deep Convolutional Generative Adversarial Network (DCGAN)" +published = "8 October 2021" +author = "Deeptendu Santra" ++++ This is a beginner level tutorial for generating images of handwritten digits using a [Deep Convolutional Generative Adversarial Network](https://arxiv.org/pdf/1511.06434.pdf) inspired by the [TensorFlow tutorial on DCGAN](https://www.tensorflow.org/tutorials/generative/dcgan). @@ -12,20 +11,23 @@ This is a beginner level tutorial for generating images of handwritten digits us A GAN is composed of two sub-models - the **generator** and the **discriminator** acting against one another. The generator can be considered as an artist who draws (generates) new images that look real, whereas the discriminator is a critic who learns to tell real images apart from fakes. - +![](/assets/2021-10-8-dcgan-mnist/cat_gan.png) The GAN starts with a generator and discriminator which have very little or no idea about the underlying data. During training, the generator progressively becomes better at creating images that look real, while the discriminator becomes better at telling them apart. The process reaches equilibrium when the discriminator can no longer distinguish real images from fakes. - + +![](https://www.tensorflow.org/tutorials/generative/images/gan2.png) [[source]](https://www.tensorflow.org/tutorials/generative/dcgan) This tutorial demonstrates the process of training a DC-GAN on the [MNIST dataset for handwritten digits](http://yann.lecun.com/exdb/mnist/). The following animation shows a series of images produced by the generator as it was trained for 25 epochs. The images begin as random noise, but over time, the images become increasingly similar to handwritten numbers. +~~~

+~~~ ## Setup diff --git a/tutorials/_posts/2021-10-14-vanilla-gan.md b/tutorialposts/2021-10-14-vanilla-gan.md similarity index 93% rename from tutorials/_posts/2021-10-14-vanilla-gan.md rename to tutorialposts/2021-10-14-vanilla-gan.md index 29f7dd6e..eb3ecce3 100644 --- a/tutorials/_posts/2021-10-14-vanilla-gan.md +++ b/tutorialposts/2021-10-14-vanilla-gan.md @@ -1,9 +1,8 @@ ---- -title: Generative Adversarial Networks -author: Ralph Kube -layout: blog -tag: Learning Flux ---- ++++ +title = "Generative Adversarial Networks" +published = "14 October 2021" +author = "Ralph Kube" ++++ This tutorial describes how to implement a vanilla Generative Adversarial Network using Flux and how train it on the MNIST dataset. It is based on this @@ -43,7 +42,6 @@ While [UnicodePlots]() is not necessary, it can be used to plot generated sample into the terminal during training. Having direct feedback, instead of looking at plots in a separate window, use fantastic for debugging. -
Next, let us define values for learning rate, batch size, epochs, and other hyper-parameters. While we are at it, we also define optimizers for the generator @@ -61,7 +59,6 @@ and discriminator network. More on what these are later. opt_gen = ADAM(lr_g) # Optimizer for the generator ``` -
In this tutorial I'm assuming that a CUDA-enabled GPU is available on the system where the script is running. If this is not the case, simply remove @@ -89,7 +86,6 @@ and shuffling the data. train_loader = DataLoader(train_x, batchsize=batch_size, shuffle=true); ``` -
## Defining the Networks @@ -271,13 +267,13 @@ per epoch and is not recommended. Below you can see what some of the images output may look like after different numbers of epochs. -Screen Shot 2021-10-22 at 6 51 00 AM +![](https://user-images.githubusercontent.com/35577566/138465727-3729b867-2c2c-4f12-ba8e-e7b00c73d82c.png) -Screen Shot 2021-10-22 at 6 51 14 AM +![](https://user-images.githubusercontent.com/35577566/138465750-423f70fc-c8e7-489c-8cf4-f01b203a24dd.png) -Screen Shot 2021-10-22 at 6 51 35 AM +![](https://user-images.githubusercontent.com/35577566/138465777-5c8252ae-e43b-4708-a42a-b0b85324f79d.png) -Screen Shot 2021-10-22 at 6 51 46 AM +![](https://user-images.githubusercontent.com/35577566/138465803-07239e62-9e68-42b7-9bb7-57fdff748ba9.png) ## Resources diff --git a/tutorials.md b/tutorials.md index 2635a670..77ef52d7 100755 --- a/tutorials.md +++ b/tutorials.md @@ -1,15 +1,7 @@ ---- -layout: blog -title: Tutorials ---- ++++ +title = "Tutorials" ++++ This section contains tutorials contributed by the Flux community and examples from the [The Model Zoo](https://github.com/FluxML/model-zoo). -{% for tag in site.tags %} -

{{ tag[0] }}

- -{% endfor %} \ No newline at end of file +{{recentposts tutorialposts}} diff --git a/utils.jl b/utils.jl new file mode 100644 index 00000000..6520f973 --- /dev/null +++ b/utils.jl @@ -0,0 +1,27 @@ +using Dates + +function hfun_recentposts(params) + postdir = only(params) + list = readdir(postdir) + filter!(f -> endswith(f, ".md"), list) + dates = Vector{Date}(undef, length(list)) + titles = Vector{String}(undef, length(list)) + links = Vector{String}(undef, length(list)) + for (i, file) in enumerate(list) + postname = splitext(basename(file))[1] + url = postdir * "/" * postname + pubdate = pagevar(url, :published) + dates[i] = isnothing(pubdate) ? Date(1999) : Date(pubdate, dateformat"d U Y") + titles[i] = something(pagevar(url, :title), "Post $i") + externallink = pagevar(url, :external) + links[i] = isnothing(externallink) ? ("/" * url * "/") : externallink + end + perm = sortperm(dates, rev=true) + io = IOBuffer() + for i in perm + write(io, """

$(titles[i])""") + !isnothing(dates[i]) && write(io, " ($(monthname(dates[i])) $(year(dates[i])))") + write(io, "

\n") + end + return String(take!(io)) +end diff --git a/zygote.png b/zygote.png deleted file mode 100644 index 5e8d4920..00000000 Binary files a/zygote.png and /dev/null differ