Month: 12月 2018

情報(工学)科の授業は教養ですらないという話 – 慶應義塾大学編

この記事はKCS Advent Calendar 25日目の記事です。

こんにちは、mt_caretです。最終日です。1お疲れ様でした。

情報科の授業は教養に過ぎないという話 – 東京工業大学附属科学技術高校編 — yosida95

自分がまだ高校生の時にこのブログ記事が大変話題になり、この記事や派生記事が大変印象に残りました。自分もついに学部3年になり、研究室も決まったので、そろそろ自分の大学や情報(工学)科に関する所感を述べます。不満だけ述べても生産的でないので、どうすれば良くなると思うかについても少し言及します。

TL;DR

  • カリキュラムが合わなかった(特に専門講義はかなり期待はずれだった)
  • 体系的な、幅広い範囲の情報科学教育(i.e. 教養)を期待しないほうがよい
  • 独学できる人ならSFCは悪くないのではないか

=> 進学先を間違えた

自分について

まずは軽く自己紹介をしようと思います。慶應義塾大学理工学部情報工学科に所属しています。

中学・高校ではロボコンや情報セキュリティに取り組んでおり、 CombGigを始めとする、CombConfと同じテーマの勉強会を開いたりしていました。その過程で、自分がやっていることはものづくりを趣味でやる範囲を出ていないことを痛感し、興味のない科目を学ぶことを強制されることなく、体系的に情報科学の様々な分野を学びたいと思い、大学に大変期待をしていました。

入学まで

興味のない分野の勉強に上手く打ち込むことができず入試に落ち、慶應義塾大学に進むことに。経済学部・環境情報学部・理工学部の3つに受かったため、情報科学を一番学べそうな理工学部に入ることにしました。

学門制 | 慶應義塾大学理工学部

ようこそ、学びの庭への 入口 [学門]へ! – 慶應義塾大学理工学部

慶應義塾大学には学門という概念があり、理工学部の入試の時点で学門1~5のどれかに入り、学部2年に進むタイミングで成績ベースで学科振り分けがされます。自分は情報工学科の定員が最も多い学門5を選びました。

B1

この学門制度にはいくつな不思議な点があります。

例えば、学門関係なく理工学部生は全員「基礎教育科目」という名目で数学・物理・化学や自然科学実験という物理と化学に関する実験を行う科目を履修することが強いられています。成績が悪いと希望しない学科に配属される可能性があるため、必死に取り組む必要があります。これが自分にとって予想以上に苦痛で、何故やる必要があるのか理解できないまま、情報科学を学ぶ権利を得るために、高校の時と同じように情報科学と一切関係のない分野の勉強や課題に取り組んでいました。

また、学門に関するサイトに

入学後、自分の興味や関心に応じて徐々に学びたい分野を絞っていき、2年進級時に所属する学科を決定します。

とありますが、自分の入学後、自分の興味や関心に応じて徐々に学びたい分野を絞っていった結果進みたい学科の枠が自分の学門に無い場合、「学門越え」が必要になりますが、理工学部全体で1学年1000人居る中許可されのは数人程度なので非常に難しいです

余談ですが、情報科学を学んだりプログラミング言語を学んだりする講義は理工学部の 1年の時は普通の選択科目としては用意されていません。例えば経済学部にはあるようだという話は聞いています。

B2

なんとか情報工学科に配属され、おお喜びです。これでやっと情報科学が学べるぞ!と思いきや、薄々感じていた違和感がより強く現れます。情報技術の話が通じる人が周りにいません。講義でもプログラミングはおろかパソコンを触ったことのない人を想定して進み、いくつかの講義を除き全て紙に鉛筆で進みます。

2年の時はC言語を学びます。2同期の多くはプログラミングをしたことがないため初めて学ぶプログラミング言語となりますが、3 純粋に文法と簡単な演習問題をやるだけなので、例えばポインタを理解していなくてもなんとかなりそうな感じでした。

