AdventCalendar2018

Vuexについて説明したい

※この記事は、KCSアドベントカレンダー12月23日の記事です。

はじめに

はじめまして、一年のsupercell(twitter: @undermountainafu)です。この記事では自分が学習しているvuexについて説明していきます。

vue.jsについて

vuexの説明に入る前に、まずはvue.jsについて簡潔に説明しようと思います。vue.jsとは、フロントエンドで用いられるJavaScriptのフレームワークです。他のフレームワークとしては、ReactやAngularがあります。vue.jsの面白いなと思った特徴は、コンポーネント指向です。この指向は、アプリケーションをコンポーネント機能ごとに分割することで、コードの再利用、保守を容易にすることができます。他にも色々な機能がありますが、詳しくはドキュメント見てください。
vuexドキュメント

vuexとは

お待たせしました(?)、vuexについて説明していきます。これは、vue.jsを用いたアプリケーション開発の際に用いられる開発フローです。要するに、データの流れを一方向に決めようってことです。vuexでは、stateをグローバル変数のように設定します。そのため、どのコンポーネントからでもstateの値を参照することができます。stateの状態を変更したい場合は、action->mutation->stateという流れで行います。下図は一連の流れの参考図です。

vuex
図. vuexの流れ

なぜ使う?

アプリケーションでは、view、action、stateで一方向の流れになっています。しかし、共通の値を共有するコンポーネントがある場合や、一つの値を複数のviewに表示させたい場合などでは、コードが複雑になってしまいますし、状態の管理が煩雑になってしまいます。具体的には、vuexを使わない場合propsとして状態を渡しますが、その状態は親から子にしか渡すことができません。
そこで、状態の管理を楽にするためにvuexを使うのです。
vuexがどんなもので、なぜ使うかを理解した後は、各機能について簡潔に説明していきます。

state

stateは、ストアで管理される状態であり、mutation以外では変更できません。

action

actionでは、mutationの登録(commit)や、データの加工などの非同期処理を行います。actionはdispatchにより呼び出されます。また、外部APIとの通信もここで行います。蛇足になりますが、APIとの通信は、axiosを用いることが公式により推奨されています。

mutation

mutationでは、stateを変更する処理や、同期的な処理を行います。commitメソッドによって呼び出すことができます。唯一stateを変更することができる機能となっています。

おわりに

余談ですが、この記事のためにvuexのサンプルコードを書いていたのですが、そのコードが動かなかったため、のせれませんでした(雑魚)。コードを直してくれる方募集しています->Missionapp
では、おつかれ三下~!

順列における二分探索木

二分探索木

とは、お金のなる木と同じようなものです(大いなるウソ)。

とまぁ、誰にもわからないウソをついたのですが。この記事では順列における二分探索木の同型問題について話そうと思います。また、文章だけで説明できるかチャレンジしてみようと思います(絶対ムリ)。二分探索木を知っている人は絵がある所から読んでください。

さて、二分探索木とは、データ構造というものらしいです。現実に植わっている訳ではありません。これはですね、二分木と呼ばれる各ノードが最大で2つの子を持つ木、かつ、すべてのノードが左の子<=親<右の子というルールを持つ木構造のことを指します。何言っているかわかりませんね。

想像してください、絵を一緒に書くと良いでしょう。あなたは数字の神様です。しかし、神様の癖に9,7,10,3,12,8の数字しか持っていません。悲しくなって、これを二分探索木という形で海の上にばら蒔きたくなります。ちなみにあなたは神の視点で海を上から見ています。

数字を海にばら蒔くと沈むので島を作りたくなります。一つ目に作った島を二分木用語ではルート(根)といいます。そして、その島に9を置きたくなり、置きます。

次に、作った島の斜め左右に二本の橋を建てたくなります。そして、あなたは7という数字を置きたくなります。しかし、二分探索木という形で置きたいので、必然的に左の橋の先に島を作って、置きます。なぜなら、7<9であり、左の子<=親<右の子というルールがあるからです。一つ目以外の島をノードといいます。また、ややこしいことに7の島ができたお陰で、9の島は7の島の親であり、7の島は9の島の子供という関係が発生します。親、子供というのも二分木用語です。この7の島にも二本の橋を架けたくなります。

次に10を置きたくなります。9<10なのでルールより、9の島の右橋先に島を作り10を置きます。二本の橋を作っておきます。今度は3を置きたくなります。3は3<9なので9の島から左橋先の島に置こうとしますが、7がいるので置けません。困ったときはルールを思い出します。左の子<=親<右の子です。3<7なので7の島の左橋先に島を作り、置きます。3と7には親子関係が発生します。

