病みつきエンジニアブログ

機械学習、Python、Scala、JavaScript、などなど

2016 / 2017 総括と今年の目標と今後の方向性と

2016年の振り返りと、2017年の抱負とか。

2016年の総括

2016年は、本当に大変な年だった。おわり。

目次

  • 体重キープした件
  • 家出れるようになった件
  • 君の名はまだ見てない件
  • おうちハックしたい件
  • 今年やった技術とか
  • 今後の方向性とかに悩んでいる件

体重キープした件

大変素晴らしいことに、1年間体重を76kg前後にキープした。毎日体重を計測して、 Twitter のプロフィールに自動反映しているのが効を奏していると思う。オムロンのNFC体重計スマホをぴっとやると、TwitterAPIを叩いて変更する仕組み

家出れるようになった件

大変驚くべきことに、何もなくても家出れるようになった。これだけ書くと人間としてやばいっぽいが、休日家でごろごろマンは多いと思う。

引っ越したのが要因として大きい。徒歩圏内に、Wi-fiと電源のある、まあまあ入れるチェーン店のカフェが複数あるのが大事(スタバと上島珈琲店がある)。今後引っ越すとしても、繁華街の近くに引っ越すのが戦略として正しいっぽい。

君の名はまだ見てない件

シン・ゴジラは見たんだけど、まだ君の名はを見ていない。新宿の映画館とかでまだやっているそうなので、1月中に見に行きたいなと思う。

映画というところで言うと、2016年はギンレイホールに初めて行ってみた。ギンレイホールというのは、いわゆる「名画座」というジャンルの映画館。入れ替え制じゃないので、一回のチケットで2本映画を見られる。雰囲気のわりにはチョイスが古すぎるわけではなく、昨年アカデミー賞とかもやってる。

おうちハックしたい件

おうちハックというのは、家にIoT系の製品とか、Arduinoとかラズパイ取り入れたりする振る舞いのこと。おうちハックできなかったのは、2016年の目標の中で、ちょっと後悔しているものだったりする。

おうちハックに使えそうなものは結構揃ってて、

  • Raspberry Pi 3 Model B
  • IRKit
  • milight とかいう Hue のパクリ製品
  • ルンバ(リモコン付き)
  • mornin という電動カーテン

家に帰ったら、「おかえりなさい」って言いながら、やってないタスクとかを読み上げながら詰ってくるホームアシスタント作りたいなって思っている(もしかして:ジャーヴィス)。AWS に読み上げお姉さん API あるしね。

今年やった技術とか

  • Docker
  • BigQuery
  • AWS Lambda
  • Akka (Scala)
  • Vue.js まわり
  • keras
  • Go

だいたいこんな感じかも。Vue.js とkerasとGoは触りに近いかなorz

結果的には、Docker、Akka、Vue.js はかなり自分の役に立った。特に、プロトタイプ環境やデータ可視化環境を作るのに、Docker と Vue.js が大活躍していて、そのうちブログに書きたい。JSのReactiveなビューライブラリ界隈は、行き着くところはReactでもVue.jsでも(触ったこと無ないがRiot.jsでも)良いと思っていて、けど「手軽にさくっと」みたいな用途だと Vue.js が個人的に良かった。

Go は、本当に手に馴染まなくて辛かった。機会作ってまたやりたい。

機械学習周りは、今年あんまりできなかったなぁ・・・が、クリスマスに会社にGPUサーバーをお願いしたら予算がおりたので、頑張るぞい。GPU使う部でも作ろうかな。会社のデータ資産に機械学習をアプライするっていうところは、自分主導でいろいろと進めたいところ。

今後の方向性に悩む件

僕個人は、メインには技術をやりたいと思っている。特に機械学習周り(もっというとNLP)をビジネスに適用する、という分野に興味がある。これは、全くぶれていない。

唯一ぶれたのは、機械学習というものに対して、「キラキラ技術したいなあ」ではなく「ビジネスを真剣に考えて、課題解決をしたいなあ、あわよくばキラキラ state-of-the-art 良いなあ」という気持ちになったところ。つまりプライオリティが変わった。あと、「NLPって結局ルールベースが一番早いしメンテナブルやんけ!」みたいな諦めも若干あったりする(これを覆せないのは、完全に自分の経験不足に起因する)。