コンピュータグラフィックスを専門とされている先生がアルゴリズムの講義を教え、4 ところどころテクニカルタームを誤用なさったり、最も実の有る講義と感じたラムダ計算とアルゴリズムのための離散数学の講義はそれぞれ文学部と数理科学科の先生によるものだったりと全体的に教員不足を感じました。アルゴリズムと言語処理系が専門の情報工学科の先生が欲しかったです。

また、講義を受けるための必修科目(prerequisites)、という概念がなくどの講義も事前知識を仮定されてないためか、例えばフーリエ変換やOSI参照モデルを別々の講義で複数回やり、カリキュラムの構成に違和感がありました。

B3

Cを1年かけて学んだ(?)次はJavaを学びます。5

3年の前期の後半は香港の企業でのインターンシップをやっていたため、限られた数の講義しか受けることができていませんが、3年になると4年の講義を履修することができることもあり、履修した範囲では流石に2年の講義と比べてもう少し深い内容になっている気がします。

しかし、米大などでは Captstone course6として位置付けられているコンパイラやOSの講義が後期週1コマに詰め込まれており、例えば計算理論の講義でDFAをゆっくり学ぶのと並列してコンパイラの講義でレキサ・パーサの文脈でDFAを軽く教わるといったような状況になり、やはりカリキュラムの構成が微妙だと感じました。

また、計算理論の講義ではAutomata Theory, Languages, and Computationをテキストとして進めますが、学生には難しいということでチューリングマシンの章まではやりません。なので、チューリングマシンを扱わず情報工学科の学位を得ることができます。余談ですが、同じ理工学部の数理科学科ではチューリングマシンまで含めて学ぶ計算理論の講義があるそうです。

こういったものを経て現在に至ります。研究室配属に関しても様々な話がありますが、話の本筋である情報科学教育から外れますので割愛します。

不満

  • 講義1つ1つが軽く、深いレベルの理解につながるような手を動かす課題を出す講義が非常に少ない
  • カリキュラム全体に統一感が無く、情報科学の中でも通信に偏っている
  • 同期に情報技術に取り組んできた人がとても少ない

良い点

  • G Suite・Google Drive無制限・Office 365あたりの福利厚生

結論

結論としては、

講義を通しては体系的な学習はできず、学部3年間は結構大きい機会損失だった

という風に考えています。カリキュラムについて良く調べ、事前に本質を見抜くべきでした。

申し送り

機会損失を減らす方向で、自分みたいな人に向けて書きます。

慶應義塾大学理工学部の受験を考えている人向け

  • 情報科学を学びたいなら、数理科学科がオススメです
  • 独学ができるなら、情報工学科と比べ必修科目が少なく自由時間が多い7 環境情報学部は悪くない選択肢だと思います

理工学部1年向け

  • 環境情報学部への転学部は比較的簡単らしい
  • KCSやロボット技術研究会といったサークルに入ったりし、探しに行くと大変優秀な人は一定数いる

情報工学科n年向け

  • ご愁傷さまです
  • n = 1くらいなら1年+αは埋没費用としてあきらめて大学の再受験は選択肢の1つだと思います
  • 過去n年は埋没費用として諦めて、残りのの4-n年の学費で学位を購入する気持ちで取り組みましょう。
    • ちゃんと取り組むと機会損失が増えるので講義・課題は最低限の手間を掛けて後は独学をがんばりましょう
  • 外の世界を見ましょう
    • 勉強会での発表は良い経験になります
    • インターンはよい経験になるだけではなく、職にも繋がります

免責