次に12を置きたくなります。12は9<12,10<12なので10の島の右橋先の島に置きます。これを繰り返して残り8を置くと

二分探索木
二分探索木

こんなのが出来上がるはずです。たぶん…。キーワードは、二分探索木はデータ構造ということです。あとはググってどうぞ…。

本題

本題はですね、二分探索木の同型問題なのですが。状況設定はですね、1からn番目までの数字列の順列を作りたくなります。このできた数字列1つ1つを二分探索木に収めたくなります。このとき、同じ木の形ができることがあるんですね。それを判断したいのですよ。

例えば、1から3の順列を考えます。123, 132, 213, 231, 312, 321の6通りの数字列ができるわけです。この各数字列を先頭から順に木に収めると、下の絵みたいに同じ木の形になるものがあるのですよ。入力の順番は異なっても。

同じ木の形の例
同じ木の形の例

で、絵を描けば一発でわかるのですが二分探索木を作るプログラム上ではわからんのですよ。ここで記事を書いてる人は考えました。順列においては!順列お・い・ては!ここ重要なので二回言いました。同じ木の形=各ノードの場所に同じ数字がある、この考えを用いると同じ木かどうか判断できるのです。

方針は、二分探索木を回るときに同じ道筋を辿るのですよ。数字は同じ場所にあるのだから、同じ木であれば同じ数字が回った先にはあるわけですね。で、二分探索木の巡回方法には前順、中順、後順があります。中順にまわり各ノードの数字を出力すると、数字の場合は昇順にソートされたものが出てきます。これではすべて123…となって意味がないので、前順または後順でまわり各ノードのを出力すると同じ木は同じ数字列になります。

というのはすぐに思いつきました。では、順列からできた木の異なる形の木だけ取り出して線形リストにしようと思いたちます…C言語で実装したのですが苦労しました。下記の絵のイメージをしていただければいいと思います。idとかは気にしないでください。よかったら実装してみてください。1からnまでの数字列の順列を二分探索木にして、異なる木だけを線形リストにするという実装を。プログラミングの練習になると思います。なんたって、かだi…ゲフンゲフンだもの。二分探索木の挿入や巡回、探索などは再帰呼出しを使うと短いコードで書けるのですが実装するにあたってわざわざ再帰呼出しなしで挿入したり巡回しましたね…

各木を線形リストにするというイメージ
各木を線形リストにするというイメージ

以上、お付き合いいただきありがとうございました。なにか間違っていたらご指摘ください。

学校の先生にクリスマスの予定がないと言ったら爆笑されました。みなさんもうすぐクリスマスですよ!

 

ZFSはいいぞ

この記事はKCS Advent Calender 17日目の記事です。

はじめに

初めまして。J科4年の @kumassy_ です。けんきうしつのサーバーの面倒を見ています。

概要

ハードディスクにはたくさんのファイルが保存されているかと思いますが、ハードディスク上にファイルを格納するための仕組みをファイルシステムといいます。世の中にはext4やxfsなどいろいろなファイルシステムがありますが、ZFSというファイルシステムがとてもよさそうだったので紹介します。

ZFSのいいところ

  • ファイルシステムにRAID機能が組み込まれている
  • 使うコマンドが2つで管理が簡単
  • スナップショットがとれる
  • パーティションの容量が動的に拡張されるため、事前にパーティションのサイズを指定しなくてよい

実際に使ってみた

CentOS7.5にハードディスクを4枚さしてRAID-Z1(RAID-5相当)を組んでみました。1枚は/と/boot用で、残りの3枚をZFSで管理します。


# ストレージプールの作成
# LVMでいうVolume Groupのようなもの
$ sudo zpool create tank raidz1 sdb sdc sdd
$ zpool list
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 16.2T 1.55M 16.2T - 0% 0% 1.00x ONLINE -

# データセット(パーティションのようなもの)の作成
# 作成すると自動的にマウントされる
$ sudo zfs create tank/storage
$ sudo zfs create tank/home
$ zfs list
NAME USED AVAIL REFER MOUNTPOINT
tank 730K 10.5T 139K /tank
tank/home 128K 10.5T 128K /tank/home
tank/storage 128K 10.5T 128K /tank/storage

# マウントポイントの変更
$ sudo zfs set mountpoint=/storage tank/storage
$ sudo zfs set mountpoint=/home tank/home

とても簡単!!データセットを作ると自動的にマウントされるので、/etc/fstabの設定すらいらないです!!!!!!