けど、PM的な立場についになってしまった。「なってしまった」というのは完全に言葉の綾で、どちらかといえば真面目にちゃんとマネジメントに取り組みたいし、そういう旨のことを経営陣に言って、そういう立場に置いてもらった、というのが説明として正しい。「自動化できる人間」たるエンジニア、そして「エンジニアの気持ちがわかる人間」たるエンジニアがマネジメントをするというのはとても大事なことで(私が人間の気持ちがわかるとは言っていない)、それは非エンジニアのマネジメントスペシャリストにはない視点。そういうところに問題意識を感じたりするので、「責任と裁量を持って、意見を述べたい」という旨のことを言ったのだった。

さて、ここにコンフリクトが発生する。「マネジメントに真剣に取り組みたい」も真だし、「機械学習のビジネス適用を真剣に取り組みたい」も真だけど、自分の体が一つしかない。

まあ、コンフリクトを解消する手法は単純で、残業とかもっと減らして(弊社、本来はホワイト企業なんだが、仕事脳なので一人ブラック企業している節がある)、周りを巻き込みながら勉強と実践する時間をもっと増やす、というのが正解っぽいし、これを今年一番の目標としたい。せっかくマネジメント側の機能を持つわけだしね、自分もチームも、残業なしに働けるように、頑張らないといけないね。

真人間になるための今年の目標

  • 残業時間を減らす(週に5時間くらいにしたい)
  • 週に5日は1〜2時までに寝る生活習慣を作る
  • 会社のGPUを活用する部を作る
  • ホームアシスタントを作る
  • 今年二回は旅行に行く。一回は一人旅をする。
  • 月に一回は映画館で映画を見る
  • 休日コンスタントに12時ぐらいに家出れるようになる
  • 体重をキープする
  • 週一程度で弁当を作る

振り返ってみたけど、1年というのは振り返るには長すぎるかもしれない。半年ぐらいで振り返りたい。

Dockerfileを生産性高く書く方法についてLTしてきた

10月21日(金)に、JX通信社内での勉強会でDockerfileを生産性高く書く方法のLTをした。

この3ヶ月で、公開しているものだけでも8個ぐらいDockerイメージを作ったらしいw

↑のスライドの要旨を言うと、 Dockerfileを書くときはTmuxとSlimeを活用しましょう!ということ。

Dockerfileを書くとき、「全部書く」→「docker build」→「修正」→「docker build」→「修正」→「docker build」みたいなことをやってると、かなり生産性が悪い。処理の途中でエラーが起きたりするし、apt-getしないといけないものが後から出てきたりする。その度に docker build していると、時間がかかってしまう。

そこで、tmuxとslimeを活用して、Dockerfileを一行ごとに検証していくと良いですよという話。 Tmuxは、Screenとかと一緒で、ターミナルを画面分割して表示するためのもの。 Slime(やその類似プラグイン)は、Tmuxの他のペイン(つまり画面分割した先)に、エディタ上のコードを送って実行するためのもの。

勉強会の様子↓ モニターの裏には泡盛が・・・

f:id:yamitzky:20161021202656p:plain

さて、そんなJX通信社では、エンジニアを募集しています! 興味のある方はぜひお声がけください! Docker力とサーバーレス力がめちゃくちゃ高まる

ちなみに社内勉強会の名前の案を募集したら、社長が大喜利を始める弊社w

f:id:yamitzky:20161021203115p:plain

25歳になった / 労働についてのあれこれ

もう誕生日から2ヶ月経つが、8月末に25歳になった。
お祝いを頂いた方、本当にありがとうございましたm(_ _)m

ちょうど今年は転職した“転機”で、転職して一段落経ったし、最近思ったこととか、気持ちの変化とか書いてみようかなと思う。

アプリのサーバーサイドを作って思ったこと

この半年間、NewsDigestというアプリのサーバーサイドを作ってきた。
そこで得た結論を言うと「アプリを作る上で、フロントエンドエンジニアが一番偉い」だ。

アプリの品質・面白さをコントロールする上で、最も直接的に影響があるのは、UI/UXだと思う。
いろいろ施策を毎日考えるが、「サーバーサイド不要でできる施策」はたくさんあるが「フロントエンド不要でできる施策」はあまり多くない。
どんな施策を考えても、結局フロントエンドエンジニアが作ってくれなきゃ何もならないのだ。。。