なお、このブログエントリを真に受けた事によって生じた利益や不利益について私はもちろんあなたの周囲の誰も責任を取りません。 自分の進路における決定はすべて自分の責任の下に行なわれるべきです。 しかし、無責任な周囲による無責任な意見を積極的に聞いて自分自身で咀嚼した方がお得です。 あなたは自身が想像している以上に視野狭窄です。 周囲の意見を聞くことで、自分だけでは考えつかなかった選択肢がいくつも出現して裏ステージへ進める可能性が高まります。
私自身がひどい視野狭窄に陥っている可能性が高いので、周囲の意見を聞こうという自戒です。 よろしければ、このエントリや私の考え方についてご意見や反論などをください。
(情報科の授業は教養に過ぎないという話 – 東京工業大学附属科学技術高校編 — yosida95より)

完全にこれです。是非意見・反論をください。

謝辞

事前に読み、フィードバックを送ってくれた皆さん、ありがとうございました。


  1. 遅刻しました。ごめんなさい。

  2. サンプルコードの文法が間違っているためそのままではコンパイルが通らないことが多々あったことが印象に残っています。また、課題の出力フォーマットが曖昧な上に手動で採点が行われているため、提出されたコードは目視で確認し採点する時がある、といったようなことをTAの方から聞いた記憶があります。既存のオンラインジャッジでもよいので、(可能であればオンラインの)自動的な採点システムが欲しかったです。

  3. C自体情報科学をやる上で必須だと思いますが、初めて学ぶ上でつまづきやすい、本質的でない部分が多いような気がしてなりません。SchemeやPythonあたりでSICPをやるぐらいが丁度よいかなと思いました。

  4. 線形探索に一時間半の講義を丸々掛けていたのが印象に残っています。

  5. E.W.Dijkstra Archive: To the Budget Council (concerning Haskell)
    余談ですが、環境情報学部ではプログラミングの講義として上級者向けにHaskellを学ぶ選択肢があるようです。

  6. こういった講義の存在は日本の大学では聞いたことがありません。東大のCPU実験あたりが該当するのでしょうか?

  7. 諸説あるようです。

Marloコンペ用の強化学習環境をサーバーに立てた話(おまけ:Google ColabでDQN)

はじめに

こんにちは、syuntoku14です。現在カリフォルニアでスマブラしてます。イカちゃん強いね。

 

スマブラのせいで時間がなくなってしまったので、本記事ではDavisで作成した無についてしゃべります。

 

皆さんMarloコンペというのをご存知ですか?OpenAIが主催しているMinecraft環境での強化学習の大会で、入賞するとカナダに行けたりするすごいやつです(もう終わっちゃいましたが、来年もあると思います)。

 

MarloコンペのチームにDavisで参加し、私は環境構築を担当したわけなんですが、この環境構築が鬼めんどくさかったのでスクリプト化しました。

 

一応公式ページにインストール方法などは書いてあるんですが、Minecraft環境非常に不親切で、ウィンドウがある環境でないと動きません。このままではGoogle Cloudなどクラウド上で学習させることが出来ません。困りましたね。

 

 やったこと

 

xvfbを使って仮想ウィンドウを作成し、Marloを走らせました。が、これだけではなぜか動かなかったので(OpenGL周りが原因?)、最終的に公式が配布しているDockerファイルを弄くり、中にあるlaunchClient.shをxvfb付きで実行したら動きました。

 

最終的に出来上がったDocker imageがこれです:

 

以下のコマンドで任意のポートにつなげて実行できます。

 

“`
docker run -it –rm -p [number of port]:10000 syuntoku/marlo_client
“`

 

ここまで自力で頑張ったあとで、これDocker Hubに既に存在していることに気がついてしまいました。圧倒的車輪の再発明だったんですね(悲しいね)。まあDockerについての知識が微妙についたので良いんじゃないでしょうか。

 

あとはこれをdocker-composeと–scaleオプションで並列化させて実行するだけです。(スクリプトにしました)

 

クラウド上で利用するにはDockerやCUDA、Anacondaのインストールもやらないといけないので、これもスクリプトにしました。

 

できたもの

Github:

https://github.com/syuntoku14/marlo_headless