さいごに

ZFSはいいぞ。

他にもスナップショットの作成やsend/receiveによるバックアップなど試したい機能がいろいろありますが、このあたりの資料を参考にしてみてください。

  • https://chibiegg.gitbooks.io/how-to-zfs/content/index.html
  • https://qiita.com/pitekusu/items/d5e9b0e4f5c06f8f76e3
  • https://pthree.org/2012/12/17/zfs-administration-part-x-creating-filesystems/

気合いで読むQRコード入門

この記事はKCS Advent Calender 16日目の記事です。

軽い自己紹介
初めまして。J科B3の@kam1tsur3です。セキュリティキャンプ2018にいました。kcsにはB2の時に入りましたが、LTを一度聴講しに行ったことがあるくらいの幽霊部員です。普段はCTFというセキュリティやコンピュータの周辺知識等を競う競技をやったりしています。別に普段からQRコードを読んでいるわけではありませんよ。

概要

記事は題名どおりQRコードをカメラを使わずにゴリゴリ読んでいこうという趣旨のものです。他の部員の記事に比べ実用的ではないですが、どの分野の方でも読める内容になっているので、箸休め程度に思っていただけると幸いです。

URLを貼りさえすれば良いと思ってたので、書くことが決まってからすぐ自分のブログで下書きを書いてしまいました。以下に記事のリンクを貼ります。ちゃんとこの場所用に書き直そうと思ったのですが、最近なかなか元気がないので許してください。直前に目を通すと、記事を書いた当時は元気だったのですごい文面も張り切ってるのが分かるので、とても切ない気分です。みんな頑張ろうぜ

ほんへ

https://kam1tsur3.hatenablog.com/entry/2018/12/16/131108



全くの初心者からの機械学習ロードマップ

この記事はKCSアドベントカレンダー第15日目の記事です!

おはござー!おはござー!おはござー🌻!

ぼく(リンク先:Twitter)自身の記事としてはおよそ1.5年ぶりとなります.12月も中程に差し掛かり学部3年ということもあって研究室選定で右往左往しております.

何かしら技術系の記事を書こうと思っておりましたが,そのネタはコミケ95での部誌に回すとしてここでは自分の1年間の自分語りにしようかと思います.オタク,自分語りしがち.

KCSはいくつかの班に分かれて活動しているのですが,ぼくはAI班とBlender班で主な活動を続けておりました.AI班自体の発足は結構前からあるようですが,ぼく自体がAI班に入ったのは今年度に入ってからですので,おおよそ9ヶ月程度の機械学習を学び始めてから経つことになります.

9ヶ月前までは二進も三進もわからなかった状態から,どのように機械学習の勉強を続けていったのか,その過程を共有することで,同様の立場にいるような人(いるのか?)の助けになれば幸いです.

図です

機械学習関連以外のことは灰色で示しました.

勿体ぶる必要もないので時系列順にやったこととその感想とかを紹介します.

3-4月 Python機械学習プログラミング

81kHmZ62+nL

Amazon

まず第一に,技術書を買った際に自分の手ですべて実装することを目標にしました.何かしらの言語を学ぶ際に,何に応用できるのか,これを覚えて何になるかといった視野を持つことにしています.C++を学ぶ際,クラスやオブジェクト指向,C++11のshared_ptrといったとっつきにくい概念から,どのように実活用されるかなどが全く把握できず仕舞でせっかくのプログラミングに対してやる気が全く出ずに,そのうち習慣が自然消滅してしまうといったことが多々あります.ぼくの場合には「機械学習」を学び「Webアプリケーション」を作りたい.スキルを活かせる「バイト」をしたい等,の目標を定めました.

この本では,機械学習で使われるSVMだとかK-meansだとかのアルゴリズムをある程度網羅的に,なおかつコード量も豊富に記載されており,Pythonと統計学,機械学習を万遍無く学べる良い本でした.無から有を生み出せそうな良書です.

また,TwitterのFF内間で日報/日記を付けるムーブメントが流行っているように見えたことから便乗して,ぼく自身もこの時期から日記/ブログをつけ始めることにしました.

進捗だめです

他人に見せるという体で学んだことをまとめ上げるという行為は,

  • 知識を言語化することで学習の反芻を行え,知識の定着が向上する
  • 他人に見せるための文章を書くことで,自己完結しない知識の表現方法を行える
  • 他人からも「○○ちゃんのブログは為になるなぁ!」とかレスポンスが貰えて習慣化が期待できる