そもそも、この2016年において、フロントエンドエンジニアがウェブのバックエンドを“書かずに作る”方法はたくさんある。
ParseとかFirebaseとかのmBaaSを使えば良い。
実際NewsDigestでもParseを使っているので、僕のようなサーバーサイドエンジニアがやっているのは「配信アルゴリズムエンジニア」だ。
フロントエンドエンジニアが「Webの仕組みがわからないのでできない」という壁はあまり高くない。

だからそのうちフロントエンドをまたやりたいな、というのは正直思ったりする。何年後でも。
でもKotlinのプロジェクトが良いな。笑

5年後価値のあるエンジニア

「5年後、価値のあるエンジニアは誰か」という問題は難しい。

5年前を思い出してみると、AWSは今ほど使われてないし(公開されたの2006年だって!)、Dockerも存在しない。Sparkもないらしい。
GoやNodeは一応あるが、Scalaや関数型も今ほど流行ってないし、ECMAScriptの状況も全然違っただろう。
サーバーレスなんて言葉もなく、RX系もそんなに流行ってないだろうな。知らんけど。

5年後、「Webアプリケーションを作る」という言葉が示すものは、少なからず変わっているだろう。

自分の場合は、答えを出すのをやめたけれども、考え続けてはいる。

ベンチャー機械学習分野を活用すること

機械学習が“最近”コモディティ化して、個人がやりやすくなった、というのはやっぱり誤っていると思う。
今も5年前も、適切な問題設定をすれば、sklearnやらを使って問題を解くことは可能だったはずだ。
ちなみにTheanoも5年前からある。

「適切な問題設定があれば、一定の問題を、一定の品質で、既存のモデルで解く」
そのラインを超えた先、というのは何なんだろう? と、ずーっと考えていた。

一つは、大規模な学習、具体的に言い換えるとディープラーニング系のトピックを追うことだろう。
ただし「大企業が」「大規模なデータで」「大規模なインフラで」というのが大抵の枕詞だ。
(※少年ジャンプと同じように、3つのキーワードが揃わなくても良い)
他に、最新の手法を作っていく、というのもあるだろう。

そしてもう一つ、「ビジネス要件を理解し、新しい問題設定を作る」 というのがあると思う。
例えば出会い系サービスで「人工知能」を活用するとしたら、学術分野では決して出てこないような案や仮説・手法が出てくるだろう。
そのような洞察は、機械学習分野への知見だけでなく、ビジネスへの深い理解から来る。
ただし、ビジネス理解を突き詰めても、必ずしも学問的・技術的に新しいものは生まれるわけではない。

自分が、自社が、前者と後者どちらで行くのか、というのは考えた方が良いと思う。

労働において重視するものの心境変化

自分はもともとエンジニアとして「機械学習」とか「データ」のドメインに張りたかったというところで会社を選んできた。
ベンチャーを主戦場にしてね。

今、転職して、それなりに好き勝手やってるんだけど(分類サーバーとかログ基盤とか作ってる)、どっぷり浸かるほどやれてるわけではない。
転職直前の方が時間比重的には多いと思う。
かと言ってそこに大きく不満があるかというと、そうでもない。

そのことに気づいて、改めて、なぜ機械学習/データ分野をやるべきだと思ったのか、というのを考え直して見ると、 「難しい問題を自分の武器で解き、市場で希少価値のあるエンジニアになりたい」ということだったんじゃないかと思う。
(もちろん、単純に面白いからっていうのが一番大きいけどね。減ったけど、今でも公私で論文読むし)

「難しい問題を自分の武器で解く」を高めるために、もっと高度な手法、もっと大規模な手法、という風に手を伸ばしていくことも必要だと思うんだけど、 自分個人は、ビジネス理解を深めたり、あの手この手を考えて、それが必ずしも「高度」じゃなくても解決していくことに、面白みを感じてしまった。
それはもはや「エンジニアとして『機械学習』とか『データ』のドメインに張る」ということによる高みではない。

勉強からのドロップアウトとも怠惰とも言い換えられて、それで良いのかという悶々としたものはある。
週末・業務後に勉強したりいろいろ試したりするけど、あんまり身が入らない感じもあって焦っている。