使い方は一応READMEに書いてあります。

 

手順:
1. AWSでもGoogle Cloudでも何でも良いが、Ubuntu18.04環境を立ちあげる。
2. Jupyterの設定も勝手にしするので(ポート5000)、各クラウドのブラウザから5000番ポートを開けとく
2. 中でgit clone https://github.com/syuntoku14/marlo_headless.git
3. . ./marlo_headless/install/gcp/install.bash
4. . ./marlo_headless/docker/launch_multi_client.sh [number of environment]

 

私はVimmerなので、Jupyter-notebookのvim extensionをセットアップするスクリプトなども別でついてます。

 

肝心の学習ですが、まだやっていないです(無能)。学習させたらまた記事を書きます。おちまい。

 

おまけ

 

Courseraの課題でDQNを実装してGoogle Colab上で動かしました。

 

Gist:

 

先ほど紹介したMarlo用のスクリプトはついでにgym環境もインストールするので、上記のgistを参考にして適当にやればGoogle Cloudで簡単にAtariの学習も出来ます。やったね。

 

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…ゲフンゲフンだもの。二分探索木の挿入や巡回、探索などは再帰呼出しを使うと短いコードで書けるのですが実装するにあたってわざわざ再帰呼出しなしで挿入したり巡回しましたね…

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

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

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

 

Studio One Prime を用いたDTM入門

この記事はKCS Advent Calender 17日目の記事です。
 
初めまして、生命情報学科3年生の紫藤です。KCSでは音楽班で活動しています。今回はDTM初心者の私が音楽班に入って一曲作れるようになるまで具体的に何を行ったか、利用させて頂いた記事等を紹介していきます。

DTM興味あるけどなんも分かんねーって方は、記事内のリンク集が参考になるかもしれません。
(DTM入門!っていうサイトは星の数ほどありますが、身近な体験談ってことで差別化を一つ。)

使用環境
OS: windows 10
DAW: Studio one 3 prime (現行版は4)

1. DAWインストール

DAWは作曲に使うソフトです。無料で使えるものはいくつかあるのですが、私はStudio One Prime を使用しました。以下のサイトに分かりやすい導入方法が載っています。↓
https://sleepfreaks-dtm.com/for-beginner-studioone/studio-one-4-prime/

このとき追加音源の導入に失敗すると、音がでなくて詰みます。私は一度再インストールしました()
 

2. 設定

 
始める前にまずキーボードショートカットの設定をしておくことをお勧めします。
譜面の再生・停止がデフォルトではテンキーに割り当てられているので、別の触りやすいキーに割り振ると良いと思います。私は停止をF4, 再生をF5に充てました。
設定方法は以下のリンクが参考になります。(再生は”スタート”、停止は”停止”なので、検索窓にそれらを入力)
http://kumagaimashairo.com/archives/7689392.html

3. DAWに触れる

 
操作方法については、検索すれば分かりやすい解説がいくつもあります。「studio one prime 使い方」等で検索するとザクザク出てきます。(studio one 4自体のリファレンスは現状少ないのですが、UIは過去バージョンと大差ないため、3の解説でも十分役に立つと思われます。)

まず↓のサイトにお世話になりました。「新規ソングの作成」「Presenceの立ち上げ:その1」「ピアノロールで打ち込み:その1~4」の辺りの項を読めば、楽器を選んで音を鳴らせるようになります。
https://kaymusic-online.com/index.php?studiooneprime

流れを掴むのに↓の動画も分かりやすいです。
https://www.youtube.com/watch?v=VJnGqfkZhOw&t=1021s

 
とりあえず適当に楽器を選んで音を出せるようになった頃からは、以下のサイトを参考に打ち込みをしました。↓
http://dtm.55-52.com/