といった役に立つことが盛り沢山だとおもいます.なのでこれを見ている皆さんも日記を付けてください.付けなさい!付けろ!!!

3-5月 Coursera

皆さんはCourseraというサイトを御存知でしょうか.

 

…では,AIdemyという動画教材による学習サービスサイトは聞いたことはありますでしょうか.

 

おそらくAidemyなら聞いたことがあるという方が多いのではないのでしょうか.

国内では個人的にはあまり聞かないの(僕主観ではの話を国家レベルに拡大するな)ですが,動画で学習ができて,なおかつ,時たま出されるプログラミング課題に回答して,全講座を終了させることで,修了証を貰えてLinkedIn等のサイトそれを貼ることで俺ツエーできる様になるというサイトです.動画講座自体は無料で閲覧することが可能であり,実際に演習を行うという場合でも月間6000円弱でコース内の全教材が利用可能となります.

同期で同じクラスのモヤシ炒め界の申し子でUCDavisのK氏がやってたことに便乗してAdvanced Machine Learning Specialization という全40週弱ある講座を申し込みました.しかし,大学が始まった事による忙しさの変化により,思うように進められなくなってしまったため途中で断念しています.しかしながら,機械学習の実力(と,あわよくば英語力)を身につけるには最適な教材です.一回の動画が10分前後で終わるため,空いた時間を有効的に活用ができ,講座数も豊富です.機械学習以外でも制御工学WebデザインVR開発まで非常に多岐にわたります.なかには大学のDegreeなどをも得られるような本格的な講義まであります.

Courseraに関する記事は,上のK氏もロ技研のアドベントカレンダーにて学習方法等を共有しています.細かい学習方法など,具体的な環境の揃え方などに興味がある方はこの記事を参考にしてみてください.

4-7,9-11月 Ian Goodfellowの深層学習邦訳版

61zJusXfyjL._SX258_BO1,204,203,200_

2018年度は,KCSの方針で週に2度ほど集まって,片方はゼロから作るを頭から読んでいく会(初級者向け)と,Ian Goodfellowの深層学習や各種論文を読んでいく会(上級者向け)を開催していました.

前者の方はおおよそ無難な結果で終わることができたのですが,後者の方は読み込み始めてからこの本が上級者向けなどではなく人智を超越した神とそれに匹敵する最強GAN制作おにいさんしか理解できないような代物であることに気付きました.

 

平平凡凡である僕は開いては悶え開いては悶えを繰り返し,全く先に進めずじまいでした.(げに今もそうなのですが.)しかし,間違いなく知識の得られる量としては日本語文献では抜群に豊富のような気がするため,これを理解さえできればおおよその深層学習の基礎については分かったと言い張れるだろうという自信がつきます(ということにしておきます).

4-7月 ゼロから作るDeep Learning ①

picture_large978-4-87311-758-4

内容に関する評価は10万部のセラーを記録したため探せばいくらでも出てくるため文が拙い僕が書くのもアレなので省略します.

KCSでは毎年(といっても先輩いわく2015年ごろからの習慣で)新入生向けの講習会を4-6月にかけて開催しています.その講習会の教材として活用しました.

実装レベルから,Adam等のオプティマイザの説明,CNNの構造まで詳しく説明されており,説明も概ね分かりやすかったです.次年度以降のAI班の活動方針は僕の手中でもないので知る由もないのですが,もし「教科書を作る」となった場合には非常に参考になるのではないか.というような良書です.

8-9月 パターン認識と機械学習

    その日、人類は思い出した。
    ベイズに凌辱されていた恐怖を。
    頻度論の中に囚われていた屈辱を。

    Seid ihr Frequenztheorie? Nein, wir sind der Bayesian!

ベイズに凌辱されました.

日記に日記とは思えない分量を書いたりしたので読んでください.

変分ベイズ(1) 変分ベイズ(2) 多項式回帰(1) 多項式回帰(2)

通年 論文輪読

KCSでは,学習の一環として,有志が集まって自分が読んできた論文をプレゼンにまとめて,知見を共有する回を行っています.

論文を読むことで,最新の知識を入手でき,多くこなしていくことで,論文の書き方や構成といったものがだいたい把握できて,将来の修論だとかを書く際に非常に参考になります.最新鋭の論文でも,Github等に本人の実装や他人による追実装等が挙げられており,写経するといっただけでも応用事例を実際にプログラムでき,最新鋭のアルゴリズムを手元のマシンで再現できるというのは,非常にモチベーションの向上につながるかと思います.