まあ、かなり悩んでいたり焦っているけど、別の楽しみを見つけたのが今の状態、というところ。
一言で言えばたるんでるけど、楽しいので、なんとも言えない。
「技術的・学術的高み」と「ビジネス理解から来る課題解決」をうまく結び直すのが、今後の自分の宿題なんだろう。

Webエンジニアの職種を変えるとしたら

僕は結構映画が好きだったり、テクノロジー系イベント(VRとかDMM.planetsみたいな)行ったりするんだけど、 テクノロジーで人を感動させるのってすごいなーと思う。
Computer Vision系の研究とか見ると、本当にすごい(ディズニーとか)
Perfumeのライブ行ったことないんだけどすごそうだし。

だからもし職種を変えるとしたら、テクノロジーで人を感動させる仕事をやりたいなと本気で思ったりする。
もしくは同人でやるとか。
数年後にはVRコンテンツをインディーズが作れるようになって、いろいろ変わっているだろう。 (Unityの無料化とかUnreal Engineとか、ここ数年だしね)

大学院に行きたいなと思ったことがある話

自分は学部卒なんだけど、特定の学問を“修了”できなかったこととか、ちゃんと勉強しなかったこととか、学部時代の研究への心残りとかがいろいろある。

会社員になってみて気づいたのは、自分は学生時代に「プロセス」を全く知らなかった。課題解決的な思考方法というのが全くなかった。
あと9時に起きるという習慣も、勉強する習慣もなかった。とにかく怠惰だったな。苦笑

逆に、会社員経験を経てから学生に戻れば、学問とは別の“武器”を持った上で戦えるのかな、とは思う。

決して今ではないんだけど、ある程度人生に余裕ができたら進学したいな、というのは一つの選択肢として思っている。

次の転機

次の転機は、漠然と「5年後」だろうなと思っている。

会社は今のx倍になっているだろうし、事業は変わっているかもしれないし、自分の立ち位置は随分と変わっているだろう。
そのとき残るのか、転職するのか、起業するのか、入学するのか。
何か1つまたは2つを、明確に“選択”することになるだろうなと思うけど、選択はきっとポジティブな理由だろう。

最近見たもの

最近のオススメで言うと、

の3点、ご査収ください。

ライトノベル原作しばらく見てなかったけど、面白かったな。

今期は亜人が楽しみなのと、テラハ新シリーズが楽しみです。

最近買ったもの

最近買ってよかったなと思うのは、

  • ケルヒャーの高圧洗浄機・・・水回りの掃除が楽になります
  • ルンバ

あたりかなぁ。今は乾燥機付き洗濯機を買いたいけど、家の蛇口が低くてダメ。

終わりに

随分と長く、面白くもないポエムを書いてしまった。

また半年後か1年後ぐらいに、いろいろ心境変化があるだろうし、言語化できたらまた書こうかな。

おわり。

俺がTerraformファイルをいじるときに使ってるツールを雑に紹介する

Terraformは、インフラ管理をコードで管理するためのツールです。具体的にJXでは、AWSのインフラを管理するのに使っています。「インフラを管理する」というのは、今までだったらAWSのWeb管理画面(コンソール)やらAWS CLIでやっていたような作業を、ソースコード(以下、Terraform設定ファイル)で管理できるようになります。

さて、そんなTerraform設定ファイルの編集ですが、正直に言ってかなり時間がかかります。具体的には、AWSとかのリソース名とか覚えていられないし、変数とかも覚えていられないし、リソースに必須なプロパティとか覚えていられないわけです。それをいちいち調べるのがとても時間かかります。

自分なりにいろいろ試してみて、生産性があがったツールを2つ紹介します。

1. IntelliJ(無料)

ひとつ目は、IDEIntelliJ IDEAです。ScalaとかJavaとかを扱うあれです。PyCharmでも構いません。コミュニティエディション(無料)でも使えます。

IDEで編集すると聞くと大仰に感じるかもしれませんが、HCL Language Supportのプラグインが死ぬほど使いやすいです。

とにかく補完が効きます。事前定義済みのAWSのリソース名はもちろんのこと、自分で定義したリソース名や変数名なども補完が効きます。さらに、必須のプロパティが設定されてないと、黄色くなって教えてくれます(Option+Enterで、必須プロパティを全部入力してくれます)。