「ドラム打ち込み講座」「ベース打ち込み講座」「エフェクト使い方講座」等の記事が役に立ちます。特にドラム打ち込みはDTM始まった感があってすごく楽しかった記憶があるので、おすすめです。
studio one での打ち込みについては↓を参考にすると良いです。
https://abc-musicschool.com/online/2017/04/dtm_lesson4-2/

鼻歌で考えたメロディにドラムを付けてみるだけで一気に曲らしさが増したり。あとはリバーブを付けてみると楽器が艶っぽくなってテンション上がったりします。
(リバーブについては上のエフェクト使い方講座、その使用方法は以下リンク↓)
https://www.studiorag.com/blog/fushimiten/studio-one-mix/2

4. 作曲

 
メロディとドラムがあればだいぶ曲らしくなるのですが、そこから別の楽器の音色を重ねていくのには、少し知識が必要です。

自分が行った作曲の手順での必要知識は、ドレミファソラシドの鍵盤上の位置や、音階の英語名、曲にはそれぞれキー(調)があり使用できる黒鍵や白鍵が決まってること、などです。要するに、「Cメジャースケール」だとか「ト長調」って言われて分かればOKです。
知らなかった方は以下リンクをご参考に
http://music.nonono.jp/composition/composition01
http://joy-music.jp/magazine/articles/compose/key/
https://thesaibase.com/music/theory/alphabet

(そんなの面倒くさいって場合は「ループ作曲法」とかググると良いです。ループ素材の使用方法は↓)
https://www.youtube.com/watch?v=PGEMX4jJWBw&list=PL53836339204520C2&index=16

 
私が一曲目に作ったのは、Koto(琴)とPan Fluteがメロディ、Basic kit(ドラム)があって、他にはFingered Bass(ベース)が低い音を単音で弾き、とGrand Pianoが和音を弾くという構成です。
まずは先ほどのドラム打ち込み講座で打ち込んだドラムのパターンをコピペで増やして、そこに鼻歌でメロディを考えて琴とフルートで鳴らしました。
この次に、メロディからこの曲の調を割り出しを行いました。無意識で歌った鼻歌でも必ず何かしらの調に属しているはずなので、打ちこんだメロディのシャープ・フラットがどこにあるのかを調べて調を確認しました。(ここが難しいかもしれません。参考↓)
http://guitarex.web.fc2.com/knowledge/key_signature.html

調が判明し、その曲中で使用できる音が決まったので、後はその音の中から適当にベースを鳴らしてみて一番良さそうな音に決めて、pianoも鳴らして違和感のない和音を地道に当てはめていって完成しました。

要するにゴリ押しなので、調を判明させる必要は別になかったと思います。調が分からずとも、調に合わない音を鳴らすとどうしても違和感が残るので、手間こそ増えますが、地道に鳴らしてしっくりくる音を探すという同様の方法を使ってピアノやベースを入れられると思います。
また制限をかけるために、pianoの和音にはそこで鳴っているメロディの音を入れた上で他の+1~2音を見繕っていきました。

今回の私の方法はメロディを決めてから和音(コード)を探っていきましたが、コードを最初に決めてからメロディを載せる方法もあります。正攻法は調を決めて、使用できるコードを当てはめていく方法ですが、難しいので、予備知識のいらない方法についてお伝えします。前者に興味があれば「音楽理論 入門」とかでググるとよさげです。下に参考になったサイトを貼っておきます。
http://studay.info/
https://www.studiorag.com/blog/fushimiten/kanon-chord?disp=more
http://sakkyoku.info/theory/diminished-seventh-chord/

予備知識のいらない方法ですが、コード進行のパターンをどこかから持ってきて、それを打ち込むのが手っ取り早いです。分かりやすいのは既存曲のコード進行を調べて載せてみる、など。他には
↓のようなコード進行を載せているサイトを探して、
http://www.masayoung.net/archives/970
↓こういうサイトでその各コードの構成音を調べて、dawに打ち込む、など。そこにメロディ適当につけて、ドラム付けて、ベースでその各コードの根音(AコードならA(ラ)の音)を弾けば曲が完成します。
http://www.piano-c.com/pianoChord_CMa.html

 
また作曲に関して分かりやすい動画を見つけたので、リンクを貼っておきます。
https://www.nicovideo.jp/watch/sm2161286