昨今,arXiv等には日に夥しい数の論文が投稿されています.その中から,読みたい論文を発見することは非常に困難だと思います.そこで,Twitter等を利用して他人の腕を借りて追いつくなど,周りの同士と共有して切磋琢磨できる環境を構築することは非常に重要となります.

これから

三田祭にて軽いWebアプリケーションを作った経験から,Web関連のことを学んでいこうかと思います.単一分野だけに留まらずに関連分野に目を向けて学習していきたいと思います.

また,KCS内でも本の輪読会を継続する声が上がっています.非常に嬉しいです.

リアルでも環境構築(特にデュアルディスプレイ)が重要なんだなと感じる一年であったとさ.完.

超解像の基礎


情報工学科3年、AI班班長の渡邉です。研究室の決定の際にメンタルがグワングワンしていましたが今は元気です。

今回は下級生の機械学習の実践として理解しやすく、結果もわかりやすい超解像の分野に関して、その初歩の部分の論文を簡単に解説していこうと思います。

超解像とは?

すごい簡単に言えば画質を上げるやつです。waifu2xなどは有名ですが、最近ではA.I.Gigapixelなどの商品も出てきているので、技術の進歩を感じますね。

最初の論文

機械学習が超解像の分野に用いられたのは2014年のImage Super-Resolution Using Deep Convolutional Networks.が最初だといわれています(確認してないので違ったら教えてください)
この論文内で採用されているモデルは3層と非常に浅く、損失関数は最小二乗誤差となっています。これを図や数式で示すと以下のようになります。尚、モデル図や損失関数の式は上の本論文から引用しています。
srcnn

$$
L(\Theta) = \frac{1}{n}\sum_{i=1}^{n}{|F(\boldsymbol{Y_i:\Theta)}-\boldsymbol{X_i}|}
$$
$$
\Theta = {W_i,W_2,W_3,B_1,B_2,B_3}
$$
このような今からだとチュートリアルにも思えるような簡単なモデルですが、PSNR(ピーク信号雑音比)という指標において既存手法を上回る性能を発揮しています。当時の既存手法と結果を比較したものが論文中に示されているのでこれも提示します。
SRCNN-result
このままだと何も違いが判りませんが、拡大するとわかりやすくなると思います。

そしてこの論文以降、機械学習を超解像に用いるのがブームになっていきました。

SRGAN

機械学習により超解像の分野にはある種ブレイクスルーが訪れたと考えられていましたが、最小二乗法を用いると、CNNで圧縮された値を最小化しようとするため、PSNRベースで見れば確かに雑音が小さいものが出力されますが、人間の視覚的にはあまりそれらしくないという状況が発生していました。これを解決する手法として用いられたのがGANです。要は、GANでは(うまくいけば)それらしいものを生成することができるので、これを使って超解像を行うことで、人間の目から見てそれっぽいものを作れるのではないかと考えられるようになり、実際にうまくいったものととして紹介されたのがPhoto-Realistic Single Image Super-Resolution Using a Generative Adversarial Network(2016)、通称SRGANです。この論文内では、新たな主な取り組みとしては、Pixelshuffler、Content loss、Adversarial lossの採用等が挙げられますが。次はこれらの解説を簡単に行おうと思います。

Pixelshuffler

通常のdeconvolutionでは、生成された画像が格子状になっている箇所があるものが比較的よくみられました。それは、画素ごとに参照回数に差があるためであり、実際にhttps://distill.pub/2016/deconv-checkerboard/にある動画を見てもらうと直感的にわかると思います。


そしてこれを解決するために用いられたのがPixelshufflerであり、Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Networkに初めて登場しています。これが、実際にはどのような操作を行っているのかというと、各チャネルの画素をその場に展開するという手法をとっています。言葉だけではわかりにくいので、元論文から画像を引用します。
pixelshuffler
画像が小さくなることを忘れていたので言葉でも頑張ってなるべくわかりやすくすることにします。convolution等を行った後のサイズが$$w\times h\times c^2$$であったときに、Pixelshufflerでは、これを$$wc\times hc\times 1$$として出力することで、deconvolutionに相当する操作を行っています。

Content loss

これは、style-transfer界隈から用いられたもので、各画素の値を比較するのではなく、学習済みのVGGに画像を流し、中間層での特徴量を比較することによって、鮮明な画像を出力することができるようにしたものです。数式としてはi番目のMaxPooling層の前のJ番目の畳み込み層(アクティベーション後)の特徴量などを逐次計算しています。(数式が入力できなかったのでこれで許してください、Hackmdで入力できたのになぜ)

Adversarial loss