例)必須プロパティの補完

f:id:yamitzky:20160801164236p:plain

Option + Enterを押すと、、、

f:id:yamitzky:20160801164307p:plain

例)リソース名の補完

f:id:yamitzky:20160801164443p:plain

2. Dash (有料; $24.99)

ふたつ目は、ドキュメント検索ツールのDashです。有料ですが、使い勝手の悪さをガマンすれば無料で使えるはずです。

Dashは、各種言語などの(公式)ドキュメントを検索することができます。なので、リソースのプロパティの細かい仕様を知らなくても、すぐに調べられるわけですね。

しかも、ローカルにキャッシュしてくれるので、とても速いです。わからなくて、ググッて、ネットワークの接続待って、公式ページに辿り着いて、ネットワークの接続待って、、、ってしなくて良いので、かなり効率が上がります。

例)検索

f:id:yamitzky:20160801164910p:plain

公式ドキュメントが表示されます

f:id:yamitzky:20160801164930p:plain

まとめ

以上、2ツールを紹介しました。他に便利なものがあったら教えて下さい。

Apexを使ってAWS Lambdaを楽に管理しよう

AWS Lambdaでサーバーレス楽しんでるみなさん。

私の所属するJX通信社では、AWS Lambdaを結構活用しています。Lambdaのデプロイ管理のために、個人的にはApexというツールを使っているので、今回はその紹介をしたいと思います。

apex.run

TL; DR

Lambda使うならApex使おう

Lambdaやってて発生する辛み

Lambdaを継続して使ってくると、だいたいこんな辛みがでてきます。

  • Lambda関数が増えてくるので管理が大変
  • Lambda関数を更新するために必要なステップが多すぎる

Lambda関数を更新するためには、だいたい次の作業が発生してきます。

  • pip install とか npm install とかして、依存ライブラリをインストール
  • ソースコードと依存ライブラリを一つのzipに梱包
  • S3にアップロード
  • Lambda関数を更新
  • 必要であれば、エイリアスを更新
  • 実行して動作を確認
  • CloudWatch Logsを見て動作を確認

というところで、これを自動化したくなってくるわけですが、それを自動化してくれるOSSが既に存在しています。本稿で紹介するApexもそのようなツールの一つです。ここでは「デプロイ管理ツール」と呼称します。

デプロイ管理ツールの分類

デプロイ管理ツールはいくつかあります。awesome-servelessというリポジトリが参考になりますが、デプロイ管理ツールを分類すると、

  • 特定の言語(ランタイム)に依存するか、全ての言語に対応するか
  • アップロードだけか、それ以外の機能も備わっているか
  • インフラ管理をする機能が備わっているか
  • API Gatewayの管理をする機能が備わっているか
  • 依存ライブラリの管理をする機能が備わっているか
  • 関数を呼び出したり、ログを確認したり、ロールバックの機能があるか

Apexはその中でも、「全ての言語に対応(というかGoにすら対応!)」「アップロード以外に、ログ確認や呼び出し機能も含む」「Terraformと連携してインフラ管理ができる」「API Gatewayの管理や依存ライブラリ管理の機能は備わってない」という分類のツールです。

参考にするべきページ

何か困ったら、Githubで検索すると良いです。

使い方の紹介

Apexにはinitスクリプトが入っているので、簡単に始めることができます。使い方を知るために、まずは空のプロジェクトから始めると良いです。

# インストール
curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh
# 初期化
apex init

apex init すると、次のようなディレクトリができます。

.
├── functions
│   └── hello
│       └── index.js
├── infrastructure
│   ├── dev
│   │   └── main.tf
│   └── modules
│       └── iam
│           ├── iam.tf
│           └── outputs.tf
└── project.json

このうち、project.jsonが設定ファイルで、infrastructureはterraformで扱うコードfunctionsがLambda関数です。functionsの下のディレクトリと、デプロイされるLambda関数が、一対一に対応します(つまり、 {プロジェクト名}_hello というLambda関数がデプロイされる)。

