OmniAICreator/Qiita-1.07M huggingface dataset:
設計書をメンテナンスする文化を醸成する

# はじめに
設計書というのは往々にしてメンテナンスされないものです。そもそも設計書というドキュメントは必要なのか？という議論もよく見かけます。設計書の要否に関しては、人それぞれ考えはあると思いますが、(どちらが良いかは置いておいて)ここでは設計書は「必要」という前提で、ではどうすれば設計書をメンテナンスする文化を醸成するかを考えてみます。

# 設計書の存在意義をメンバーに共感してもらう
設計書の存在意義を本当に理解しているメンバーは意外に少ないものです。「設計」というフェーズが存在するから書いている、お客様に納品するから書いている、リーダーに指示されたから書いている、なんてことも少なくありません。また、設計書の存在意義の解釈もメンバーによって違うことが多いです。このような状況で「設計書はしっかりメンテナンスしよう！」と言っても、メンバーのモチベーションを下げるだけです。そのため、

* 設計書の目的(なぜ設計書が必要なのか、設計書があることで何が幸せなのか)
* 設計書は誰のためのドキュメントなのか
* 設計書はどんな時に必要となってくるのか

をプロジェクト内(組織内)で定義して、メンバーに説明し共感してもらうことから始めます。

# 設計書のメンテナンス工数を確保する
設計書のメンテナンスが必要となるケースはいくつかあると思いますが、そのほとんどがプログラムの修正に伴うメンテナンスです。例えば、テスト時のバグ対応で処理フローを修正しそれにより設計書も修正が必要となった、なんてケースがその1つです。このケースの場合、テストのバグ対応をしながら残ったテストケースの消化もしなければならず、スケジュールに追われて設計書のメンテナンスまで手が回らずそのまま、、、なんてオチに繋がります。そのため、工数を見積もる時は設計書のメンテナンス工数も確保することで、メンテナンスまで手が回らない、、という事態を防ぎます。

# メンテナンスしやすい設計書フォーマット・記載粒度にする
設計書の存在意義を共感してもらって、メンテナンス工数を確保しても、メンテナンスしやすい設計書フォーマット・記載粒度でないと、これはこれでメンバーのモチベーションを下げてしまいます。複雑すぎるフォーマット、細かすぎる記載粒度はなるべく避けたほうが良いと思います。

# ソースレビューと同時に設計書も修正されているかを確認する
色々と述べてきましたが、そもそも設計書のメンテナンス作業を忘れては意味がありません。前項でも述べた通り、設計書のメンテナンスが必要となるケースのほとんどがプログラムの修正に伴うメンテナンスです。そのため、プログラムを修正してソースレビュー依頼が来たら、ソースだけでなく設計書も修正されているかを確認するフローにします。例えば、ソースレビュー観点に設計書も修正されているか、を盛り込む等です。ただ、重厚なフローにし過ぎるとかえって開発者が窮屈になってしまうので適度なやり方が良いと思います。

# 設計書の存在意義を定期的に振り返り確認し合う
定期的な振り返りや認識合わせは重要です。定期的に振り返りや認識合わせを行うことで、設計書をメンテナンスする文化を磨き上げていきます。

# 最後に
色々述べてきましたが、プロジェクトや組織の文化、メンバーの特性によるところも大きいと思います。そのため、本ページのやり方がベストというわけではなく、プロジェクトや組織の文化、メンバーの特性を考えながらそれにあった手法が良いと思います。本ページの手法はあくまで一例として捉えていただけたらと思います。

以上です。
Brewfileを使った新Mac移行手順

https://github.com/darai0512/dotfiles に最新内容を記載。

古いものは以下を除き削除（必要なら履歴から）

### （過去ログ）brew-file移行元の操作

これはコミッタ様が直してくれたので残している。
実際の操作は最新docsを確認。
https://homebrew-file.readthedocs.io/en/latest/getting_started.html

以下古い内容

```
$brew-file init
Do you want to set a repository (y)? ((n) for local Brewfile). [y/n]: y
Set repository, "non" for local Brewfile,<user>/<repo> for github repository,
or full path for the repository: non
```

initではGithubリポジトリと連携する場合に"non"以外の文字列を入れるが、
一度リポジトリを設定してしまうと、変更は`$brew-file set_repo`でできるものの、~~削除はできない様子~~。

~~自分は間違えてlocal pathを入れてしまい、`$brew-file set_repo`で"non"と答え直してBrewfileを生成できたが、
再度`$brew-file init`をしても最初に入力したpathを探されて困った。~~

=> こちら修正されました（コメント欄参照）

cask系は`$brew cask install [app-name]`ではなくGUI（dmgファイル）で既に導入済みの場合、Brewfileには含まれないため、必要なら手動で打ち込む。
Docker HubにGolangの公式イメージをベースにRevelのイメージを作成してみた