GANの損失関数です。数式が入力できなくなった(添え字が複数段階つく数式などが表示できない)のでこれもほとんど通常のGANの損失関数と変化がないのでこれだけにしておきます。

SRGANのモデル

いろいろ書きましたが、結局SRGANのモデルは以下のようになっています。
SRGAN-models
また、損失関数に関しては、generatorはContent loss と Adversarial loss を1:0.001の割合で足し合わせて使用しているそうです。
では、SRGANがどの程度の性能を出すことができたのかを比較してみましょう。

SRGANの性能

元論文では、以下のような差が出たことが報告されています。
srganresultimage

確かに、SRGANの性能が他のSRCNN等と比較してよくなっていることがわかります。また、SRGANは特に人間が主観的に判断した際の美しさ(MOS)の値がよいことが知られており、それを示している結果は以下の画像の通りです。
srganresurltable2
尚、これらの画像において、SRGANのAdversarial lossを考慮しないものはSRResNetと呼ばれています。

最近の研究

これらの超解像の技術の進歩の結果、PSNRなどの数式で表すことができるような定量的な指標と、人間の主観で判断するMOSなどの定量的な指標の間にはトレードオフの関係があることがわかっており、どちらかに特化した手法が最近は開発される流れになってきています。具体的な例としては、SRGANの中のAdversarial lossのgenaratorの部分のlossに関しても考慮し、その中間層の特徴を生かすような構造を用いたSRFeatや、PSNRの向上に特化したRCANや、SRGANに対して、さらに他の手法で用いられた手法を取り込むことでさらにMOSの評価を上げたESRGANなどが開発されています。

所感

記事の冒頭にも書きましたが、このような分野の大きな利点は成果を実際に見て確認することができることだと思います。また、自分で記事を書いてみて、改めて基礎分野の重要性を感じました。
 

鯖缶 #とは

*これはKCS AdventCalender2018 13日目の記事です*

はじめに

はいどうもこんにちは.
やり手の名ばかりサーバ管理担当(鯖缶),いくぴーです.
最近サーバー構築やってるんですけど,ありえんハマっているのでネタにします.
文章力皆無なのはゆるしてヒヤシンス…

やっていること

サーバをたくさんおっ立てなくてはならないのですが

  • 個別で立てるのがダルい
  • 個別で管理するのがダルい
  • 開発環境と本番環境が違うとダルい

と3つのダルみが揃った結果,「docker compose使えばええやん」という安易な発想に至りました.
そういうことである.

今回はローカルでの開発用仮想サーバを立てることをメインにして書いていきますね.

実際にどうやってる?

必要なもの

サーバーに必要なのはDockerとDocker Composeだけです.
ローカルで本番と同じ構成のサーバを立てる際に必要なのは

  • VirtualBox
  • Vagrant
  • Docker (Docker Compose)

こんなとこですね.
VirtualBoxとVagrantはローカルに仮想環境を簡単に立てるために使います.
Windows10からDockerを使えるようになったのですが,Home版では使えないので…
ホストOSの違いを気にしなくていいようにした結果こうなりました.やはりWindowsはクソ.

やりかた

1. VirtualBoxとVagrantをインストール

ここでは本筋ではないので省略します.ネット上に記事はたくさん転がってるので参考にしてください.
Vagrantの使い方もとっっっても簡単なのでググってみましょう.

  • vagrant up (起動)
  • vagrant ssh (Vagrantで立ち上げたゲスト環境にSSHログイン)
  • vagrant halt (停止)
  • vagrant reload --provision (再起動する際にprovisionを実行)
  • vagrant destory (仮想環境を破棄)

とりあえずこれだけ知っていればどうにかなります.

2. Vagrantfileを編集

適当な作業ディレクトリをターミナル/コマンドプロンプトで開き,vagrant init "{BOX_NAME}"します.
BOX_NAMEはここから引っ張ってきます.今回は例としてubuntu/bionic64を使用しますね.
vagrant init "ubuntu/bionic64"を実行すると,Vagrantfileという以下のようなファイルができます.

ちなみに,このVagrantfileには設定上の様々なヒントがコメントとして記載されています.超親切ですね!
これをもとに,いい感じのオレオレVagrantfileを仕上げてみました.それとついでにdocker / docker-composeインストール用のシェルスクリプトも作りました.

ちなみに,Vagrantfile内のprovisionのところでshellの代わりにdockerを指定してconfig.vm.provision "docker", do |d|とすることで自動的にインストールすることも出来るのですが,本番サーバで実際に動かすDockerとバージョンを統一したいので,わざわざ手動でインストールしています.