デフォルトのhello関数は index.js が入っているので、当然nodeランタイムが選択されます。main.py だったらPythonが選択されます。ランタイムの推論ルールはソースコードで確認できますが、function.json を変更することで、ランタイムや、ハンドラー関数を明示的に指定することもできます(このあたりは、Githubで検索するとわかりやすいかも)。

Terraformは、terraform hogehoge の代わりに、 apex infra hogehoge のように扱います。そうすることで、関数名のARNとかがうまい感じにTerraformに引き渡されます。

デプロイ

apex deploy

こうすると、デフォルトで current というエイリアスが貼られて、全ての関数がデプロイされます(コードが変更されてなければ、もちろんデプロイされない)。--alias フラグとかをつけると、エイリアスを明示的に変えることも出来ます。

呼び出し

apex invoke hello < event.json

渡すJSONを指定して、上記のように呼び出せます。

ログの確認

呼び出した際、当然ログを確認したいですね、ということで、ログの確認は下記のようにします。tail -f のようにしたい場合は、-f フラグをつけます

apex logs hello
# または
apex logs -f hello

Apexの悪いところ

  • dev, prod のような環境管理が、別アカウントであることが前提になっている。つまり、Lambdaのエイリアスであったり、API Gatewayのステージで環境管理をすることがあまり想定されていない
  • Terraformを使ったことがない人には、Terraformの学習コストが高い。ただし、Terraformを使わずにGUIでポチポチインフラ管理をすることももちろんできる
  • Pythonのpipのサポートが特にない(というかnode以外のサポートが薄い? ちなみに作者はJS界隈で有名な @tj さん)

ApexのTips

Apexの悪いところをあげてみたのですが、回避策もあります。そんなTipsを紹介します。

強制的にデプロイする

デプロイする際、--alias というフラグをつけるとエイリアスcurrent以外にできると紹介しました。しかし、次のようにすると、コードが更新されていないためにデプロイされません。

# currentを更新
apex deploy
# devを更新、、、されない!
apex deploy --alias dev

こういうときは、--set という環境変数を変更するためのフラグを使って、強制的にコードが変わった状態を作ってデプロイすると良いです。

# currentを更新
apex deploy
# 環境変数を入れるために、コードが変更されるので、devが更新される!
apex deploy --alias dev --set tekitounahensuu=dev

Pythonで使う

先ほども述べたとおり、pipとかrequirements.txt のための仕組みは特にありません。

Apexでは、 functions というディレクトリ規約で、関数をデプロイします。つまり、functions というディレクトリをうまく使ってあげるといろいろできます。言い換えると、functionsディレクトリはビルド用ディレクトリ(コミットしないディレクトリ)として割りきりましょう

例えば、次のようなディレクトリ構成を考えます。

.
├── functions
│   └── hello
│       └── .gitkeep
├── infrastructure
├── project.json
└── src
    └── hello
        ├── main.py
        └── requirements.txt

src というディレクトリを作りました。例えば、apex deployする前に、次のようなステップを踏んであげれば、「requirements.txtの依存関係をインストール」「ソースコードディレクトリを綺麗にする」という2つの要望がかなえられます。

1. pip install -r requirements.txt -t functions/hello して、依存ライブラリをインストール
2. cp -r hello functions/ して、ソースコードをfunctions下にコピー
3. apex deploy すると、functions/hello の中身をデプロイしてくれる

ちなみに、Apexにはhookの仕組みがあるので、活用すると良いと思います。

Javaで使う

Javaの場合は、apex.jar というファイルがあれば、それをデプロイします。つまり、こんな感じ。

.
├── functions
│   └── hello
│       └── apex.jar
├── infrastructure
├── project.json
└── src
    └── hello
        └── 適当にJavaプロジェクトとか作ればいいじゃない

同じように、ソースコードfunctions 以外で管理しましょう。jarさえ作れば良いので、ScalaだろうとClosureだろうとGroovyだろうと(たぶん)動きます(Scalaしかやったことないけど)。

APIの管理にはTerraformを使わない

突然ですが、TerraformのAPI Gatewayの管理は貧弱です。貧弱というか、「ステージへデプロイをする」ということを想定していない作り、だと思います。

API Gatewayは幸いなことにSwaggerによる管理ができるようになっています。これをインポートするための公式ツールもあるので、これを使うと良いでしょう(awslabs/aws-apigateway-importer: Tools to work with Amazon API Gateway, Swagger, and RAML)。