5. Tips

 
・メトロノーム
https://unko.kpop.jp/studio_one/20180208-4-metronome.php
考えたメロディを打ち込むとき、音符の長さがどこまでか分からずに困ることがあると思います。その時はメトロノームを鳴らしておくとリズムを取りやすくなります。

・ショートカットキー
https://ch.nicovideo.jp/yellow_line/blomaga/ar978623
特にctrl+s, ctrl+z, ctrl+y, Dは必須と言っていい程よく使います。また2. 設定 でショートカットキー登録したスタート、停止も必須です。マウスでカチカチするよりよっぽど楽です。

・ループ機能
https://sleepfreaks-dtm.com/for-beginner-studioone/loop-play/
試しに打ち込んでみた音が曲全体に合っているかどうかを確かめるには、再生してみる以外ありません。その度にわざわざキーを押すのも一手間です。ループ再生の機能でループさせながら、入れる音を決める、という方法がかなり便利です。

・音源
http://gaha2.blog52.fc2.com/blog-entry-766.html
外部音源でメジャーなフォーマットはVSTpluginですが、studio one primeはVSTを使用できません。studio one primeで音色を拡張する方法としては、soundfontというフォーマットがあります。(拡張子はsf2。sfzは無理なので注意!)

・Studio one起動してるとyoutube等の音が出ない
https://sleepfreaks-dtm.com/dtm-trouble/sound-out/

↓あまり関連ないですが、最近感動したTipsを貼っておきます。Studio one professional付属音源のギター打ち込みの記事です。midiデータだとかエディタの画像だとかを用いて再現性の高い情報をくれる記事はとても素晴らしいですね。(遠い目)
https://htmusicm.hateblo.jp/entry/studio-one-3-guitar-uchikomi

 

ここまで調子に乗ってべったべったと他人様のブログのリンクを貼り付けてきましたが、許可は一切取っておりません。もし問題だぞという方が居れば、お手数ですがご連絡をお願いいたします<(_ _)>

あんぱんたべたい

Algebraic Effects for Rust

Algebraic Effects for Rust

この記事はKCS Advent Calender 18日目の記事です!
Algebraic Effectsが最近話題ですね!自分は普段Rustというプログラミング言語を使っているのですが,残念ながら(?)Algebraic Effectsの言語レベルサポートはありません.無ければ作るとも言いますし,AEをサポートするライブラリを作ってみたので紹介します.

Algebraic Effectsとは?

自分も良く分かりません.教えてください.

「継続がとれる例外」らしいですね.

どうやって実装したの?

びしょ〜じょさんの記事によると,コルーチンを使うとAEの実装ができるようです.ちょうどRustにはasync/awaitサポートのためにコルーチンが今年入ったので,それを使えば実装できそうですね.詳しい実装方法は次のコミケ(30日日曜日です!)の冊子にこれから書く書いたのでそちらを参考にしてください!

はじめてのAlgebraic Effects

以下で登場するコードはhttps://github.com/pandaman64/hello-effからもダウンロードすることができます.

まずはRustを入手します.新しい機能を利用しているので(特にunsized_locals)最新のNightlyビルドが必要です.

$ rustup update
$ rustup toolchain install nightly

それが済んだら新しいプロジェクトを作りましょう.

$ cargo new hello-eff
$ cd hello-eff

Cargo.tomlのdependenciesに次の行を追加します.まだcrates.ioにはアップロードしていないのでGitHubのURLを書いています.

eff = { git = "https://github.com/pandaman64/effective-rust.git" }

それではmain.rsを下のように書いていきましょう.