3. docker-compose.ymlとnginx.confを編集

Vagrantfileと同じディレクトリにdocker-compose.ymlとnginx.confいう名前でファイルをふたつ作っておきます.
docker-compose.ymlの中はご自由に…という感じなのですが,今回はNginxでHelllo Worldを表示させることを目標にしましょう.
ちなみにNginxはApacheとならぶwebサーバソフトウェアのひとつです.
このNginxの設定ファイルnginx.confの設定例も一緒に貼っておきます.

またVagrantfileと同じディレクトリにwwwディレクトリを作り,その中にhello worldを表示させるindex.htmlを置いておきます.

4. 仮想サーバ起動

ここまでできたら,あとは仮想環境を立ち上げるだけです.Vagrantfileのあるディレクトリでvagrant upしてみましょう.
初回はOSのイメージを引っ張ってくるので少し時間がかかります.気長に待ちましょう.
しばらくするとCreating Web...と表示が出てくると思います(出てこないかもしれないですが).そうしたらブラウザでlocalhostを開いてみましょう.Hello Worldと表示されているはずです.

さいごに

今回,僕はさくらのVPSを借りているのですが,サーバーを本格的に運用するなら,これ以外にもやるべきことはたくさんあります.
最も面倒くさいのがセキュリティまわりの設定です.
ファイアウォールやSELinuxの設定も必要ですし,また多くのdockerコンテナは基本的にrootユーザーで実行されてしまうのでこれもまたセキュリティ上のリスクを抱えています.これを回避するための策も講じなければなりません.労力に見合わないんだよなぁ…
ただ,「今のローカルの環境を壊したくない,リモートデバッグ的に使いたい」というのであればちょうどいいかもですね!

というわけで,個人とか小規模なスタートアップ等でサービス開発するときはあらかじめ色々入ってくれてるやつ(Netlifyとか)を活用したほうがいいと思います.
つまりそういうことなんである.以上.