ちなみにSwaggerによるインポートに対応する予定はあるみたいです。

まとめ

いろいろ書いてきましたが、Apexというツール自体、高速に動くし、便利だし、縛りも少ないし、おすすめです。

日本で一番Apexで苦しんできたかもしれないので、何か質問などあればTwitterとかでメンションください。

ところで、JX通信社では素敵なPythonistaや素敵なiOSエンジニア募集中です。

www.wantedly.com

通信系テストのためのサイトのススメ:example.com、httpbin.org、badssl.com

HTTP通信の機能を持ったプログラムをテストするときに、どこにアクセスするか、迷うことがある。(モックが使えるならそれがいいけど)

そんなときにおすすめな、example.comhttpbinbadssl.comを紹介してみる。

example.com

名前がそのままだが、example.com はちゃんと動くサイトである。よくサンプル文字列として(例えばメールアドレスとかで)仕込んでたのだが、最近まで本当に生きたサイトだとは知らなかった

亜種に example.org とか example.netもある。RFC 2606に定義されているそうで、第三者に悪影響が及ばないことを保障することができるとある。Wikipediaにも記事がある。

ただ、あくまで普通のウェブサイトであり、「403をテストしたい」といった特殊なテストには合わない。そんな人にhttpbinをおすすめしたい。

httpbin

httpbin は高機能なレスポンスをJSONで返してくれるサイトだ。トップページを見ると、返してくれるエンドポイントの一覧が見られる。

具体的なエンドポイントを軽く紹介する。

/ip

https://httpbin.org/ip を叩くと自分のIPアドレスが返ってくる。つまり、IPアドレスを返すためのエンドポイント。

/headers

http://httpbin.org/headers を叩くと、リクエストしたヘッダーが返ってくる。ヘッダーのテストなどに。

/status/:statusCode

このエンドポイントは、特定のステータスコードを常に返すことができる。例えば、https://httpbin.org/status/418 は 418のステータスコードになる。

/delay/:n

これは、遅延したレスポンスを返す。例えばhttp://httpbin.org/delay/3は3秒待ってレスポンスを返す。

その他

他にも、認証のテストであったり、Cookieのテスト、リダイレクトのテスト、キャッシュのテストなどなどいろいろできるので、便利。

badssl.com

最後に、SSLのテストができる badssl.comを紹介する。このサイト上では、いろんな種類の良い/ダメなSSLサブドメインがテストできる。例えばオレオレ証明書などがあるので、こういったサイトに接続できないようになってるかなど、テストすると良いと思う。

他にもおすすめなサイトがあったら教えて下さい〜!

そろそろニューラルネットやディープラーニングを「人間の脳を模倣してる」というのをやめませんか?

最近(?)ニューラルネット(Neural Network)やらディープラーニング(Deep Learning; 深層学習)やらが流行ってきて、人工知能やらシンギュラリティやら言われるようになって、その中でよく言われるのが「ディープラーニングは人間の脳を模倣してる」とか「特徴量を選ばずに学習できる」とか、そんなことが言われるわけです。

けど、そういったキーワードが一人歩きして、「人工知能は危険だ」論とか、人工知能に対する過剰な期待論がはびこってしまっている気がする。そこで言いたいのが「ディープラーニングは人間の脳を模倣している」と言ってしまうのをやめましょう、という話。

ニューラルネットワークが「人間の脳を模倣」してる話

まず最初に、「ニューラルネットワークが人間の脳を模倣してる」論が、あながち間違ってないよ、ということを話しておきたい。あながち間違ってないんだけど、それでもやめたほうが良いよということを言いたい。

そもそも、ニューラルネットワークは、「Artificial Neural Network=人工ニューラルネットワーク」とか言われたりする。つまり、わざわざ「人工」という言葉をつけている。逆に「人工」じゃないものが何かというと、それはBiologicalなニューラルネットワークであって、つまり生物に備わる脳の話だ。

ニューラルネットワーク系に出現する用語も、明らかに脳の用語から出現するものがある。わかりやすいものだと「ニューロン」とかもそうだし、視覚野を模しているものもあると聞く。「細胞」という言葉が出てくることもある。

実際、PRMLにはこう書いてある(上巻5章 p.226)