#![feature(generators)]

use eff::*;

struct Hello;
impl Effect for Hello {
    type Output = String;
}

struct World;
impl Effect for World {
    type Output = String;
}

fn main() {
    let with_effect = eff! {
        let hello = perform!(Hello);
        let world = perform!(World);

        format!("{} {}!", hello, world);
    };

    run(with_effect, |x| println!("{}", x), handler! {
        H @ Hello[_] => {
            resume!("Hello".into());
        },
        W @ World[_] => {
            resume!("World".into());
        }
    });
}

これをcargo runで実行すると

Hello, World!

と表示されることでしょう.

これは一体何が起きているのでしょうか.
コードを一行一行見ていきましょう.

#![feature(generators)]

これは,このモジュールではジェネレータを使うという宣言です.ジェネレータとはコルーチンのRustでの名称です.Rustでは実験的な機能は明示的にオプトインしなければ使うことができません(feature gateと呼びます).このライブラリはジェネレータをフルに活用しているので,この宣言が必要です.

use eff::*;

次の行はライブラリのインポートです.自分が書いたAEライブラリはeffという名前で公開されているので,eff::*と書くことによって後ろのeff!handlehandler!といった関数・マクロをインポートします.

さて,この後に続くのがエフェクトの宣言です.

struct Hello;
impl Effect for Hello {
    type Output = String;
}

ここでは,Helloという名のエフェクトを宣言しています.effではエフェクトの宣言はEffectトレイトを実装することで行います.Effectトレイトの実装にはOutput型を指定する必要があり,Outputはこのエフェクトが解決したときにどの型の値になるかに相当します.

Worldの方も同様にエフェクトの宣言がされています.

それでは,main()の中を見ていきましょう.まずは以下の部分です.

let with_effect = eff! {
    let hello = perform!(Hello);
    let world = perform!(World);

    format!("{} {}!", hello, world);
};

ここでは,eff!マクロを使ってエフェクト付きの計算を定義しています.注意してほしいのは,この時点ではまだeff!内部の計算は実行されていないということです.eff!の中では,perform!を使ってエフェクトを発動することができます.perform!式の結果は上で紹介したEffectトレイトのOutput型となります.
今回の場合はどちらもStringですね.perform!によって取得した値はformatの行のように自由に使うことができます.

eff!で定義したエフェクト付きの計算はrun関数によって実行することができます.

run(with_effect, |x| println!("{}", x), handler! {
    H @ Hello[_] => {
        resume!("Hello".into());
    },
    W @ World[_] => {
        resume!("World".into());
    }
});

run関数は
1. エフェクト付き計算
2. value handler
3. effect handler

の3つを引数にとります.1のエフェクト付き計算は上で紹介したeff!マクロで作った値です.2のvalue handlerはeff!マクロ内の最終的な計算結果を受け取ってあれこれする関数です.今回は|x| println!("{}", x)と標準出力にプリントしてますが,そのままの値が欲しい場合は|x| xとすれば良いでしょう.3のeffect handlerにエフェクトに応じて処理を行うコードを記述します.

effect handlerはhandler!マクロにハンドラを並べることで定義します.一つ一つのハンドラは

ユニークな識別子 @ エフェクトの型 [ パターン ] => 式

という文法で記述します.ハンドラを複数書くときは,カンマで区切って書きます(実装をサボっているので末尾カンマは許容されません).

エフェクトの型によってこのハンドラがどのエフェクトをハンドルするのかを指定し,ハンドルした結果がとなります.perform!に渡されたエフェクトはパターンによって束縛されます.今回の例ではHelloWorldといったエフェクトの型が重要で,値自体は不要なので_パターンによって捨てています.ユニークな識別子は実装上の都合(Rustのマクロは識別子を生成できない)で必要です.handler!内でユニークになるよう名前をつけてください.