Node.jsを触ってみた

  1. Node.jsとは
    javascriptという言語がありますが,これはよくhtmlと組み合わせてクライアント側で使われます。しかし,Node.jsというものを使えばサーバー上で動かせます。Express-generatorと組み合わせて簡単な一人用チャットを作ってみました。
  2. Node.jsのインストール
    Node.jsと検索して公式ホームページからインストールすればいいです。するとコマンドプロンプトでnodeというコマンドが使えるようになります。
  3. フォルダの作成
    どこでもいいのでフォルダを作ります。
  4. socket.ioのインストール
    コマンドプロンプトのcdでそのディレクトリに移動した後,npm install -save socket.ioでできます。
  5. フレームワークのインストール
    npm install -g express-generatorでインストールできます。
  6. アプリの原型作成
    express -e appで作れます。appの部分は何でも構いません。
  7. パッケージのインストール
    cd appでappフォルダに移動します。そのあと,npm installと入力します。この時点ですでにアプリは出来上がっています。コマンドプロンプトでnode bin\wwwと入力するとアプリを実行できます。ブラウザでhttp://localhost:3000と入力すれば,Welcome to Expressと出てくるはずです。
  8. コードを書く
    編集するのは,wwwとindex.ejsです。Addedと書いてあるところに追加するだけで完成です。
    index.ejs:

    <!DOCTYPE html>
    <html>
    <head>
      <title>
        <%= title %>
      </title>
      <link rel=’stylesheet’ href=’/stylesheets/style.css’ />
      <!–Added–>
      <script src=”socket.io/socket.io.js”></script>
      <script src=”https://code.jquery.com/jquery-1.11.1.js”></script>
    </head>
    <body>
      <h1>
        <%= title %>
      </h1>
      <p>Welcome to
        <%= title %>
      </p>
      <!–Added–>
      <form id=”form” action=”#”>
        <input id=”input” autocomplete=”off” /><button>送信</button>
      </form>
      <ul id=”messages”></ul>
      <script>
        var socketio = io();
        $(function () {
          $(‘#form’).submit(function () {
            socketio.emit(‘message’, $(‘#input’).val());
            $(‘#input’).val(”);
            return false;
          });
          socketio.on(‘message’, function (msg) {
            $(‘#messages’).append($(‘<li>’).text(msg));
          });
        });
      </script>
    </body>
    </html>

    www.js:

    #!/usr/bin/env node
    /**
    * Module dependencies.
    */
    var app = require(‘../app’);
    var debug = require(‘debug’)(‘app:server’);
    var http = require(‘http’);
    /**
    * Get port from environment and store in Express.
    */
    var port = normalizePort(process.env.PORT || ‘3000’);
    app.set(‘port’, port);
    /**
    * Create HTTP server.
    */
    var server = http.createServer(app);
    /**
    * Listen on provided port, on all network interfaces.
    */
    server.listen(port);
    server.on(‘error’, onError);
    server.on(‘listening’, onListening);
    /**
    * Normalize a port into a number, string, or false.
    */
    function normalizePort(val) {
      var port = parseInt(val, 10);
      if (isNaN(port)) {
        // named pipe
        return val;
      }
      if (port >= 0) {
        // port number
        return port;
      }
      return false;
    }
    /**
    * Event listener for HTTP server “error” event.
    */
    function onError(error) {
      if (error.syscall !== ‘listen’) {
        throw error;
      }
      var bind = typeof port === ‘string’
        ? ‘Pipe ‘ + port
        : ‘Port ‘ + port;
      // handle specific listen errors with friendly messages
      switch (error.code) {
        case ‘EACCES’:
          console.error(bind + ‘ requires elevated privileges’);
          process.exit(1);
          break;
        case ‘EADDRINUSE’:
          console.error(bind + ‘ is already in use’);
          process.exit(1);
          break;
        default:
          throw error;
      }
    }
    /**
    * Event listener for HTTP server “listening” event.
    */
    function onListening() {
      var addr = server.address();
      var bind = typeof addr === ‘string’
        ? ‘pipe ‘ + addr
        : ‘port ‘ + addr.port;
      debug(‘Listening on ‘ + bind);
    }
    /**
    * Added
    */
    var io = require(‘socket.io’)(server);
    io.on(‘connection’, function (socket) {
      socket.on(‘message’, function (msg) {
        console.log(msg);
        io.emit(‘message’, msg);
      });
    });
  9. 完成
    スクリーンショット (1352)2

CNNについて

こんにちは。1年のhirotです。KCSでは主にAI班で活動しています。
と言っても、4月から12月にいたるまでに身に着けた知識はゼロに近く四捨五入したら初心者になるレベルですが…
しかし、今回はそんな僕が三田祭期間中に多少勉強したCNNの仕組みについて簡単に書いていきたいと思います。

★CNNとは

画像処理や音声認識など様々なところで使われるニューラルネットワークの一つです。主に「全結合層」「出力層」「畳み込み層」「プーリング層」の4層で構成されていて、これらを組み合わせることで処理を行えるという仕組みです。
例えば、「今持ってるたくさんの写真の動物が犬か猫か調べたい」という時に使用します。

★全結合層とは

1つの写真が持っている様々なデータをすべてまとめて扱いやすいように変換し、それにより得られたデータを活性化関数というもので差別化を行う層です。
例えれば、「この写真の動物の目と鼻と口は犬っぽい。だけど耳は猫っぽいなぁ」と識別します。

★出力層とは

全結合層で得られた結果を分析して、最終的な結果を出す層です。
例えれば、「犬成分の方が多い。だからこの動物は犬率75%だ」と出力します。

★畳み込み層とは

従来のニューラルネットワークは上の「全結合層」と「出力層」で構成されていました。しかし、ここで使われている「全結合層」にはデータをまとめる際に必要なデータを無くしてしまうという欠点があり、処理精度が高くありませんでした。
そこであらかじめ必要な情報を出しておくように改善され、その際用いられたのが「畳み込み層」です。

例えば、
ao
と表される画像があった時、
ak
畳み込みフィルタ-(特徴を浮かばせるもの)を通すと、
kk3.PNG

となり、出てきた緑色が特徴付けられた画像になります。
例えれば、「この動物は口が長くて、耳はピンと立っているな」と特徴を見つけます。

★プーリング層とは

取り扱っているデータの詳細情報を消去して、認識の幅を持たせる層です。
poo.PNG
このように1つの画像のある程度の範囲の最大値をとったり、平均化を行ったりします。
例えれば、「この動物の鼻に水滴がついてるけど、これは情報の一つにいれなくても平気だな」と考慮しなくていい情報を無くします。

★そして全部合わせてCNN

初めに述べたようにCNNはこれらの層を合わせて機能します。
順番は「畳み込み層→プーリング層」を何回か行った後、得たデータで「全結合層→出力層」となります。
とても大雑把な仕組みはこのような感じです。

★最後に

かなり雑になりましたが、CNNの仕組みについて書かせて頂きました。
Deeplearningに触れたことが無い人にも分かって頂けたら幸いです。
何か間違いがあったらすいません_(。。;)_