ニューラルネットワーク」という語は、生体システムにおける情報処理を数学的に表現しようという試みにその起源がある(McCulloch and Pitts, 1943, Widrow and Hoff, 1960; Rumelhart et al., 1986)

「脳から学ぶ」という分野もあるし、生物から学ぶこと自体、とても価値のあることだと思う。

それでもなお、「ニューラルネットワークは人間の脳を模倣している」という表現は、かなりのミスリーディングを生んでいると思う。その話をしたい。

理由1:ニューラルネットワークは関数であって、「意識」ではない

そもそも、ニューラルネットワークは確定的な関数として表現されたりする。単純な例で、三層パーセプトロンの話を持ちだそう。

三層パーセプトロンは、次のような図式で表現される。多層パーセプトロンより引用

f:id:yamitzky:20160513011244j:plain

確かに、これではまるで脳に見えてくるかもしれない。しかし数式化するとこうなる。(PRML p.228より引用し、簡略化のためバイアス項を削除)

{ \displaystyle
y=\sigma \sum_{j=1}^{M}{w_{kj}^{( 2)} h \left ( \sum_{i=1}^{D}{w_{ji}^{( 1 )}x_{i}} \right )}
}

この式は、かなり乱暴に言えば「出力=係数2×(係数1×入力)」だ。ちなみに、「係数×入力」というのは、有名な「線形回帰」だ。つまり、かなり単純には線形回帰を2段階にしたもの、ということができる。「線形回帰」をもっと単純な話に言い換えると、中学だか高校の数学の「y = ax + b」だ。これを多段階にしただけで人間の「意識」と呼ぶのはさすがにおこがましいし、この三層パーセプトロンは入力に対して掛け算をしていくだけのものだ。途中でニューロンがプッツンすることはないし、アルツハイマーになることはない。

ニューラルネットワークのキーポイントの1つは、関数として目標と近似できる能力の高さではないかと思う。「意識」というものがあって、「人格」というものがあって、「考える」という能力があるような「人間シミュレーション」とは、現状は根本的に異なる。(そのうちぶつかるかもしれないけど)

ここにあげた例はかなり単純な例であるが、画像処理に使われる畳込みニューラルネットワークなども同様に、パラメータと入力に対して確定的に計算することになる。もちろんそこに確率的な枠組みを導入することはできるが、そうでなければ必ずしも精度が出ないということではない。ましてや、ここに意識という存在を考えるのは、さすがにバカバカしい。

理由2:脳を模倣するほど精度があがるわけではないし、必ずしも脳の模倣ではない

自然言語に対するニューラルネットワークの適用で言うと、LSTMというものが使われることがある。LSTMについてはわかるLSTM ~ 最近の動向と共に - Qiitaが詳しいが、その発展の仕方が興味深い。

もともとRNNのような構造があって、そこに「勾配消失問題」と呼ばれる課題があり、それによって精度が出ない類のタスクがあった(超深い層のNNを学習するようなものだった)。そこで、入力ゲート・出力ゲート・忘却ゲート、etc...みたいなものが提案され、精度が改善されて、、、という進化をたどっている。

そこで疑問なのは、果たして人間の脳はLSTMのような構造を持つだろうか? もしくは、生物の脳はLSTMのような進化を経ただろうか?

答えについては、自分は知らない(正しいか間違っているかわからない)。ひょっとしたら繋がりがあるかもしれないが、提案されている論文には「人間の脳がそういう風にできているから」という話は書いていない。

それよりもむしろ、提案者は「モデルとして現在勾配消失問題があって、それを解決するためにはどういう構造を提案すればよいか?」と考えているだろう。脳を模倣するという話は、1つのアイディアの起点でしかなくて、既存の課題を解決する構造は何か、という話の方がむしろ大事だと思う。

まとめ

言いたいのは、ニューラルネットは人間の脳とは全く関係がないだとか、脳を模倣することに意味はないだとかではなくて、「ニューラルネットが人間の脳を模倣している」ということによって、過剰な恐怖を煽ったり、過剰な期待を煽ったり、誤った認識を導いてたり、NNのブレイクスルーの本質を見誤ったりないですか?ということ。

そろそろ、ニューラルネットやディープラーニングを「人間の脳を模倣してる」というのをやめませんか?