さて,ハンドル結果のについて見ていきましょう.ここには任意の式を書くことができますが,その中でも特別に扱われるのがresume!マクロです.resume!(式)はエフェクトの発動時点(perform!の時点)から処理を再開します.このとき,perform!の結果はresume!に渡した引数に評価されます.ですので,resume!に渡す式は対応するエフェクトのOutput型の値でなければいけません.これによって,例えば実装の分離ができることでしょう.

ハンドラ内でresume!を行わない場合は,ハンドラの式の結果がrun関数の結果となります.これを使えば,例外のような大域脱出が実装できます.

また,effライブラリはハンドラのexhaustiveness checkを行います.つまり,ハンドラがエフェクト全てを網羅しているかをチェックします.試しに上のコードからWorldのハンドラを削除するとコンパイルエラーとなることでしょう(マクロの内部でエラーが発生するのでエラー自体は読んでも意味が分からないと思います...).

引数をとるエフェクト

エフェクトは引数をとることができます.どうするのかというと,Effectトレイトを実装する型にフィールドを加えるだけです.上のサンプルに下のエフェクト型を追加しましょう.

struct Ask {
    prompt: String
}
impl Effect for Ask {
    type Output = String;
}

次に,eff!部分を下のように置き換えます.Worldエフェクトの代わりにAskエフェクトをperform!するようにしました.

let with_effect = eff! {
    let hello = perform!(Hello);
    let name = perform!(Ask {
        prompt: "What's your name?".into()
    });

    format!("{} {}!", hello, name)
};

さて,扱うエフェクトの型が変わったのでハンドラも書き換えなければいけません.ここでは次のようにしました.

use std::io::{stdin, stdout, Write};
let stdin = stdin();
run(with_effect, |x| println!("{}", x), handler! {
    H @ Hello[_] => {
        resume!("Hello".into());
    },
    A @ Ask[Ask { prompt }] => {
        print!("{} ", prompt);
        stdout().flush().unwrap();

        let mut name = String::new();
        match stdin.read_line(&mut name) {
            Ok(_) => resume!(name.trim().into()),
            Err(_) => eprintln!("failed to read"),
        }
    }
});

Worldのハンドラの代わりにAskのハンドラが追加されています.Askハンドラではpromptをエフェクトから取り出した後(ここで構造体パターンが使われていることに注意),それを表示しユーザからの入力を待ちます.入力が成功した場合には,resume!によって処理を戻します(trimは末尾の改行文字を除くためです).失敗した場合にはfailed to readと標準エラーに出力して終了します.こっそりstdinをハンドラ外の環境から引っ張ってきているのにも注目してください.

error: recursion limit reached while expanding the macro

というエラーが出た場合には#![recursion_limit="128"]という行を先頭に追加してください.

制約

  • ジェネリックなハンドラ.実装上の都合でジェネリックなハンドラが宣言できません.特に不便な点は,ハンドラで参照をとることができません(参照のライフタイムが宣言できないため).
  • その他にもライフタイムの不必要な'static制約がいくつかあります.困ったときはとりあえず参照を使うのをやめてください.
    eff!のネスト.実装のアイデアはあるのでもう少しお待ちください.
  • エフェクトのうち一部だけハンドルするハンドラ.exhaustivenessとこれを両立する実装を考えているところです.型レベル黒魔術が必要かも?

以上,Rust向けAlgebraic Effectsライブラリeffの紹介でした.自分自身良くわからないままやっているので,もっと良くなるところもあると思います.質問・意見等々ある人はhttps://github.com/pandaman64/effective-rustにIssueを立てるかTwitterで@__pandaman64__までぜひメンションを飛ばしてください!

再度の宣伝ですが,KCSはC95の二日目(30日)に同人誌を頒布予定です!
自分もそちらにこのライブラリの仕組みを解説する記事を寄稿しているのでぜひそちらもご覧ください.

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内でも本の輪読会を継続する声が上がっています.非常に嬉しいです.

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