## 必要な環境
* [Github](https://github.com)のアカウント
* [Docker Hub](https://hub.docker.com/)のアカウント
* docker

## 手順
1. Githubにリポジトリを作成
1. Dockerfileを作成して、Githubにpush
1. Docker HubにGithubと連携したRepositoryを作成
1. 作成したDockerfileに対して、`Build Settings`を作成

### Githubにリポジトリを作成
[省略]

### Dockerfileを作成して、Githubにpush

以下のコマンドで、ローカルでイメージ作成の動作確認をする

```
docker build -t revel .
```

問題なければ、GithubにPushする

### Docker HubにGithubと連携したRepositoryを作成
* [Docker Hub](https://hub.docker.com/)にアクセスしたら、以下の画面に従って、`Create Automated Build`を選択

![スクリーンショット 2017-05-08 3.55.32.png](https://qiita-image-store.s3.amazonaws.com/0/120666/449f083b-0288-e4f9-49f3-340fc829c9ff.png "スクリーンショット 2017-05-08 3.55.32.png")

* Github/Bitbucketを選択
	* 今回は、Githubを選択
* 遷移した画面で対象のリポジトリを選択(`docker-revel`)

### Dockerfileに対して、`Build Settings`を作成
以下のように、バージョン毎に`Docker Tag Name`を作成することで、バージョン違いのイメージを保持しておくことが可能

![Build Settings.png](https://qiita-image-store.s3.amazonaws.com/0/120666/969c9b45-0520-9775-9f84-f21321c3fdaa.png "Build Settings.png")

## 作成したリポジトリ

* Github
	* [docker-revel](https://github.com/kterada0509/docker-revel)
* Docker Hub
	* [kterada0509/docker-revel](https://hub.docker.com/r/kterada0509/docker-revel/)


## 利用例

* docker-composeでの組み込み

``` docker-compose.yml
version: '2'
services:
  dynamodb:
    image: kterada0509/docker-dynamodb-local:latest
    ports:
      - "8080:8080"

  app:
    image: kterada0509/docker-revel:latest
    volumes:
      - ".:/go/src/github.com/kterada0509/sample/"
    command: revel run github.com/kterada0509/sample
    environment:
      DYNAMODB_ENDPOINT: "dynamodb:8080"
    links:
      - dynamodb
    ports:
      - "9000:9000"
```
WindowsでMySQLのインストールが進まない場合（Starting Serverで止まってしまう）の対策


本来ならば、次のように進むはずですが：
![image](https://qiita-image-store.s3.amazonaws.com/0/73576/43dfcfee-3978-9535-dbb1-ec9319f90a12.png)

Starting Serverの手順で進まないことがあります。その場合は、次のようにします：

1. コントロールパネルを開く
2. 表示を大きいアイコンにして「管理ツール」を選択
3. 「サービス」を選択
4. MYSQL57を右クリックしてプロパティを選択
5. ログオンのタブで「ローカルシステムアカウント」を選択し「デスクトップとの対話をサービスに許可」にチェックを入れる

![image](https://qiita-image-store.s3.amazonaws.com/0/73576/55181cc8-b50f-dba9-75f0-a4dc3d6e1922.png)

6. 全般のタブで「開始」をクリック

これでインストーラが無事に続行します。

ソース：http://stackoverflow.com/questions/26970454/mysql-configuration-stops-at-starting-server
avaでテスト時にbabelをoffにする

特殊なパターンでavaのテストがこけてしまうので、avaのbabelを切りたかったが結構苦労したので備忘録。

# テストが失敗するパターン
呼び出す関数が通常の関数なのか、AsyncFunctionなのかによって分岐する下記のようなプログラムで問題が起きた。
async/awaitはNode.js v7からかなり高速化しているため、テストの高速化も期待してNode.js v7で開発をしている。

expressのrouteに登録する関数の共通処理です。

```javascript:controller.js
module.exports = (controller) => {
  if (controller.constructor.name === 'AsyncFunction') {
    return (req, res) => {
      controller(req, res)
      .then((data) => {
        res.status(200).json(data);
      })
      .catch((err) => {
        res.status(500).send('error');
      });
    };
  }

  return (req, res) => {
    try {
      const data = controller(req, res);
      res.status(200).json(data);
    } catch (err) {
      res.status(500).send('error');
    }
  };
};
```

失敗するテストコードは以下

```test.js
'use strict';

const { test } = require('ava');
const express = require('express');
const request = require('supertest');

const controller = require('./controller.js');

test('async functionを呼び出せる', async (t) => {
  const responseObj = { hoge: 'hogehoge' };

  let counter = 0;
  const func = async () => {
    const get = (ms) => {
      return new Promise((resolve) => {
        counter++;
        resolve(responseObj);
      });
    };
    return await get(100);
  };

  const app = express();
  app.get('/', controller(func));

  const res = await request(app)
    .get('/')
    .set('Accept', 'application/json');

  t.is(counter, 1, 'async functionが呼び出されている');
  t.is(res.status, 200, '正常responseを返せている');
  t.deepEqual(res.body, responseObj, '返却するreponseの形式が正しい'); // ここがこける
});
```

# 原因
デバッグしてみると通常ならば以下のif文に入ってAsyncFunctionとして処理してくれるはずなのだが、`controller.constructor.name`が`Function`になってしまい処理がおかしくなっていた。

```js
if (controller.constructor.name === 'AsyncFunction') {
}
```

avaが内部的にbabelを利用しているため通常関数にコンパイルされてしまっていた。

# 調査
要はasync/awaitをコンパイルしないようにしたいので、babelを切れるオプションを探したら下記のissueにあたった。
[Disable babel via `--no-babel` flag · Issue #424 · avajs/ava](https://github.com/avajs/ava/issues/424)

`--no-babel`とかいうドンピシャなオプションがあるじゃないかということで早速実行したらエラー

```
> ava -v --no-babe
  ✖ Unexpected Babel configuration for AVA. See https://github.com/avajs/ava#es2015-support for allowed va
lues.
```

下記のissueを見るとこのコマンドを実行すると`"babel": false`になるらしい。
https://github.com/avajs/ava/issues/448#issuecomment-190286370

エラー文が何を示してるのか探ってみたらavaのconfigにfalseが入ると問答無用でErrorを飛ばされていた。
https://github.com/avajs/ava/blob/90fb60a895bff0a76df46e2af8deec307a67cbbb/lib/babel-config.js#L19-L22

つまりオプションはあるけど実質指定できない状態のようだ。

`conf === 'inherit'`はどこで指定するんだと思ったらREADMEに書いてあった。
https://github.com/avajs/ava#configuration

`"babel": false`を設定したら同じエラーになったので、どうやらここの様子。

# 対処
babelそのものをoffにするのは難しそうなので、babelで使っているpresetsを強制的に空にすればいいじゃないか、という結論に達した。
下記のドキュメントに沿ってavaの中で使っているpresetsを空で上書きをしたら無事async/awaitがコンパイルされずテストが通った。
https://github.com/avajs/ava#es2017-support

```js:package.json
...
  "ava": {
    "babel": {
      "presets": []
    }
  }
```
なかなか踏み出せないWeb画面の自動テストを導入する。

# 概要
既に稼働が始まってしまっているサービスで、Web画面の自動テストを導入するのに躊躇しているあなたにお届けします。
# 目的
自動テストを導入してみようかなと思って貰えること。
## はじめに
既に稼働してしまっているサービスに対して自動テストを導入するのって、途方もない膨大な仕様や機能がわかっているだけに躊躇してしまいますよね？
確かに完璧なテストを目指すとそれだけテストコードを準備しなければならないし、テストコードのメンテナンスも大変です。
私もそんな風に悩んでいたうちの一人でしたが、ミニマルから導入して結局は良いことが多かったので皆さんにもオススメしたいと思います。
今回は、LV 1 〜 6 まで順番に私が導入した自動テストケースを記載するので、明日からのミニマルスタートの参考にしていただければ幸いです。
## 前提
レガシーな技術で作成されたWebサービスのプロジェクトに、途中参画したときのお話です。

## 自動テストケース
### LV 1
#### 導入したテストケース
1. 指定した URL へのアクセスで、正常なステータスコードが返ること。
2. 指定した URL へのアクセスで、想定されるタイトルが返ること。
3. フッタやヘッダなど共通部品が表示されていること。

#### 導入について
仕様変更が多く、納期も短いこともあり、サーバの共通ロジックに変更があった時に結合テストで修正対象でない画面で不具合が発見されることが多々発生していたため、最低限の自動テストを導入しました。
この自動テストの導入のおかげで、結合テストでの発覚はほぼ０となりました。

費用対効果 : **高**

### LV 2
#### 導入したテストケース
1. 画面特有の項目のうち、静的でない項目が想定通り表示されていること。
2. 画面上の静的リンクが正常に機能していること。

#### 導入について
自動テストの仕組みが整ったため、重要な画面から少しずつ自動テストを追加していきました。
1番は機能変更によるデグレを防ぐための自動テストで、この導入前後で結合テスト不具合発生頻度が目に見えて下がりました。
2番については機能削除などでリンク先がなくなったケースで見逃しやすい不具合だったため導入しました。

費用対効果 : **高**

### LV 3
#### 導入したテストケース
1. スタイルが適用されていること。

#### 導入について
デザインと機能を分業しているため、最終的に組み込んだあとに機能は問題がないがスタイルの適用に問題があるという不具合が何件か発生していたため導入しました。
スタイルシートが正しく読み込まれていることの確認だけをおこなっていますが、不具合となるケースが大幅に減りました。

費用対効果 : **中**

### LV 4
#### 導入したテストケース
1. 正常な入力で画面遷移ができ、正常なステータスコードが返ること。
2. 異常な入力で画面遷移ができ、異常なステータスコードが返ること。
3. 異常な入力で画面遷移ができないこと。

#### 導入について
デグレ防止のために導入しました。
導入することで不具合発生が減ったことはもちろんなのですが、特にテストに手間のかかる異常系の自動テストは、何故最初から導入していなかったのかと後悔するほどに工数の軽減を感じました。
ここからはテストコードを準備するのに結構なコストを要するため、ある程度割り切って正常・異常で各 １ パターンでも用意すれば良いという気持ちで望むほうが良いと思います。

費用対効果 : **高** 
※ 自動テストパターンを増やすと費用対効果は下がっていくが安心感は増える。

### LV 5
#### 導入したテストケース
1. 入力項目のバリデーションを確認する。
2. 入力項目のバリエーションを確認する。

#### 導入について
入力項目のバリデーションの確認や、入力のバリエーション確認を一部画面にも導入しました。
効果は確かにありますが、テストコードが多くなりメンテナンスが大変という印象でした。

費用対効果 : **小**

### LV 6
#### 導入したテストケース
1. 画面入力と、その結果の出力がサービスの仕様通りであるか確認する。

#### 導入について
複数の画面に跨る、サービスの仕様確認を一部機能に導入しました。
プロジェクト特有の問題だったのかもしれませんが、サービスの仕様変更が入るたびにテストコードを大きく作り変える必要が多かったことから、サービスの仕様に直接関連するような自動テストはおこなわなくなりました。

費用対効果 : **小**

# まとめ
私のプロジェクトでは、全てが自動化とはならずコストも大きく削減できたわけではありませんが、結果として同じコストで出来上がるプログラムの品質は大きく向上しました。

LV 4　のバリエーションを増やしたり LV 5 以降をしっかりやろうと思うと テストコードが急激に増えていくことと、仕様変更のたびにそれをメンテナンスするコストとで費用に見合った効果は感じ難いと思います。
お金で安心を買える状況であればこちらも自動化を進めた方がよいと思いますが、個人的にはプロジェクト状況によりけりだと考えています。

ただ個人的な感想としては、LV 1 〜 4 まで比較的簡単に導入できる内容のため、どんなプロジェクトでも今スグにでも導入したほうが良いと思いますので、この記事が皆さんの導入のきっかけとなれば幸いです。

ご静聴ありがとうございました。
ルー語で遊んでいたらJSONPが作れてしまった

#ルー語で遊ぶ
<a href="https://lou5.jp/" target="_blank">ルー語変換</a>
おそらく「ルー語」がちょっと流行ったときに、さっと作ったサービスですかね～
Webサービスは、こういうフットワークの軽さがいいですね。


##作りを見てみる
エンジニアの職業病、このサービスはいったいどんな作りをしているのか？
ブラウザの開発者ツールで調査してみました。

「Network」をみると、「api」というものが取得されていました。
「api」の「Headers」を見ると

```
General
 Request URL: https://lou5.jp/api
 Request Method: POST
```

ふむふむ。
ベースとなるURLは「https\://lou5.jp/api」だな。
送信方法は「POST」と。

さらに見てみる。

```
Form Data
 text: 寝耳に水
```

どうやら「text」という名前で「寝耳に水」が送られていますね。

##ということで
「POST」でAPIを叩いているのですが、ダメ元で「GET」をしてみます。

URLとして「<a href="https://lou5.jp/api/?text=寝耳に水" target="_blank">https://lou5.jp/api/?text=寝耳に水</a>」を作り
ブラウザの新規タブでアクセスしてみました。

すると
```
寝耳にウォーター
```

GETで変換できてしまった。。。いいのかな。


##ということで、さらに
URLとして「<a href="https://lou5.jp/api/?text=callback('寝耳に水')" target="_blank">https://lou5.jp/api/?text=callback('寝耳に水')</a>」を作り
ブラウザの新規タブでアクセスしてみました。

すると
```
callback('寝耳にウォーター')
```

こ、これはすごい！！
なんと「JSONP」でデータが返ってきています！！

##ということで、サクッと
JSONPのサンプルを作ってみます。

ここで最小限に必要なUIは、
「変換前のテキスト」「変換後のテキスト」「変換ボタン」
以上の3つがあればいけそうですね。

```html:sample1.html
<input id="beforeText" type="text" placeholder="ルー語に変換したい言葉を入力してください">
<input id="btnRun" type="button" value="ルー語変換">
<input id="afterText" type="text" placeholder="こちらにルー語が表示されます">
```

```css:sample1.css
input[type='text'] {
    width: 300px;
}
```

JavaScriptの実装もシンプルに。

```javascript:sample1.js
window.onload = function(){
    var btnRun = document.getElementById("btnRun");
    btnRun.onclick = function(){
        var beforeText = document.getElementById("beforeText");
        addScript("https://lou5.jp/api/?text=callback('" + beforeText.value + "')");
    };
};

function addScript(url){
    var script = document.createElement('script');
    script.src = url;
    document.body.appendChild(script);
}

function callback(val){
    var afterText = document.getElementById("afterText");
    afterText.value = val;
}
```

これで、いとも簡単に「ルー語変換」のサービスが作れてしまいました。
さらに、JSONPなので、**クロスドメイン制限**にも引っかからないし、自由にサイトに組み込むことができてしまいます！

##まとめ

今回たまたま、**セキュリティの穴**を発見してしまいました。
ちょうど過去の自分の仕事を見直す、いい機会になりました。
おそらく、世の中のセキュリティ系エンジニアは、
もっと高度なレベルのことをして、ご飯を食べているのかもしれませんね～
機械学習論文読みメモ_66


[Unsupervised Image-to-Image Translation Networks](https://arxiv.org/abs/1703.00848)
従来提案されてきたimage-to-image translationは教師あり学習に基づいたものであった。
しかし異なるドメイン間に適切な教師ありデータを用意する事は難しい。
本論では教師なし学習の枠組みでこれを提案する。
このモデルはVAEとGANを組み合わせたモデルであり、高レベル特徴を共有した各２つのエンコーダ、デコーダと判別機を持ち、異なった２つドメインのデータを入力して学習する。
この時、各デコーダは２つのドメインから得られたエンコーダの結果を両方入力し、２つの画像を生成する。
判別機は入力に用いた実際の画像と、デコーダから得られた２つの画像の３つの画像の間で実際の画像を判別するタスクを解く。
これらをGANの枠組みで最適化する事により、特徴を共有させながら学習するためドメインに依存しない一般的な特徴を学習可能になる。
このモデルを利用してあるドメインの画像を入力し、そこから異なったドメインへ適応した画像を生成する事が可能になる。

[Stochastic Optimization with Importance Sampling for Regularized Loss Minimization](http://jmlr.org/proceedings/papers/v37/zhaoa15.pdf), ICML2015
従来より訓練データを一様サンプリングし、それに基づいてstochastic optimizationを行う手法がある。
これはProximal Stochastic Mirror DescentやProximal stochastic dual descentを含む。
これらは一様サンプリングに基づくため不偏推定が可能であるが、しかし分散がおおきくなってしまうデメリットがある。
本論ではimportance samplingを用いる事で分散を軽減し収束レートを改善する手法を提案する。

[Layer Normalization](https://arxiv.org/abs/1607.06450)
各層のニューロンをnromalizeする事で学習効率を改善する事が知られている。
従来提案されているbatch normalizationは、ミニバッチに関して得られる入力分布に基づいた平均と分散を計算し、それにより入力をnormalizeする。
この手法はしかし入力バッチのサイズに依存しており、RNNに対してはどのように適用すれば良いかは決まらない。
本論で提案する手法は単一の訓練サンプルに対して、各ニューロンへの入力分布を考え、それを利用したnormalize手法を提案する。
この手法はbatch normalizationと同様に、normalize後で非線形活性関数を適用する前に、それぞれのニューロンへのadaptive biasとgainを計算する。
またbatch normalizationと違い、訓練時とテスト時で全く同じ計算を要求する。
RNNに対しても各時間ステップを分けてnormalizationを行う事にすれば、同じ枠組みで適用可能になる。
これによりRNNの各ニューロンを安定化する事が可能になる。
機械学習論文読みメモ_65


[Unifying Count-Based Exploration and Intrinsic Motivation](https://papers.nips.cc/paper/6383-unifying-count-based-exploration-and-intrinsic-motivation.pdf), NIPS2016
強化学習において、agentから見た環境の不確実性を扱い、また複数の観測を通した不確実性の一般化を行う。
ここでは特に、tabular形式でない（連続的？）空間における探索を考える。
Intrinsic motivationの考え方を応用し、sequential density modelにより不確実性を測る。
また任意のsequential density modelよりpseudo-countを導出する手法を提案する。
この手法を用いる事でcount-basedの探索モデルをnon-tabularなモデルに対しても適用可能になる。

[Difference Target Propagation](https://arxiv.org/pdf/1412.7525.pdf), ECML/PKDD2015
誤差伝搬法は偏微分を用いて各重みに対する勾配の割り当てが行われ、それらは極小値になるため、多層または非線形なモデル構造の場合はその活用が難しい。
こうした誤差伝搬手法は生物学的にも説明がつけ難いものであり、従来いくつかの代替的な割り当て手法が提案されてきた。
本論では新たなにtarget propagationと呼ばれる割り当て手法を提案する。
この手法は勾配ではなくニューロンそのものを直接計算する。
そしてこの結果は誤差伝搬法と同じく伝搬していく。
従来の代替手法は対称行列の重みで成り立つbackwardネットワークを用いるが、今回提案するものは各層において定義したauto-encoderを用いる。
この手法を用いた場合、実数だけでなくbit情報を用いたやり取りが可能になる。
Auto-encoderの不完全性を線形補間していくモデルを利用する事でtarget propagationがより良く働く。

[Ladder Variational Autoencoders](https://arxiv.org/pdf/1602.02282.pdf), NIPS2016
Variational autoencoderは教師なし学習において威力を発揮するモデルである。
しかし多層モデルの場合は各層間で長く繋がった依存関係を持つ変数の学習は難しくなってくる。
本論で提案する手法はLadder networkをベースにしており、各層毎に生成分布を考え、それらをrecursiveに集めてくる事でよりタイトな変分下界を利用可能になる。
機械学習論文読みメモ_64


[Variational Inference for Monte Carlo Objectives](https://arxiv.org/pdf/1602.06725.pdf), ICML2016
最近のdeep latent variable modelは変分推論の利用で発展してきた。
最近の手法では。multi-importance samplingを利用する事でさらにタイトな変分下界を利用可能になった。
本論ではこのmutli-sample samplingを離散変数に対して適用し、その勾配推論に関する困難さを解析した。
特に勾配に関する不偏推定手法を提案し、生成モデルやstructured outputモデルの学習に利用した。

[One-Shot Generalization in Deep Generative Models](https://arxiv.org/pdf/1603.05106.pdf)
人間は１つのサンプルより新しいコンセプトや例に対するコンセプト、構造、あるいはバリエーションを生み出す事が可能である。
本論ではこうした機能を、bayesian reasoningの機能をもたせたdeep learningを用いる事で実現する。
今回提案するモデルはsequence generative modelを提案しフィードバックとアテンションの構造を取り入れる。
この２つの機能を用いる事で高性能なoneshotベースの生成分布推定及び画像生成が可能になる。

[Weight Normalization: A Simple Reparameterization to Accelerate Training of Deep Neural Networks](https://arxiv.org/pdf/1602.07868.pdf)
本論ではweight normalizationを提案する。
これは、neural netの重みベクトルをその向きに応じてその長さを分解するreparameterizationを行う。
これにより最適化において適切なconditioningが行われるためsgdの収束性が良くなる。
この手法はbatch normalizationにインスパイアされているが、batch normalizationと違いサンプルに依存した最適化を行わない。
これによりLSTMやreinforcement learning、generative modelといった従来では難しかったモデルにも適用可能になった。
またこの手法はシンプルながら計算効率も良い。
機械学習論文読みメモ_63


[Preconditioned Stochastic Gradient Langevin Dynamics for Deep Neural Networks](http://people.ee.duke.edu/~lcarin/aaai_psgld_final.pdf), AAAI2016
Deep learningの学習には２つの大きな課題がある。
１つ目はパラメータ空間におけるこれらモデルの形状は病的な曲率を持つ事である。
従来研究はSGDに対してadaptive preconditioningを行う事でこれに対処してきた。
この手法はパラメータ空間の局所構造に合わせて最適化を行う事で性能を改善する。
２つ目は過剰適合の問題で、これはearly stoppingを活用する事で対象可能である。
しかし最近の研究によってbaysian model averagingを活用する事で可能である。
モデルに関わる事後分布はstochastic gradient Langevin dynamics(SGLD)を通してサンプリング可能であるが、曲率が激しく変わるようなパラメータ空間においては、あまり有効ではない。
本論ではadaptive preconditionerをSGLDに組み合わせる事でこれに対処する手法を提案する。
またこの手法に関するasymptotic convergenceやpredictive riskに関する理論的特性を与える。

[Renyi Divergence Variational Inference](https://arxiv.org/pdf/1602.02311.pdf)
従来の変分推論をrenyi divergenceを用いて構築する。
この新たな枠組みは既存の様々な手法を統一可能で、パラメータαをコントロールする事でevidence lower-bound(ELBO)からlog周辺化尤度までを内挿する事ができる。
Reparameterization trick, monte carlo近似, stochastice optimizationを利用する事で統一的な最適化フレームワークを提供する。

[ALL YOU NEED IS A GOOD INIT](http://cmp.felk.cvut.cz/~mishkdmy/papers/mishkin-iclr2016.pdf), ICLR2016
新しいdeep learningの初期化手法としてlayer-sequential unit-variance (LSUV)を提案する。
これは２つのステップから成り立つ。
まずはじめにプレ初期化として正規直交行列により初期化する。
その次に、最初の層から順に、各層の出力の分散を１にしていく。
従来、モデルによって異なった初期化プロセスが要求されるが、提案手法は統一的に利用可能である。
実際、Maxout, ReLU, tanhなどの活性化関数を用いた時に実験的に、テスト時の性能が通常手法以上になり、FitNetsやHighway netなどの複雑なvery deep netと同等以上の速度を持つことができる。
Djangoのコンソールにデバッグのメッセージを出力する方法

通常のDjangoの設定では，コンソールにデバッグメッセージが出力されないのでsetting.pyに設定を書かなくてはいけません．
print文でも出力はできますが，loggingで表示した方が健康的ですし，多くの情報を表示することができます．

setting.pyの最後の行に以下を追加します．
logging.basicConfigによってフォーマットを自由に設定できるようです．

```python:setting.py
import logging

# For debugging 
if DEBUG:
    # will output to your console
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
    )
else:
    # will output to logging file
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
        filename = '/my_log_file.log',
        filemode = 'a'
    )
```

デバッグメッセージの出力は，logging.debug()で表示することができます．

```py3
import logging

def article_edit(request, pk):
    post = get_object_or_404(Article, pk=pk)
    if request.method =="POST"
        # コンソールにデバッグメッセージを出力する
        logging.debug('debug message')
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.published_date = timezone.now()
            post.save()
            return redirect('article_detail', pk = post.pk)
    else:
        form = ArticleForm(instance=post)
    return render(request, 'blog/article_edit.html', {'form' : form})
```

loggingの詳細は以下を参考にしてください．
https://docs.djangoproject.com/en/1.11/topics/logging/
WWAWingのコンパイル方法

# WWAWingとは
以下参照
http://wwawing.com/
https://github.com/WWAWing/WWAWing

## WWAWingのローカルでの動かし方
(※昔は補足が必要なほど動作手順が複雑だったのですが、
現在は公式のReadmeの通りに実行すれば簡単に動きます。)

```
# リポジトリをクローンしてください
$ git clone git@github.com:WWAWing/WWAWing.git
## クローンしたリポジトリのディレクトリに入ります
$ cd WWAWing
## 依存しているライブラリをインストールします
$ npm install
$ npm run bootstrap ## 内部的に lerna bootstrap が呼ばれます
$ npm run build ## 各種ソースをコンパイルします
## 開発用のサーバを起動します (内部的にengine ディレクトリ下での npm startが呼び出されます。)
$ npm start
```

* 引用
  * https://github.com/WWAWing/WWAWing#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%97%E3%81%9F%E3%81%84
  *
mac Sierraでcaps lockキーが遅延する

# 何
- macでOSをSierraにするとcaps lockキーが効いたり効かなかったりするようになったので解決する

## 概要
- caps lockキーにcontrolキーを割り当てて、"caps lock"+aや"caps lock"+eで、カーソルを先頭末尾に移動していた。
- 参考）https://wayohoo.com/mac/tips/control-7-shortcut-key.html
- sierraにすると、"caps lock"+aが、"aの入力"になってしまうことがあり、ストレスになった。

## 原因
- 参考）https://discussions.apple.com/thread/7700948?start=0&tstart=0
- caps lockの誤入力を防ぐために、入力を検知するまでの時間が伸びた模様。（割り当てを変えて頻繁に使うのはプログラマーくらいなのでしょう）

## 解決法
- 再起動すると元に戻るので根本解決ではない
- システム環境設定→キーボード→修飾キー
- caps lockを「アクションなし」にして、OKから、システム環境設定を閉じて、システム環境設定を開き直して再度キーを割り当てる


## その他
- 日本語の情報が見当たらないため記事を起こしました。最新の情報や不備がありましたら教えてください。

## 追記
- 解決法をして、再起動していなくても再発するときがある？
MacのEclipse,AndroidStudio,VisualStudioCodeショートカットキー対応表

以前の記事
http://qiita.com/Tazake/items/5c725a8b68d13271d43d

VisualStudioCodeを使い始めたので新たに記事を作りました
色々書くと逆に読みにくくなるんでよく使うもののみ


やりたいこと | Eclipse(Mac) | AndroidStudio(Mac) | VSCode(Mac) 
------- | :-------: | :------: | :------:
フォーマット | ⇧⌘F | ⌥⌘L | ⇧⌥F
リネーム | ⌥⌘R | ⇧F6 | F2
定義へジャンプ |  | ⌘B | F12
呼び出し元をリスト | | ^⌥H | ⇧F12 
クイックフィックス |  | ⌥Enter | ⌘.
サジェスト | | ⌃Space | ⌃Space (IME切り替えと競合して動かないよ!)
前へ | | ⌘[ | ^-
layoutにtitleなどのデータを引き渡す

#sinatraでタイトルをview側から動的にlayoutにデータを引き渡したいときの対処法
####これをやろうと思った理由
railsだとprovideヘルパで解決できたりするけど、sinatraだとうまくいかなかったので、以下の方法でやってみたいと思います。

今回view側からと言うことでこのようなやり方でやりました

app.rb側では

```app.rb
get '/' do
  erb :index
end
```
views側では

```views/layout.erb
<title><%= @viewtitle %></title>
```

```views/index.erb
<% @viewtitle = "index" %>
```
5分でUnicornを設定する。--Unicorn,Nginx

前回は、NginxとUnicornの連携はsock名を同一にする、ということをお話しました。
それを踏まえて、進めていきます。

#デモ
<a href="http://candii.tk">デモ</a>
<a href="https://github.com/sagaekeiga/deploy">Git Hub</a>

#Unicornのインストール

```
gem 'unicorn'
bundle
```

#Unicorn.rbファイルの作成

自動では作成されませんので手動で作成しましょう。
このファイルの中身がunicornの設定を行うものになります。


```ruby:config/uncorn.rb
worker_processes 2
working_directory "/home/anime/deploy_sample/current" #appと同じ階層を指定

timeout 3600


listen "/var/run/unicorn/Nginxで設定した名前.sock" ★
pid "/var/run/unicorn/Nginxで設定した名前.pid"


stderr_path "/home/anime/deploy_sample/current/log/unicorn.log"
stdout_path "/home/anime/deploy_sample/current/log/unicorn.log"


preload_app true
```

これだけで済みます。
特に★の部分の名前には気をつけてください。

&nbsp;

冒頭でも説明しましたが、
ここの名前を一致させることでNginxと連携させることができます。
<pre>working_directory "/home/anime/deploy_sample/current" #appと同じ階層を指定
</pre>
unicornを起動するディレクトリを指定します。
currentの下にはアプリが存在します。


デプロイ時は/home/anime/deploy_sample/の下にアプリを置いてくれと設定したことを思い出してください。



今回はこのような設定を書きました。

```ruby
worker_processes 2
working_directory "/home/anime/deploy_sample/current"

timeout 3600


listen "/var/run/unicorn/unicorn_deploy_sample.sock"
pid "/var/run/unicorn/unicorn_deploy_sample.pid"


stderr_path "/home/anime/deploy_sample/current/log/unicorn.log"
stdout_path "/home/anime/deploy_sample/current/log/unicorn.log"


preload_app true
```



さて、これをgitに入れてデプロイ、その後起動してみましょう。

&nbsp;

&nbsp;

```
$ git add .
$ git commit -m ユニコーン
$ git push
$ cap production deploy

起動
[anime@tk2-241-30026 current]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
[anime@tk2-241-30026 current]$
```


できた！と、思ったら、production環境のシークレットキーを設定していなく、HTTP500エラーです。

#シークレットキーの作成


```
$ bundle exec rake secret
```


生成されたキーをsecret.ymlに設定します。

config/secret.yml

```yml
production:
  secret_key_base: 生成されたキー
```


もう一度デプロイして結果を確認します。
<a href="http://candii.tk">デモ</a>

できました。


再起動した時に以下のエラーが出ますが、これはすでにアプリケーションサーバが起動している為です。

```
master failed to start, check stderr log for details
```


ですので、以下のようにプロセスを殺して起動してください。
プロセスIDはその度に異なるので、適切に処置してください。
　

```
[anime@tk2-241-30026 current]$ ps -ef | grep unicorn                                                                              
anime    22414     1  0 00:18 ?        00:00:01 unicorn_rails master -c config/unicorn.rb -E production -D                                                                                  
anime    22417 22414  0 00:18 ?        00:00:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D                                                                               
anime    22420 22414  0 00:18 ?        00:00:00 unicorn_rails worker[1] -c config/unicorn.rb -E production -D                                                                                                                                                            
[anime@tk2-241-30026 current]$ kill -QUIT 22414
[anime@tk2-241-30026 current]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
```






以上です。
いかがでしょうか？



*********************************************************
個人のコードレビューを売り買いできるサービス: https://www.pullimage.com/
*********************************************************
Linux基本操作備忘録_リスト表示編

ファイルやディレクトリの一覧を見るコマンド
　ls（オプション）
　現在のディレクトリのファイルとディレクトリを表示

lsコマンドオプション
 ls -a
 .(ピリオド)で始まるファイル（基本的にシステムファイル）も表示する

　ls -l（ll）
　ファイルの詳細を表示する「
表示例：-rw-rw---x 1 user group 256 5月  7 15:00 2017 file

それぞれを個別に解説
１（-）２（rw-rw---x）３（1）４（user）５（group）
６（256）７（5月  7 15:00 2017）８（file）

１（-）はファイルタイプ。「-」はファイル、「d」はディレクトリ、「l」はシンボリックリンク

２（rw-rw---x）はパーミッション。パーミッションは操作許可設定。
rwx-の４つの記号で表現される、記号３桁で１セットの計９桁３種類の許可設定。
左から所有者ユーザ、グループ、その他のユーザとなっている。
r：読み取り権：表示が可能か、ファイル(more,cat,cp)、ディレクトリ(ls)
w：書き込み権：ファイル(編集が可能、vi)、ディレクトリ(ディレクトリ内のディレクトリやファイルが作成、削除可能、mkdir,touch,rmなど)
x：実行権：ファイル(実行ファイルとして実行できる)、ディレクトリ(他ディレクトリへの移動やコピーができる)
-：権限無し

３（1）はハードリンクの数、ハードリンクについては後述

４（user）は所有するユーザのユーザ名

５（group）は所属するグループのグループ名

６（256）はサイズ、何バイトか

７（5月  7 15:00 2017）はタイムスタンプ、この場合は最終変更日時

８（file）はファイル名
」

 ls -r
 逆順に表示する、-lや-ltオプションと合わせて-lrや-tlrとして使うことが多い。

 ls -tl
 更新時間順に並べる、これで新しいファイルが上に古いファイルが下になる。
-tlrで古いファイルが上に新しいファイルが下になる

 ls -S
 ファイルサイズ順に並べる。lとあわせて-lSとして使うことが多い。
これで降順、-lSrで昇順。

 ls -X
 ファイルを拡張子毎にまとめる、lとあわせて-Xlとして使うことが多い。

 ls -R
 サブディレクトリの中も表示する。

 ls -F
 ディレクトリ名の後に「/」をファイル名の後に「*」をつける。
lとあわせて-lFとして使うことが多い。

 ls --help
 lsコマンドのヘルプを表示する。
Atom で autohide-tree-view が動かなくなって困っている人へ

(！)2017/05/17更新：Atom 1.17.0 がリリースされました。1.17.0 では、この方法は使えないようですのでご注意ください。


Atom のプラグインのひとつ、[autohide-tree-view](https://atom.io/packages/autohide-tree-view) は大変便利なライブラリなのですが、数年前からずっと動かないままです。
Atom 1.5 の頃から API が変わって、動かなくなってしまいました。[レポジトリ](https://github.com/olmokramer/atom-autohide-tree-view)もアップデートされる様子がなく、今後も直る可能性は薄いでしょう。[^1]

が、設定をちょっといじると、完全復活とはいきませんが、部分的に機能を復活させることができます。
ソースをいじれば、完全復活もできます。
参考：https://www.bountysource.com/issues/32946964-failed-to-execute-animate-on-element-partial-keyframes-are-not-supported

# 設定いじって部分的に復活させる
この方法の場合、アニメーションは復活しません。

メニューから、「Atom」→「config」と開く。
次のような設定ファイルが表示されるはずです

```coffeescript
"*":
  "activate-power-mode":
    autoToggle: false
  "atom-beautify":
    general:
      _analyticsUserId: "625b554d-eff2-4dc9-83c3-3e35332bf415"
    sql:
      indent_size: 2
  "atom-clock":
    dateFormat: "HH:mm"
    showClockIcon: true
  "autocomplete-plus": {}
  "autocomplete-python":
    triggerCompletionRegex: "([a-zA-Z_][a-zA-Z0-9_]*)"
    useKite: false
  "autohide-tree-view":
    minWidth: 3
    showDelay: 0
    hideDelay: 0
  "bracket-matcher":
    autocompleteBrackets: false
    autocompleteSmartQuotes: false
  core:
    allowPendingPaneItems: false
    disabledPackages: [
      "highlight-selected"
      "activate-power-mode"
      "symbols-tree-view"
以下略
```

`autohide-tree-view` の項を探して、次のように修正してください：

```coffeescript
"autohide-tree-view":
  minWidth: 3
```

# アニメーションも復活させる
※プラグインのソースを直接書き換えます。将来どうなるかわからないので、この方法は自己責任でお願いします。
[この問題を解決するプルリク](https://github.com/olmokramer/atom-autohide-tree-view/pull/71)から diff を取ってきて、自分のローカルファイルに適用すれば、アニメーションも無事復活します。
書き換えは2行だけなので、手動でやってしまってもよいでしょう。
`~/.atom/packages/autohide-tree-view/lib/autohide-tree-view.js` (`~` は環境によって異なるかもしれません。`.atom` のある場所を探してみてください) の 173 行目を、次のように編集します：

```diff
-      {width: initialWidth},
-      {width: targetWidth},
+      {width: `${initialWidth}px`},
+      {width: `${targetWidth}px`},
```

編集後は Atom を再起動する必要があります。

[^1]: [プルリク](https://github.com/olmokramer/atom-autohide-tree-view/pull/71) が出ていますが、マージされる気配もありません。
dotfilesをgitで管理


##まず、dotfilesにGITで管理したいのをまとめます。

まとめる先のファイルを作ります。

```
$ mkdir dotfiles
```

Windowsで言うショートカットを作成します。
例)　

```
$ ln -sf ~/dotfiles/.tmux.conf  ~/.tmux.conf
$ ln -sf ~/dotfiles/.vimrc ~/.vimrc
```

##GITにアップロードします。

```
$ git init
$ git add .
$ git commit -m "commit message"
$ git remote add origin [URL]
$ git push -u origin master
```
GitLab CIを使ってGoogle Apps Scriptを自動デプロイ


## 前置き
社内のツールを色々とGoogle Apps Scriptを使って、開発していたが、ローカルでコードを書いて、GitLabにpushして、MRを発行して、レビューされて、手でコピペを繰り返していたが、Gitlab CIを使って、自動で反映できないかなと考えていたところ、[Google Apps Scriptをローカルで開発する](http://qiita.com/ttyokoyama/items/a4edfdcfcad56d664522)の記事を発見したので、一連の処理をGitLab CIにやらせてみた。

## やってみたこと
* GitLabで、masterブランチにマージされたら、deployされるようにした
* node-google-apps-scriptで利用する認証情報を、Secret Variables経由で設定
	* リポジトリには、含めたくなかったので

## 環境情報
* GitLab Community Edition 9.1.0-pre


## 必要なもの
* Googleのアカウント
* [node-google-apps-script](https://github.com/danthareja/node-google-apps-script)
	* 使い方は、githubページ、もしくは参考資料をご確認ください。


## ディレクトリ構成
```
.
├── .gitignore
├── .gitlab-ci.yml
├── README.md
├── gapps.config.json
└── src
    └── sample.js
```

## GitLab CIの設定

### Secret Variablesの設定
* 該当リポジトリの`Settings`から`CI/CD Pipelines`に遷移
![settings.png](https://qiita-image-store.s3.amazonaws.com/0/120666/5d096634-5040-5105-a2d4-57550a251194.png "settings.png")


* `Secret Variables`の項目に値を入力
![Secret Variables.png](https://qiita-image-store.s3.amazonaws.com/0/120666/69c663a3-24e4-cafc-afad-defb3508e154.png "Secret Variables.png")
	* `Key`に`gapps`と入力
	* [gappsコマンドを使って認証](http://qiita.com/ttyokoyama/items/a4edfdcfcad56d664522#gapps%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E8%AA%8D%E8%A8%BC)の結果、`~/.gapps`に生成されるjsonを`Value`に入力


### 設定ファイルの作成

```.gitlab-ci.yml
image: node:4.5.0

stages:
    - deploy_gas

before_script:
  - apt-get update
  - npm install -g node-google-apps-script

deploy:apps:
    stage: deploy_gas
    script:
        - echo ${gapps} > $HOME/.gapps
        - gapps upload
    only:
        - master
```

## 参考資料
http://qiita.com/ttyokoyama/items/a4edfdcfcad56d664522
Kerasで分岐・結合を持つNNを素早く書く

#環境
Python 3.5.2
Keras 2.0.4
tensorflow-gpu 1.1.0

#分岐も簡単に書きたい
Sequentialモデルは

```py3
from keras.models import Sequential
from keras.layers import InputLayer, Dense, Activation
model = Sequential()
model.add(InputLayer(input_shape=(32,)))
model.add(Dense(32, activation='relu'))
model.add(Dense(16, activation='relu'))
#...
```
簡単に分岐のないモデルが書ける！
一方で複雑な構造記述で有利なFunctional APIは

```py3
from keras.layers import Input, Dense
_input = Input((32,))
x = Dense(32, activation='relu')(_input)
x = Dense(16, activation='relu')(x)
#...
```
initのカッコとcallのカッコが並んでいたり、右から左へ積んでいたり、
分岐する度に一時変数が必要だったり…
Sequentialモデルのようにサクッと書きたい。

ということで

#関数定義

```py3
def build(_in, *nodes):
    x = _in
    for node in nodes:
        if callable(node):
            x = node(x)
        elif isinstance(node, list):
            x = [build(x, branch) for branch in node]
        elif isinstance(node, tuple):
            x = build(x, *node)
        else:
            x = node
    return x
```

分岐はリスト、Sequentialな積み上げはタプルで表現して
この関数に突っ込みます。

#使用例
追加中...
##分岐→和→分岐→積
![example_1.png](https://qiita-image-store.s3.amazonaws.com/0/150382/f7aee30e-1cf9-c0b7-c5ba-95fda078e388.png)

```py3
from keras.models import Model
from keras.layers import Input, Dense, Add, Multiply
def example_1():
    _input = Input((10,))
    _output = build(
        _input,
        Dense(10),
        [Dense(11, activation='relu'), Dense(11, activation='relu')],
        Add(),
        [Dense(12, activation='relu'), Dense(12, activation='relu')],
        Multiply(),
        )
    model = Model(_input, _output)
    return model
```

##2入力2出力
このモデル
https://keras.io/getting-started/functional-api-guide/#multi-input-and-multi-output-models
を書いてみます。
![example_multi_input_and_multi_output.png](https://qiita-image-store.s3.amazonaws.com/0/150382/fa8eb39d-e672-0132-2ee2-ae0fcf04139d.png)

```py3
from keras.models import Model
from keras.layers import Input, Dense, Embedding, LSTM, Concatenate
def example_multi_input_and_multi_output():
    main_input = Input(shape=(100,), dtype='int32', name='main_input')
    auxiliary_input = Input(shape=(5,), name='aux_input')
    outputs = build(
        main_input,
        Embedding(output_dim=512, input_dim=10000, input_length=100),
        LSTM(32),
        [Dense(1, activation='sigmoid', name='aux_output'),
         ([auxiliary_input, lambda x: x],
          Concatenate(),
          Dense(64, activation='relu'),
          Dense(64, activation='relu'),
          Dense(64, activation='relu'),
          Dense(1, activation='sigmoid', name='main_output')
         )
        ]
    )
    model = Model([main_input, auxiliary_input], outputs)
    return model
```

##ResNet
![example_residual_connection.png](https://qiita-image-store.s3.amazonaws.com/0/150382/1e12f6d4-9889-b91a-08cd-e8fecc0acab6.png)

```py3
def example_residual_connection():
    _input = Input(shape=(256, 256, 3))
    _output = build(
        _input,
        [(Conv2D(3, (3, 3), padding='same'),
          Activation('relu'),
          Conv2D(3, (3, 3), padding='same')),
         lambda x: x],
        Add(),
        Activation('relu')
    )
    model = Model(_input, _output)
    return model
```
Linux關機命令

# shutdown

shutdown [option] [time]

option:

- `-c` 取消關機命令
- `-h` 關機
- `-r` 重新開機

```bash
$ shutdown now
$ shutdown -r now
```

<!---more--->

```bash
[cyberjun@localhost ~]$ shutdown -r 05:30
Must be root.
[cyberjun@localhost ~]$ su
密碼：
[root@localhost cyberjun]# shutdown -r 05:30
Shutdown scheduled for 五 2017-04-28 05:30:00 CST, use 'shutdown -c' to cancel.
[root@localhost cyberjun]# shutdown -c

Broadcast message from root@localhost.localdomain (Thu 2017-04-27 17:21:20 CST):

The system shutdown has been cancelled at Thu 2017-04-27 17:22:20 CST!
```

shutdown的關機比較安全，如果可以的話還是使用shutdown來關機，如果有打開一些伺服器、網路接口之類的就必須先關掉在關機會比較安全。

# half、poweroff、init 0 

```bash
# halt
# poweroff
# init 0
```

直接關機，這三個指令和shutdown比起來爛了不少，如果可以用shutdown就用shutdown，上面三個指令執行會有一些資料沒有貯存。

# 其他重啟命令

```bash
# reboot
# init 6
```

# init 運行級別

```bash
$ man init
```

其中內容

```bash 
SIGHUP
           Reloads the complete daemon configuration. This is mostly
           equivalent to systemctl daemon-reload.

       SIGRTMIN+0
           Enters default mode, starts the default.target unit. This is mostly
           equivalent to systemctl start default.target.

       SIGRTMIN+1
           Enters rescue mode, starts the rescue.target unit. This is mostly
           equivalent to systemctl isolate rescue.target.

       SIGRTMIN+2
           Enters emergency mode, starts the emergency.service unit. This is
           mostly equivalent to systemctl isolate emergency.service.

       SIGRTMIN+3
           Halts the machine, starts the halt.target unit. This is mostly
           equivalent to systemctl start halt.target.
SIGRTMIN+4
           Powers off the machine, starts the poweroff.target unit. This is
           mostly equivalent to systemctl start poweroff.target.

       SIGRTMIN+5
           Reboots the machine, starts the reboot.target unit. This is mostly
           equivalent to systemctl start reboot.target.

       SIGRTMIN+6
           Reboots the machine via kexec, starts the kexec.target unit. This
           is mostly equivalent to systemctl start kexec.target.
.
.
.
```

級別|動作
---|---
0|關機
1|救援模式
3|進入文字界面
5|進入GUI模式
6|重新開機

如果要查詢現在界面所在的級別可以執行`runlevel`；注意！我是使用CentOS來舉例，如果是Debian的系統就不一樣了，要自己去用`man`查詢。

```bash
$ runlevel
N 3 ##在文字界面
```

如果要設定開機之後進入的級別可以找`/etc/inittab`文件看一下，其中級別0和級別6，是不能設定在裡面的，如果設定了，初學者大概只有重新安裝這個辦法了。

```bash
$ cat /etc/inittab
# inittab is no longer used when using systemd.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target
#
id:3:initdefault:
```

# 退出登錄

>Linux支援256個遠端登錄，Windows XP 1個、Windows Sever 2003 2個、Windows Sever 2008 4~8個

如果我們遠端登入沒有登出的話會造成下一次可能登入不了的問題，舉一個例子，如果我用Windows XP遠端登入，然後我們直接關掉，沒有登出，直接關掉終端機，在下一次登入的時候，有可能會登不進去，因為Windows XP只能一個遠端登入，所以登出是很重要的習慣。

```bash
# logout
```
Unity トゥーン調エフェクト

#**はじめに**
Unity5.5の標準Particle Systemを使った**トゥーン調エフェクト**の話です。
![Fire](https://j.gifs.com/2Rmn8v.gif)

#**Unityパーティクルが進化した**
Unity5.5からノーマルマップを使ったライティングが可能になりました。
![パーティクル比較.png](https://qiita-image-store.s3.amazonaws.com/0/100182/2a70e950-bc33-7fd6-55fb-9737279d33d5.png)
左画像：ノーマルマップを使ってライティングしたパーティクル

#**Toon Shaderパーティクルの作成**
以前に紹介した[3Dアニメ表現](http://qiita.com/MuRo_CG/items/c417ef6d6cbeed3dd42b)を応用しつつ、ライトの光源を利用したをトゥーンパーティクルを作ってみる。
Toon Shaderで**アルファ抜き+ノーマルマップ**が出来るようにShaderを調整。
カラーは**ToonRamp**で調整していきます。
ToonRampの比率によってライトを当てた時の見え方が変わってくる。
![ToonRamp比較.png](https://qiita-image-store.s3.amazonaws.com/0/100182/75ef6472-de09-4dfc-9625-b5b064a6e9dd.png)
※全部同じライティングです
カラーの割合と色味をこだわって調整すると良いです。


#**Image Effectsを付ける**
最後にImage Effectsで発光と色調を整えて完成。
![イメージエフェクト比較.png](https://qiita-image-store.s3.amazonaws.com/0/100182/54f9aefe-5aa0-4f3b-03a3-ef67ad1eda63.png)
左画像：適用前
右画像：適用後


#**最後に**
今回は炎エフェクトを作りましたが、もちろん他のエフェクト作りにも応用できます。
お試しあれ。
![煙.png](https://qiita-image-store.s3.amazonaws.com/0/100182/d78fb270-6638-3a77-3871-8309c772136d.png)
（例）煙エフェクト
tf.layers.denseメモ

TensorFlowの[tf.layers.dense](https://www.tensorflow.org/api_docs/python/tf/layers/dense)について動作メモ
TensorFlowのバージョンは1.1です。

```python:サンプル
inputs = tf.Variable([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]],dtype=tf.float32)
outputs = tf.layers.dense(inputs, units=2)
input_shape = inputs.get_shape()
output_shape = outputs.get_shape()
with tf.Session() as sess:
     sess.run(tf.global_variables_initializer())
     outputs_m = sess.run([outputs])
     print(outputs_m)
     print(input_shape)
     print(output_shape)
```
を実行すると

```python:結果
[array([[[ -2.30599022,   0.86052746],
        [ -6.50499964,   1.60668135]],

       [[-10.70400906,   2.35283518],
        [-14.903018  ,   3.09898901]]], dtype=float32)]
(2, 2, 3)
(2, 2, 2)
```
となります。unitsに入れた値で変わってます。
outputの値は、乱数のseedの指定しないと毎回変更されるみたい。
次元を増やすと、

```python:サンプル
inputs = tf.Variable([[[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]],               
        [[[13,14,15], [16,17,18]], [[19,20,21],[21,22,23]]]],  dtype=tf.float32)
outputs = tf.layers.dense(inputs, 2)
input_shape = inputs.get_shape()
output_shape = outputs.get_shape()
with tf.Session() as sess:
     sess.run(tf.global_variables_initializer())
     outputs_m = sess.run([outputs])
     print(outputs_m)
     print(input_shape)
     print(output_shape)
```
結果は、

```python:結果
[array([[[[  4.34919119,   1.06798601],
         [ 10.13897705,   1.18018818]],

        [[ 15.92876434,   1.29238999],
         [ 21.71855164,   1.40459204]]],


       [[[ 27.50833702,   1.51679313],
         [ 33.29812241,   1.62899613]],

        [[ 39.0879097 ,   1.74119818],
         [ 42.94776917,   1.81599891]]]], dtype=float32)]
(2, 2, 2, 3)
(2, 2, 2, 2)
```
となりました。outputsの値は、乱数のシードを設定しないと、毎回出てくる値は変わりますね。
Sublime Text 3 で Jupyter カーネルを使ってコード実行、補完 etc...するプラグインを書いている

2017/6/6 更新: Package Control Channel に入れてもらえました！ Package Control で Hermes を探してもらえばインストールできます。


タイトルの通りです。

今作っているものの紹介記事です。ちゃんとリリースしたあとで「書いた」として記事を上げる方がカッコいい気もしますが、気分転換したくなってきたので書いちゃいます。こんなもん作ってますよという以上ではないです。GW 中にとりあえず Package Control にサブミット出来るくらいが目標だったのですがなかなかそうもいかず。

とりあえず以下にレポへのリンクとスクショです。

https://github.com/ngr-t/SublimeHermes

![image.png](https://qiita-image-store.s3.amazonaws.com/0/53885/5f47933b-67cd-4337-f50a-500ee96c4e12.png)

## 何をするプラグインなの？

Jupyter のプロセスと通信して Sublime Text 上のバッファにあるコードブロックを実行する＆補完の情報を取ってきます。図表なんかは Phantom を使って結果表示用のビューの中にそのまま表示します。関数のシグネチャとかも取ってこれるようにしようと考えています。
Atom には [Hydrogen](https://atom.io/packages/hydrogen) というクレイジープラグインがあるのですが、それの自分流移植版てなところです。

そもそも Sublime Text ではエディタ内でのコード実行に[SublimREPL](https://packagecontrol.io/packages/SublimeREPL) というパッケージが合ったわけですが、それのメンテ止まっていたこと(最近再開したようなのですが)が開発の動機だったりします。また、Atom に浮気している時に先述の Hydrogen に出会ってしまったことで、「Jupyter のプロトコル使えば、理想的にはカーネルのあるあらゆる言語でコード実行と補完 etc が出来るプラグイン書けるじゃん！」ということに気付かされ、ちょこちょこと開発作業を開始したのです。

とりあえずはカーネルに接続してコード実行・結果表示・補完の取得とまあ最低限の機能くらいまでは書けたかなあと思ったので、とりあえずこんな記事を書いちゃっています。


## 何で Jupyter を介するの？

iPython Notebook から名前が変わった Jupyter は今ではいろんな言語を実行することが出来ます。
重要なのは Jupyter のプロトコルを介することでプラグイン側からは同じ操作でコードの実行・補完などの各種情報の取得が出来るようになることです。プラグインから直接インタープリタを叩くとした場合、意外と各インタープリタ(および OS)独特の対応が必要になることがあります。補完なんかも当然言語・インタープリタ依存の処理が必要になります。SublimeREPL が一時メンテ止まっていたのもその辺りの対応に追われているうちに作者がゲンナリしてきたんじゃないかと邪推しています。
でも今は Jupyter カーネルという形で各言語についてそれらを統一的に呼び出せる仕組みが出来ちゃっているので、それに乗っかっちゃおうぜウェーイということです。


## Jupyter Notebook 使えばいいじゃん？

Jupyter Notebook はもちろん目的によっては素晴らしいツールです。すぐ終わるようなデータ分析の結果を簡単に共有できますし、よくわかっていないデータやAPIを探索するときには便利ですし、実行可能なチュートリアルを作成するのにも良いでしょう。けれども、私見ですが、コードベースが大きなプロジェクトになってくると Jupyter Notebook ではいろいろ厳しいです。ipynb 形式ではコードの適切なモジュール化が難しくなりますし、編集が必要になったコードにジャンプしたりするのも面倒です。そしてバージョン管理システムとの食い合わせも良くないです。
コードの再利用性と再現性を高めるためには、データ分析の各処理も高機能なエディタで編集してスクリプトとして書いて、人に見せる資料には Rmarkdown や Pweave を使う方が好ましいワークフローに思えます。
確かにデバッグするときとかプロットを作る時とかはインタラクティブな方が楽ちんだったりはしますけどね。

## 使ってみたい！

などというそんな物好きな方がいるのかどうかわかりませんが、簡単に使い方をば。


### インストール

まだ Package Control にはサブミットすらしていませんが GitHub のレポからクローンすれば使えるはずです。メニューからPreferences->Browse Packages...を選択すると開くフォルダで

```
git clone https://github.com/ngr-t/SublimeHermes Hermes
```

としてクローンしてください。

(アンインストールしたくなったら単純にフォルダごと消しちゃってください)

もちろん Jupyter が実行に必要なのでインストールしてください。Anaconda を使うのが楽ちんかなと思います。

### 使い方

0. Jupyter Notebook を起動してください。
1. コマンドパレットから Hermes: Set URL コマンドを選んで Jupyter のポートが空いているアドレス＆ポートを入力してください。
    - URL のあとでトークンも入力を求められます。設定していなければ空欄のまま Enter を叩いてください。
2. ビューをカーネルに接続します。
    - カーネルが起動していなければ Hermes: Start Kernel コマンドで起動してください。
    - 起動していれば Hermes: Connect Kernel コマンドで繋いでください。
3. Hermes: Execute Block コマンドでコードを実行できます。実行されるコードブロックの判定基準は「カーソルを含む行から連続する行のうち、空行あるいはインデントがより少ない行を跨がない範囲」です。


## 最後に

興味を持った方がおられたら何らかのフィードバックがもらえると嬉しいです。

普段アプリケーション的なものはあまり書かず、ウェブ関連の技術も全然触ってこなかったので、作ってみるとなかなか一筋縄でいかないところが多く新鮮な体験がたくさんありました。
ばっちり実用的なものに仕上げて Sublime Text コミュニティを盛り上げるのにも一役買いたいものです。
【書評】60分でわかる! 機械学習&ディープラーニング 超入門 (60分でわかる! IT知識)

備忘録

「60分でわかる! 機械学習&ディープラーニング 超入門 (60分でわかる! IT知識)」
https://www.amazon.co.jp/60%E5%88%86%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E8%B6%85%E5%85%A5%E9%96%80-IT%E7%9F%A5%E8%AD%98/dp/4774188794/ref=sr_1_1?ie=UTF8&qid=1494157923&sr=8-1&keywords=%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%80%80%E8%B6%85%E5%85%A5%E9%96%80


## 概要
エンジニア、非エンジニア問わず、「機械学習とは何か?」から入るような入門書です。
最近バズワード化している、人工知能、機械学習、ディープラーニング(深層学習)、AlphaGo、自動運転、、、についてモヤッとしているものがスッキリすると思います。
150P程のボリュームで、本のサイズも小さいので通勤時間などにサクッと読めそうです。

機械学習の入門書は何冊かありますが、本書はビジネスマン向けの本なので、ソースコードや数式、技術的に詳しい話は載っていません。

・機械学習で出来ること、出来そうなこと
・機械学習の仕組み
・ビジネス導入事例
・ビジネスへの導入検討
・機械学習ビジネスの未来
について説明されています。

## ディープラーニング(深層学習)とは
ニューラル・ネットワーク(人間の脳のニューロンを模倣したアルゴリズム)を利用した**機械学習の一分野**です。
そして、機械学習とはAI(人工知能)の一分野です。
以下参考図です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/146742/dfeceaa0-7a43-dd18-fd9c-06cc6858591e.png)
Reference:https://www.atkearney.com/operations-performance-transformation/article?/a/will-you-embrace-ai-fast-enough



## AI(人工知能)の分類
ざっくり分けるとAIには「汎用型」と「特化型」という2分野があり、機械学習は後者に属します。
(汎用型とは鉄腕アトムのように何でも出来るロボットのイメージ、特化型とはその名の如く特定の領域でパフォーマンスを発揮する。例えば、自動運転や画像認識など)

### 機械学習の用途
主に
・データの__分類__
・未来の__予測__
・データの__最適化__
・対象の__認識__
に分けられ、ビジネスの目的によって何をどう使うか選択する必要があります。
例えば、商品の需要や将来の株価を知りたい時は「予測」です。

では、なぜコンピューターが予測といった高度な判断を行えるのか。
それはその名の通り「機会」が「学習」することで行えるようになるのですが、
そのアプローチには大きく
・__教師あり学習__:正解ラベル付きデータを使う
・__教師なし学習__:正解ラベルがないデータを使う。データ同士の関係性をコンピューター自身で見つける。
・__強化学習__:良い結果に対して報酬を与える学習
が存在します。

### 1.教師あり学習
教師あり学習は、最も単純な学習アプローチで、「Xという特徴があれば猫、Yという特徴があれば犬」などと正解ラベルの付いたデータを大量に学習させることで精度を向上させていきます。
過去のデータから未来を予測するような場合に有効です。
ただし、正しくラベル付けされた大量のデータの用意が大変です。

### 2.教師なし学習
次に、教師なし学習は、データ同士の類似度を判定することで、例えば顧客購買傾向を割り出してレコメンド商品に応用するといった事が出来ます。

### 3.強化学習
強化学習は、どのような状態で何をしたら報酬(ポイント)が貰えたかを記憶して、これを繰り返します。すると次第に精度が上がり、AlphaGoや自動運転といった分野に活用されています。

## 機械学習で大事な事
機械学習で大事なのは、機械に食べさせる「データ」です。
データに偏りがあったり、十分な数が得られていないと正確な結果を出力出来ません。
金融であれば過去の取引データ、医療であれば過去の診断データ、小売業であれば過去のPOSデータといった、ビジネスで活用可能なデータを用意出来るかが大きなポイントとなります。

## まとめ
といった感じで機械学習における大きな特徴を解説した後(上記以外にも色々ありますが)、
ビジネスにどう適用すれば効果的であるか、といった注意点的なポイントや、
既にこの分野で最先端を走っている企業が展開しているサービスやプラットフォームについてページが割かれています。

最後は、機械学習が適用されると未来はこう変化するかも、といった内容と、
「機械学習注目企業リスト」で締められています。
IT系やロボット関連の企業だけでなく、コンサルティング会社も割と載っていました。

機械学習について知識ゼロの状態で読むにあたっては良かったです。
Ruby｜UnboundMethodで遊んでみた

`UnboundMethod`は仕事では直接的にはお世話になりませんが、
何事もやってみることもありだと思うのでちょっと遊んでみました。

[マニュアル](https://docs.ruby-lang.org/ja/latest/class/UnboundMethod.html)によると、`instance_method`を使うと良さそうです。

```ruby
class Hoge
  def initialize(val)
    @val = val
  end

  def val
    @val
  end

  class << self
    def class_method
      15
    end
  end
end

unbind_method = Hoge.instance_method(:val)
hoge = Hoge.new(20)

p unbind_method.bind(hoge).call  #=> 20
```

`Module`クラスに定義されているので、必然的にクラスがレシーバーになります。
インスタンスメソッドだけはつまらないので、クラスメソッドにも同じことをやってみます。

特異クラスを取得して、`class_method`メソッドを引数に渡して実現しています。

```ruby
singleton = Hoge.singleton_class
unbind_class_method = singleton.instance_method(:class_method)

p unbind_class_method.bind(Hoge).call #=> 15
```

`Method`オブジェクトを作ってからあえて`unbind`メソッドを呼び出して実現しています。
こっちのほうがシンプル？かなと

```ruby
bind_class_method = Hoge.method(:class_method)
unbind_class_method = bind_class_method.unbind

p unbind_class_method.bind(Hoge).call #=> 15
```
Arduboy2ライブラリのスプライトフォーマットはちょっと不思議

Arduboyをさわり始めた。
パタパタアニメを楽に実装しようと思うとフレーム指定で描画を切り替えられるスプライトを使いたくなる。
ろくにドキュメントを読まないとまずはまる点はスプライトのデータはArduboy.drawSlowXYBitmap()で使用するビットマップデータとは形式が違うということ。

開発フォーラムにスプライト用のデータを出力できる[ツールの投稿](https://community.arduboy.com/t/ardu-imconvert-a-desktop-image-converter-for-arduboy/3024 "Ardu-imconvert")があった。
これを使って変換すればデータを得ることができる。
もちろん他にも存在すると思う。
ともあれこのツールのおかげでデータの構成を把握することができた。

データの基本構造は

* １バイト目: スプライトの幅
* ２バイト目: スプライトの高さ
* ３バイト目以降がスプライトのビットマップデータ ✕ Ｎ

となる。
マスクデータも同時に保持する形式もあるが今回はSprites.drawSelfMasked()で使用するデータを想定。（なお複雑な画像を重ねるゲームの場合はおそらくマスクデータをきちんと使いこなす必要がある）

ツールを使っていれば特に気にすることもないと思うがビットマップデータの変換ルールが独特な点をちょっと解説。

次のような画像があったとする。
![t.png](https://qiita-image-store.s3.amazonaws.com/0/67680/d949d5f1-be2a-82a6-3e37-226c0518678a.png)


Arduboy.drawSlowXYBitmap()用のビットマップはこの向きのまま左上から0/1に変換すればよい。
ところがSprites.drawSelfMasked()用のビットマップはちょっとおもしろい変換ルールになっている。
先ほどの画像は次のように左に90度回転した上で8ピクセル毎の垂れ幕の様に切り出して0/1に変換する。
![t-turned.png](https://qiita-image-store.s3.amazonaws.com/0/67680/d7421acf-6595-8779-216f-96b2581bdadb.png)


なんだかちょっと不思議なフォーマットで将来的に改良されるかもしれないが2017/05/07時点では上記の通り。

私は絵を修正するたびにGUIツールを使うのは面倒なので[自分用にコマンドラインツール](https://github.com/kivatek/abspriteconverter "abspriteconverter")を作ってしまった。なお機能的にはまだ最低限。ドキュメントもないという惨状。
OpenPoseをUbuntu16.04で動かす

OpenPoseを動かしてみた。
http://qiita.com/nnn112358/items/a4490d85dac5827db53b

の単なる追試です。

- Ubuntu 16.04 (64bit)
- Geforce GTX1060

# ライブラリインストール
- cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb
- libcudnn6_6.0.21-1+cuda8.0_amd64.deb
- libcudnn6-dev_6.0.21-1+cuda8.0_amd64.deb
をそれぞれ
sudo dpkg -i でインストール

```
export CUDA_HOME=/usr/local/cuda-8.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${CUDA_HOME}/lib64
export PATH=$PATH:${CUDA_HOME}/bin
```
をcudaインストール後に追加する。

また、libEGLがシンボリックリンクではないエラーが出たので参考元と同様に修正

# OpenCV , Atlasインストール
apt-getで同様にインストール

また、
```
sudo apt-get install python-numpy
```
を実行しておかないと後述のcaffeのビルドが失敗したのでインストールを推奨します。

#OpenPoseのインストール
```
git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose.git
```
して
```
chmod u+x install_caffe_and_openpose.sh
```
```
./install_caffe_and_openpose.sh
```
を実行するとインストールが完了し、サンプルの実行が可能になります。

Ubuntuで何も手を加えずにインストールすると、OpenCVは2.7系を使います。

https://twitter.com/izm/status/861171349036736513

#ソースをちょっと見た雑感
関節の3次元座標を直接求めている訳ではないようなので、モーションキャプチャ用途であれば
- 身長から各関節の長さを求めて、画面内の長さから奥行き方向を推定する
- カメラ2個で撮っておいてステレオマッチングで各関節の奥行き座標を求める

などの工夫が必要かもしれません。

また、dockerfileもpull requestに上がっているので、もっと手軽に試せるようになりそうです。
CSSで見出し要素(h1, h2...)の前に自動で採番する方法


例えば、h1タグは"1. 最初の章", "2. 次の章"というように章番号をふることはよくある。
そのときに、手動で採番するのは保守性が悪いし、美しくない。
そんなときはCSSのcounter機能を用いると簡単に自動採番できる。

```css:サンプルコード
body {
    counter-reset: chapter;
}
h1 {
  counter-reset: sub-chapter;
}
h2 {
  counter-reset: section;
}

h1::before {
  counter-increment: chapter;
  content: counter(chapter) ". ";
}
h2::before {
  counter-increment: sub-chapter;
  content: counter(chapter) "-" counter(sub-chapter) ". ";
}
h3::before {
  counter-increment: section;
  content: "(" counter(section) ") ";
}
```


## MDN
仕様は次で確認。

[Using CSS counters - CSS | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters)

## (おまけ)Atomのマークダウンプレビューで設定する方法
基本は同じ。
Atomのstyleはメニューの[Stylesheet]からstyle.lessを開いて編集する。
ポイントは、bodyはmarkdown-previewの外なので、上記設定をすべて`.markdown-preview`の中にいれるとうまくいかない。


```scss:style.less
// for markdown-preview
body {
    counter-reset: chapter;
}
h1 {
  counter-reset: sub-chapter;
}
h2 {
  counter-reset: section;
}
.markdown-preview {
  h1::before {
    counter-increment: chapter;
    content: counter(chapter) ". ";
  }
  h2::before {
    counter-increment: sub-chapter;
    content: counter(chapter) "-" counter(sub-chapter) ". ";
  }
  h3::before {
    counter-increment: section;
    content: "(" counter(section) ") ";
  }
}
```