離島プログラマの雑記

島根県の離島、隠岐・西ノ島に移住して子育て中のフリープログラマです。

Windows タブレットでデジタルサイネージ制作

あらすじ

隠岐・西ノ島に移住して早くも3年が過ぎましたが、去る7月21日、我らが西ノ島町にもすてきな図書館が完成しました。

f:id:k-aeg:20180919221002j:plain

今回この図書館のウェブサイト制作と館内のデジタルサイネージ(しまポータル)の制作を任せていただきました。 特にデジタルサイネージはあまり制作機会がないので制作記を記しておこうと思います。 備忘録を兼ねているのでかなり細かい話が多くて読みづらいですが。

f:id:k-aeg:20180920015649j:plain

システム構成

f:id:k-aeg:20180919230326j:plain

しまポータルでは、タッチ操作できるインタラクティブなコンテンツを計画していましたが、システム構成は予算の都合上、大型タッチパネルモニタではなく普通の大型テレビモニタと操作用のタブレットという構成になりました。ちなみに大型タッチパネルモニタは普通のテレビの3倍くらいのお値段...。

検討案 検討内容
大型モニタ + 画面表示用PC + 操作用タブレット モニタとPCはHDMI、PCとタブレットの接続はWiFi(リモートデスクトップ)となる。WiFI通信による操作遅延と、リモートデスクトップ自体の操作バネルが常に表示されており、ユーザが操作できてしまうという問題あり。
大型モニタ + 操作用タブレット 操作用タブレットとモニタはHDMIで接続。基本的に有線接続となるためケーブルの取り回しが効かなくなる。通信による操作遅延はないが、タブレット側で2つのモニタ出力をまかなう必要があるので、廉価タブレットオンボードGPUには若干負荷が高めか。

当初の案では、画面表示用PC + 大型モニタ + コントロールタブレットという構成で検討していましたが、Webサイトのブラウジングなど、モニタとコントローラの画面を完全に同期する必要があったので、タブレットから直に大型モニタに出力するシンプルな構成となりました。

コンテンツはウェブサイトと共にVPSに配置しており、タブレットからアクセスしています。

モニタへの出力方法

タブレットからモニタへの出力方法は無線・有線を検討しましたが、遅延や安定性などを考慮して有線としました。

検討案 検討内容
無線(ワイヤレスHDMI) 送信機のドングルが邪魔なので却下
無線(ChromeCast のような WiFi で飛ばすタイプ) タブレット本体がケーブルレスになるので取り回しが良い。動画などでは問題にならないが、インタラクティブなコンテンツは操作遅延が気になる。また、受信側のドングルは熱のこもりやすいモニタの裏側(しかもモニタは木枠で覆われたデザイン)に設置することになるため、動作が不安定になりそう。
有線(HDMI) ケーブルの取り回しやタブレット側接続端子の耐久性が問題だが、最も遅延が少なく安定している。

HDMIケーブルは通常のストレート型だと端子に負荷がかかるので、L字型(左向き)のものを使用しました。

タブレット選定

タブレットはモニタと画面をミラーリングする都合上、アスペクト比をなるべく揃えることと、キオスク端末としての設定の柔軟さ(と予算)で検討し、Windows10 Pro のタブレットを使用することにしました。

検討案 検討内容
iPad アスペクト比4:3であり、テレビ画面(16:9)と大きく異なるので却下。
Android タブレット 常に表示される操作ボタンバーのため、テレビのアスペクト比16:9より若干幅広な16:10のものがほとんどであり、テレビのアスペクト比に併せて出力した場合、タブレット側の上下に黒い帯ができてしまう。また Android のバージョンにもよるが、電源周りの設定等、キオスク端末として使うための機能が不十分であったり、それらの機能にバグがあるなどの理由で却下とした。
Windows タブレット 設定の方法は煩雑だが自由度が高く、機能的には十分。Android タブレットと同様にアスペクト比 16:10 のタブレットが多く、Android タブレットと同様に帯ができてしまう。稼働中に Windows Update が実行されないようにスケジューリングが必要なため、Windows 10 Pro エディションが必須(Home だと制御不可)。

機能や性能の要件的には Microsoft Surface シリーズがベストですが、経年劣化や故障によるリプレースも視野に入れると予算オーバーだったため、Lenovo 製の Windows10 タブレット(キーボード付き)を採用しました。Windows 10 Home のモデルしかなかったので、購入後に Pro にアップグレードしています。

Surface 以外で候補にしていたWindowsタブレットは以下の通りです。いずれも3万円台。

機種名 メーカー モニタサイズ 重さ プロセッサ ビデオカード メモリ ストレージ
LAVIE Hybrid ZERO HZ100/DA 2016年春モデル NEC 11.6インチ 398g Pentium 4405Y/1.5GHz インテル® HD グラフィックス 515 4GB 64GB
Diginnos DG-D09IW2SL ドスパラ 8.9インチ 495g Atom x5-Z8350/1.44GHz インテル HDグラフィックス400 4GB 64GB
ideapad Miix 320 80XF0007JP Lenovo 10.1インチ 550g Atom x5-Z8350/1.44GHz インテル HDグラフィックス400 4GB 64GB
WiZ KVK111KHD KEIAN 11.6インチ 730g Atom x5-Z8350/1.44GHz インテル HDグラフィックス400 4GB 32GB
dynabook S29/TG PS29TGP-NYB 東芝 8.9インチ 479g Atom Z3735F/1.33GHz Intel Atom® プロセッサー Z3700 シリーズ向けインテル® HD グラフィックス 2GB 32GB

コンテンツ制作

コンテンツ制作は、ウェブベースで行いました。廉価タブレットの性能を考えると Unity でネイティブアプリとして実装したほうがキビキビ動いて良かったんですが、ネイティブアプリ内でウェブサイトのブラウジングを扱うのがいろいろ厄介な感じだったので断念して、全部ウェブでやることにしました。イラストは西ノ島町出身のデザイナーまの悠さん( marumi03 )によるものです。

f:id:k-aeg:20180920021541j:plain

f:id:k-aeg:20180920021525j:plain

f:id:k-aeg:20180920021638j:plain

f:id:k-aeg:20180920021702j:plain

クライアント側は貸出ランキングや埋め込みブラウザの表示に vue.js、サザエや牛を触ったりできるインタラクティブ要素に phina.js + Box2d などを使って実装しました。 サーバ側はOPACから吐き出される貸出ランキングなどのCSVデータに、RubyopenBD から取得した書影URLを付加して JSON に成形したものを配信しています。貸出ランキングなどはサーバ側でレンダリングまでしたほうがおそらく速いんですが、今の所すべてクライアントまかせです。

Windows タブレットキオスク端末

いろいろなやり方があって試行錯誤しましたが、最終的にシンプルだけどあまり上品でない方法に落ち着きました(笑)

  1. キオスク画面用のローカルユーザで自動ログイン(管理者アカウントは別に用意しておく)
  2. スタートアップで explorer.exe(エクスプローラ) の強制終了と Chrome のフルスクリーンモード起動を行うバッチファイルを実行

ChromeKIOSKモードで大体の要件は満たせるのですが、explorer.exe の強制終了が必要なのはエッジスワイプ(画面端から画面内に向かってのスワイプ)対策です。エッジスワイプ操作が行われると、エクスプローラのアプリ一覧画面が表示されてしまい、Chrome の画面から抜け出せてしまいます。

デジタルサイネージを作ったので学んだことを晒してみる Part.1

エッジスワイプ自体を無効にする方法はいろいろウェブ上に乗っているのですが、現在のバージョン1803ではどれも無効なようで、最終的に確実な解決策が explorer.exe を殺す、という方法な訳です(笑)

explorer.exe を強制終了しても、タスクマネージャは Ctrl + Alt + delete キーで起動できるんですが、タブレット端末の場合は入力できないので問題なさそうです。(Surface とかハードウェア Windows ボタンがついている場合は電源ボタン + Windows ボタン長押しで起動できてしまうようですが...)

forest.watch.impress.co.jp

なお、一番真っ当なやり方としては、

  • Windows 構成デザイナー(ICD)でキオスク端末としてプロビジョニング
    • キオスク用アカウントの作成や、固定するアプリの指定(割り当てられたアクセス)、スクリーンの自動オフ無効化などをまとめて設定
  • 割り当てられたアクセスには Kiosk Browser を指定

だと思います。が、Kiosk Browser や IE11 ではタッチイベントを拾えず、うまくコンテンツが動かなかったのでやむなく却下としました(Microsoft Edge の開発者オプションでタッチイベント有効にできるぽいけど、Kiosk Browser ではできなそう)。

ちなみに開発当初、「割り当てられたアクセス」はストアアプリ限定のため、ブラウザとして使えるのはIE11のみ(Microsoft Edge はストアアプリだが「割り当てられたアクセス」に非対応、Chrome 等他社製ブラウザはストアアプリでないため使用不可)という状況でしたが、Windows 10 Fall Creators Update(バージョン1703)でMicrosoft 公式の Kiosk Browser(Edge の機能限定版) が実装されたので、これを使うことができるようになりました。

Kiosk Browser の細かい設定ができるようになったのは、Windows 10 April 2018 Update(バージョン1803)からで、Windows 構成デザイナー(ICD)を利用して規定のURLや表示するUIの設定を行うことができるようになったようです。

“割り当てられたアクセス”で使えるMicrosoft純正ブラウザ「Kiosk Browser」とは:企業ユーザーに贈るWindows 10への乗り換え案内(28) - @IT

さらに補足しておくと、Windows 構成デザイナー(ICD)にはストアアプリ版と Windows ADK 版の2種類あるんですが、ストアアプリ版は罠です!ストアアプリ版ではキオスク端末のプロビジョニングウィザードで、Required の項目を全部埋めてもパッケージのビルドができない不具合があってハマりました。Windows ADK 版を使いましょう。

docs.microsoft.com

なお、プロビジョニングウィザードで固定するアプリに Windows Classic のアプリが(ドキュメントには Windows 10 Proは非対応と書いてあるが)指定できたのでやってみたところ、キオスク用アカウントでサインインできなくなるばかりか、管理者アカウント側のエクスプローラが起動しなくなり復旧が大変でした(笑)

ちなみに復旧方法は、

  1. 管理者アカウントでログイン(画面真っ暗)
  2. Ctrl + Alt + Delete でタスクマネージャ起動
  3. 適当なプロセスの右クリックメニューから「ファイルの場所を開く」→ エクスプローラが起動する...がタスクバーはまだ表示されない
  4. タスクマネージャでファイルエクスプローラのアプリの「ファイルの場所を開く」
  5. explorer.exe をダブルクリックで起動 → タスクバー復活
  6. 原因となったプロビジョニングパッケージの削除 → http://www.wannko.net/windows10/etc/probijo2.html Windows10のプロビジョニングパッケージを解除・削除を行う方法
  7. 「regedit」を起動し、レジストリを編集。 キー名:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 値名 :Shell に"eshell.exe"が設定されていたので、“explorer.exe” に置き換え(全ユーザ用の初期起動Shellの設定)。

Windows 10 でのシェルの置き換えについて | Ask CORE

Windows10でWindows ICDを使って埋め込みシェル起動ツール(Shell Launcher)を設定する方法

【cmd】Windows10でエクスプローラーが動かない時にコマンドプロンプトでエクスプローラーだけを再起動する方法 | onocom

2 でタスクマネージャ起動できるのに気づくのに時間がかかったり、3でエクスプローラが起動するけどタスクバーが表示されない状態でハマったり、7の当該レジストリを探したりなんだかんだで復旧に1日かかりました...。

以上、コンテンツについてあまり触れていないですが、とりとめのない制作記でした。中身の話はそのうち書くかも...

プログラミング教室のPCを Raspberry Pi に置き換えてマイクラでプログラミングまで

しばらく更新が滞っていましたが、にしのしまデジタルラボ・プログラミング教室は、おとなり海士町での開講に伴い、「隠岐デジタルラボ・プログラミング教室(西ノ島教室、海士教室)」として活動しています。

西ノ島教室では、某所からお下がりでもらった10年前くらいのデスクトップPCを使っていましたが、故障が目立つようになってきたため、リプレースとして最新の Raspberry Pi3 B+ を導入してみました。

Raspberry Pi のOSである Raspbian には、しばらく前から Mincraft Pi (Raspberry Pi 用のマイクラ)がプリインストールされており、さっそく小学生に見つかった(笑)のでみんなで遊んでみることにしました。Mincraft Pi の特徴はスクリプトでプレイヤーを動かしたり、ブロックを配置したりできるところなので、普段使っている Scratch と接続してマイクラプログラミングもやってみます。

f:id:k-aeg:20180620162349j:plain

購入した機材

f:id:k-aeg:20180604114229j:plain

本体セットアップ

OSイメージの準備

www.raspberrypi.org

から「RASPBIAN STRETCH WITH DESKTOP」をダウンロードして dd コマンドで SDに書き込み。 手順はいろんなページに書いてあるので省略します。

記事によってはSDカードのフォーマット操作してますが、ddコマンドで書き込む時にパーティションごと消えるので事前のフォーマット操作は不要です。

あと、こんな落とし穴があるらしいけど jessie 時代の話なので、stretch ではどうなってるか不明ですが、まあ conv=sync オプションもつけて置いたほうが無難そうです。

akkiesoft.hatenablog.jp

電源投入〜デスクトップ表示まで

最近はオートログインで、電源入れただけで一気にデスクトップ表示まで行くんですね。 なにもしなくても pi ユーザーで自動ログインされます。初期パスワードは「raspberry」。

日本語化 + 日本語入力

こちらを参考に設定しました。

deviceplus.jp

Mincraft Pi セットアップ

Scratch2MCPI のインストール

こちらの記事の通り、Scratch と Minecraft Pi の Python I/F をつなぐ Scratch2MCPI をインストールします。

thinkit.co.jp

ローカルネットワーク内のワールド共有

  1. ワールド共有したい Raspberry Pi (最大5台)を同じ LAN 内に接続する
  2. ホストするマシンで Mincraft Pi を起動し、ワールドを作成して動ける状態にしておく
  3. 他のマシンでも Minecraft Pi を起動し、Join Game をクリックして Steve Pi (192.168.xxx.xxx) に接続

4台で接続してワールド共有してみましたが、けっこうサクサク動きます。

Scratch との接続

  1. Minecraft Pi を起動してプレイヤーを動かせる状態で、TAB でカーソル解放
  2. Scratch2MCPI を起動
  3. Scratch でプログラムを書いて実行

特にトラブルなくあっさりうまくいきました。ワールド共有中でもスクリプトは実行可能です。

あそんでみる

さて、小学生3人と一緒に遊んでみました。マイクラができると聞いたとたんテンション爆上がりです(笑) Scratch2 単体の動作は描画が多いと若干カクっとしましたが、Minecraft Pi はかなり軽快に動きます。

イクラ自体ほとんどやったことなかったので、小学生の遊び方を観察したりしてみましたが、マイクラ内で鬼ごっこしたり、石を並べて宝石店を作り出したり、なかなかクリエイティブな遊びかたをするので、これはデジタル版のレゴなんだな〜という感じがします。

Scratch を通してのプログラミングも少し手をつけてみて、プレイヤーを色んな場所にワープさせたり、ブロックを直線に並べてみたりもしましたが、いつも使っている Scratch のインタフェースなので割とスムーズに受け入れてくれました。

ただ、グローバル変数(mcpiX、mcpiY、mcpiZ)に座標をセットしてsetPosなどのコマンド送信、という流れは普通のScratchプログラミングと異なるお作法(アセンブリ言語レジスタに値をセットして命令発行している感じ)なのでちょっと慣れが必要そうです。気軽に並列処理しようとするとメチャクチャになります(笑)

というわけで、しばらくマイクラ+プログラミングで遊んでみようと思います。

プログラミング教室近況

今年2月に開講した「にしのしまデジタルラボ」プログラミング教室は早9ヶ月となり、口コミでメンバーも増え現在は6名が在籍しています。11月初めには地域の文化展にて生徒作品の展示も行うことができました。

f:id:k-aeg:20171128031431j:plain:w400
文化展展示の様子

開講からこれまでは、ミッションカードとオリジナルゲーム制作を中心に授業を進めてきましたが、どうしてもタイピングの遅さがネックになってきたので、今月はタイピング強化月間としてScratchで作ったタイピングゲームでタイムを競い合ったりしています。

競争要素を持ち込むと小学生たちの場外マウンティング合戦(足は俺のほうが速いとか、成績は俺のほうが良いとかw)が始まって少しサツバツとするのがデメリット(?)ですが、かなりモチベーションは高まるようです。競い合った結果、授業時間の90分だけでひらがな入力スピードが3倍くらいになるなど、タイピングのような単純なスキルアップには効果があるようです。

ところで、授業で使っているタイピングゲームのような教材は、生徒がやっていることの延長線上に見えるようになるべく Scratch で作っています。今回のタイピングゲームは1時間程度で完成しましたが、マルチプラットフォーム対応(開発機はMac、生徒PCはLinuxWindows)でこの程度のアプリケーションを同じくらいの学習コスト、制作時間でできる環境って他に案外無いのでは?

f:id:k-aeg:20171128033356p:plain:w400
授業で使っているタイピングゲーム

プロジェクトを公開しているので、以下のリンクからタイピングゲームを遊べます。 scratch.mit.edu

昨今のプログラミング教育において、「教育用言語」と目される Scratch 後をどう他につなげるかという至上命題みたいなものがありますが、Scratch のポテンシャルを十分に引き出すことができれば、(現状では制約が多いものの)かなり有用なツールになり得るという感触があります。JavaScript ベースの Scratch 3.0 がリリースされれば、自由度は高まっていくと思われるので今後どうなるか楽しみです。

ScratchブロックをHTMLで描画する方法

プログラミング教室の教材を作るために Scratch ブロックの画像が欲しかったんですが、いちいちスクリーンショットを撮るのも面倒だし、ラスタ画像ファイルだと解像度の問題で取り回しが不便なので、ベクタ画像出力かつ更新が簡単な方法を探していたらドンピシャのライブラリがありました。

ScratchのWikiやフォーラムでも使われている blob8108 氏作の Block Plugin(scratchblocks)です。このライブラリはブラウザ上で動作するブロック画像ジェネレータとしても公開されていますが、Webページに組み込めば Scratchスクリプトからブロック画像を生成してHTMLにSVGとして埋め込むことができます。

教材の製本も視野に入れると、画像編集ツールを介さずにHTMLで完結できればCSS組版とも相性が良さそうです。

使い方

ライブラリのインクルード

現在の最新バージョンはver3.1なので、以下のJSファイルをインクルードします。

<script src="https://scratchblocks.github.io/js/scratchblocks-v3.1-min.js"></script>

ブロック表記を英語以外(今回は日本語)にするためにはさらに以下の翻訳データをインクルードします。

<script src="https://scratchblocks.github.io/js/translations-v3.1-min.js"></script>
描画

実際に描画してみたサンプルを GitHub Pages で公開しておきました。

https://ag-k.github.io/scratchblocks-html-sample-ja/

サンプルコード全体は以下で参照できます。

https://github.com/ag-k/scratchblocks-html-sample-ja/blob/master/index.html

以下は各描画方法の説明です。

ベーシックな描画方法

HTMLの要素としてScratchスクリプトを記述しておき、scratchblocks.renderMatching() で指定したセレクタに該当する要素をまとめて描画します。 指定するセレクタは自由ですが、preタグだとそのままスクリプトが書けるので便利です。

<pre id="blocks1" class="blocks">
  @greenFlag がクリックされたとき
  x座標を (0) 、y座標を (0) にする
  ずっと
    (10)回繰り返す
      @turnright (10) 度回す
      (5) 歩動かす
    end
    次のコスチュームにする
  end
</pre>
<pre id="blocks2" class="blocks">
  このスプライトがクリックされたとき
  もし <(向き) = [90]> なら
    ペンを下ろす
  でなければ
    ペンを上げる
  end
</pre>
// 'pre.blocks' セレクタで指定された要素をまとめて描画
scratchblocks.renderMatching('pre.blocks', {
  languages: ['ja', 'en'],
  render: function(doc, cb) {
    doc.render(function(svg) {
      var el = document.createElement('div');
      el.appendChild(svg);
      cb(el);
    });
  },
});
インラインで描画

scratchblocks.renderMatching() の第2引数 option に inline: true を指定するとインラインでブロックを描画できます。

scratchblocks.renderMatching() の第2引数 option に inline: true を指定すると、<code class=b>スタンプ</code>のようにインラインでブロックを描画できます。
// インラインで描画
scratchblocks.renderMatching("code.b", {
  languages: ['ja', 'en'],
  inline: true
});
サイズを拡大して描画

今のところブロックが描画サイズは固定になっているようですが、大きくして使いたい場面があったので、描画結果のサイズを変更する方法を考えました。ブロックはSVG形式で描画されるので、Document.render() から取得できるSVG要素を拡大してやれば良さそうなのですが、scratchblocks.renderMatching() に渡した場合、SVG要素のサイズが取得できませんでした(clientWidth, clientHeight, viewBox が0)。

一方、Document.render() を単体で使う場合は SVG要素のサイズが取得できたので、scratchblocks.parse() でスクリプトをパースしたオブジェクトを Document.render() でレンダリングし、結果のSVG要素を指定されたスケールに拡大するようにしました。

<code id="big_blocks">
  @greenFlag がクリックされたとき
  x座標を (0) 、y座標を (0) にする
  ずっと
    (10)回繰り返す
      @turnright (10) 度回す
      (5) 歩動かす
    end
    次のコスチュームにする
  end
</code>
<code id="middle_blocks">
  @greenFlag がクリックされたとき
  x座標を (0) 、y座標を (0) にする
  ずっと
    (10)回繰り返す
      @turnright (10) 度回す
      (5) 歩動かす
    end
    次のコスチュームにする
  end
</code>
<code id="small_blocks">
  @greenFlag がクリックされたとき
  x座標を (0) 、y座標を (0) にする
  ずっと
    (10)回繰り返す
      @turnright (10) 度回す
      (5) 歩動かす
    end
    次のコスチュームにする
  end
</code>
// スケールを変更する場合のブロック描画関数
//   renderMatching()で呼び出される doc.render()ではSVGのサイズが取得できないため、
//   parse() と doc.render() を使用して描画する。
var renderScaledBlocks = function(target, scale) {
  var doc = scratchblocks.parse(target.innerHTML, {
    languages: ['ja', 'en'],
  });
  doc.render(function(svg) {
    target.innerHTML = "";
    target.appendChild(svg);
    //SVGの拡大処理
    svg.setAttribute("width", svg.clientWidth * scale);
    svg.setAttribute("height", svg.clientHeight * scale);
    svg.setAttribute("viewBox", "0 0 " + svg.clientWidth / scale + " " + svg.clientHeight / scale );
  });
};

//各HTML要素に記述したスクリプトを元にブロックを描画
var titleBlocks = document.getElementById('big_blocks');
renderScaledBlocks(titleBlocks, 2.0);
var middleBlocks = document.getElementById('middle_blocks');
renderScaledBlocks(middleBlocks, 1.5);
var smallBlocks = document.getElementById('small_blocks');
renderScaledBlocks(smallBlocks, 1.0);

SVGの拡大方法については以下の記事を参照しました。

ASCII.jp:HTML5のInline SVGをJavaScriptで操作 (2/5)|古籏一浩のJavaScriptラボ

[SVG] viewBoxについての考察

つまづきどころ

  • 画像を含むブロックの入力方法

    これらのブロックはブロック名に画像が含まれているので、文字列で表現する時はエイリアス文字列が設定されています。

    ブロック 日本語スクリプト
    f:id:k-aeg:20170227224919p:plain @greenflag がクリックされたとき
    f:id:k-aeg:20170227225645p:plain @turnright (15) 度回す
    f:id:k-aeg:20170227225720p:plain @turnleft (15) 度回す
  • 日本語に翻訳されていないブロックがある

    「() 回繰り返す」などのループは閉じるコマンド(英語版では「end」)が必要なんですが、日本語に翻訳されていないので、languages に"ja"と"en"の両方を指定した上で「end」と記述する必要があります。

おすすめ作業フロー

HTMLでスクリプト手書きは結構面倒なので、Scratch プロジェクトのブロックからscratchblockのスクリプトを生成するジェネレータを活用するとラクです。以下の手順で作業するのが良さそうです。

  1. Scratchでプロジェクトを作成
  2. ブロックを組んで動作確認
  3. generator :: scratchblocks でScratchプロジェクトをscratchblockスクリプトに変換
  4. scratchblockスクリプトをHTMLに貼り付け

サックスのメンテナンス用リークライトを自作してみる

離島という環境ゆえ、近くに楽器屋さんがありません。 楽器のメンテナンスのたびにフェリーで3時間かけて本土まで行くのも大変なので、簡単なメンテナンスは自分でできるようにしようと思いたちました。

調べた限り、分解&組み立てレベルのサックスメンテナンスに関する日本語の文献はこの本がベスト(というかこれしかない)のようです。

サクソフォン マニュアル 日本語版

サクソフォン マニュアル 日本語版

さっそく買って読んでみましたが、日常のメンテナンスからタンポの交換まで、全ページカラー写真でとても丁寧に書かれていて良書でした。さすがに自力でタンポ交換は無理そうでしたが…。 本書では息漏れチェックの手段として2つ紹介されており、1つは薄い紙で作った隙間ゲージをタンポに挟んで引っ張るというものと、もう1つはリークライトをボアに挿入して光が漏れる場所をチェックするというものです。

後者のリークライトは、LEAK LIGHTSのようなところで買えるのですが、大体$100以上とお高めなので、LEDテープで自作することにしました。作り方は、奥津サックスマウスピース製作さんのブログで紹介されている通りです。

okutsumouthpieces.com

用意するもの

作り方

まずはLEDテープを切り出します。

f:id:k-aeg:20170225150112j:plain

出来上がりの長さは市販品と同じ21インチ(約53cm)にします。半分で折り返してくっつけるので、倍の長さを切り出します。今回使用したLEDテープは5cm間隔で切断可能になっているので、105cmとしました。

f:id:k-aeg:20170225150102j:plain

切断可能な部分は丸い端子が4つ並んでいるところの真ん中の線です。 切断したら、裏面の両面テープを剥がして真ん中で折って貼り合わせます。

f:id:k-aeg:20170225150533j:plain

今回はクリアタイプの熱収縮チューブがなかったので、根本だけ短いチューブで固定することにしました。チューブをLEDテープの根本にかぶせてライターやヒートガン、はんだごてなどで熱を加えて収縮させます。

f:id:k-aeg:20170225151147j:plain

最後に、DCコネクター変換プラグにドライバーで赤線と黒線を接続します。LEDは極性があるので注意が必要です。赤線は+、黒線は−につながないとLEDが壊れます(たぶん)。

f:id:k-aeg:20170225153407j:plain

これで完成です。ACアダプタを接続していざ点灯! ちゃんと尽きました。カメラのホワイトバランスで暗めに写ってますが、肉眼で見ると結構明るいです。

f:id:k-aeg:20170225153528j:plain

サックスに入れてみるとこんな感じになります。

f:id:k-aeg:20170225153815j:plain

総工費としては2000円以下で自作できました。めでたしめでたし。

子供向けプログラミング教室の開講とインターンシップを受け入れた話

今週は、西ノ島デジタルラボと称して子供向けのプログラミング教室を開講したり、近くの高校からインターン生を受け入れるなど、プログラミング教育について色々と知見を得られたので記録しておこうと思います。

プログラミング教室

昨年末から準備を進めていた子供向けプログラミング教室ですが、1月末に申込者があったため2月より開講の運びとなりました。一応「西ノ島デジタルラボ」という名前をつけているのは、今後プログラミング講座以外に、ファブ系(CAD、3Dプリンタ等デジタル工作機)の講座なども展開したいという事と、今は固定の活動場所は無いけれど、将来的にはPCやデジタル工作機などを常設して活動できるような拠点があると良いなーという想いからです。

インフラとしては町内の船越地区の公会堂をお借りして、お古のデスクトップパソコン数台に軽量 Linux を入れて、Scratch のオフラインエディタをインストールして実施しました。ネット環境が無いのがネックですが、データ保存用のUSBメモリを配布したりして、当面はオフラインで進められそうです。第1回の授業はインターン期間と重なったので、会場設営などインターン生に少しお手伝いしてもらいました。

低学年向けの配慮について

そんなわけで、第1回の授業は小学2年生と3年生の2名でのスタートでした。内容としては、ビジュアル言語のScratchを使ってゲームを作ろう、というスタンダードなものです。元々は小学4年生以上という条件で始めようと考えていましたが、低学年の子のほうがプログラミング(というよりゲーム制作?)に興味があるようで、希望者や興味がある層は軒並み低学年の子でした。当初、小学4年生という区切りにしていたのは、主に以下のような理由によります。

  1. 抽象的思考ができるようになる年齢(と言われているらしい)
  2. 低学年の子にとってはマウスやキーボードの操作自体が難しい(以前に実施したプログラミング体験講座での観察から)
  3. 低学年に読めない漢字が多い(教材に配慮が必要)

逆に上記をなんとかできれば、低学年向けにも実施できるだろうということで、せっかく希望者がいるのだしと、挑戦してみることにしました。

実際取り組んでみた結果、

  • 1については、第1回実施時点では内容もそこまで踏み込んでおらず、N数も2なので何とも言えませんが、想定よりもずっと積極的に探究心をもって取り組んでくれているので、経験を積んで土台を固めていくことで壁を乗り越えられるかも、という感触です。

  • 2については、マウスをクリックした時にカーソルがずれてしまったり、アルファベットが読めないのでローマ字が入力できないといった問題になりますが、対策としては子供の手に合うように小さめマウスを用意したり、マウス操作練習のゲームをScratchで作ったり、ローマ字入力表を配布したりしました。ただ、マウス操作は若干ぷるぷるしているものの、操作自体には支障がなかったのでマウス操作練習ゲームの出番はなかったり、アルファベットが読めなくてもローマ字入力表とにらめっこして、象形文字を読むかの如くに該当する文字を見つけ出してタイプしたりと、思ったより適応力が高く杞憂だった部分も多かったです。

  • 3については、プリント教材にはすべてルビを振るようにしました。画面上ではルビは表示されませんが、読めない漢字があっても絵として覚えられるようなので、特に操作のストレスになっている感じは見受けられませんでした。Scratch はすべての表示をひらがなにするモードがあるんですが、全部ひらがなだと逆に読みづらいし、前述のとおり漢字モードでも支障はなさそうなので、そのまま使ってもらっています。

という感じで、このまま継続していけそうな気がしています。

授業の進め方について

まず前提として、このプログラミング教室では何を目指すのかということですが、若年層向けのプログラミング教育の方向性としては大きく分けて以下の2つの方向性があると考えています。

  1. 教養としてのプログラミング
    • プログラミングができるようになることよりも、プログラミングというプロセスを通して論理的思考や創造性、問題解決能力といったものを身につけることを目的とする
  2. 実用としてのプログラミング
    • 職業や趣味として実用的なソフトウェアを制作できる能力を身につけることを目的とする

この教室では基本的にプログラミング自体に興味があることを前提として、2に重きを置いた方向性を目指しています。教養という意味では、今後小学校でも必修化されるプログラミングの授業で扱われるべきかなと思います。ただ、プログラムを書くことそのものは表現の一手段でしかないので、結局はどちらの方向性をとるにしても(プログラムによって動作を指示される対象となる)コンピュータというものの性質や振舞いを理解した上で、

  • どんなことができるのか
  • 何をしたいのか
  • どのようにやるのか

といったことを考えるのが本質なのかなとも思います。プログラミング言語というだけあって、あくまでコンピュータと対話するためのコミュニケーション手段でしかないので、例えば英語だけ勉強しても(言語自体への興味は別として)、肝心の伝えたい情報や欲しい情報がなければ意味がないのと同じです。 というわけで、授業の進め方としては以下の3つのフェーズを繰り返しながら発展させていくイメージです。

  1. 探求フェーズ
    • 自由にプログラムを組みながら、色々な機能を試したり、必要な概念を身につける
  2. 構想フェーズ
    • 紙のワークシートなどを使いながら、どんなものを作るかじっくり考える
  3. 実践フェーズ
    • 考えたものをプログラムとして形にする

初回授業の雑感

初回は探求フェーズということで、自由にプログラムを組んでいきますが、何も無い状態では右も左もわからない状態なので、適当なタイミングでちょっとした課題を出したり、同じ課題を別のやり方で実現してみたり、ということ繰り返しました。探求フェーズでは好奇心を重視して、課題からちょっと逸れたりしてもそのまま続けてもらい、その方向で発展できることがあれば新たに課題を設定することで、枝葉のように多方向に知識や経験を広げていきます。

一方、課題をこなすこと以上に大切なのは、遊ぶ時間をじっくり取ることでした。例えば、移動距離を指定する場所にありえないような大きい数値をいれたらどうなるか?とか、数値にマイナスを2つつけたらどうなるか?など直接課題に関係ないことでも、コンピュータの性質や振舞いを知るのには重要なことです。ただ、同じことを何度も繰り返して無限ループに入ってしまう場合があるので、そういう時には新しい機能や他のやり方のヒントを投下して興味を引きつけるとすんなり抜け出してくれました。

生徒同士の相互作用もなかなか有効に働きました。各々の好奇心ベースで進んでいくので、進んでいく方向も異なりますが、隣の人が自分の知らないことをやっていると真似してみたり、自分が経験したことで隣の人がつまづいていたら教えてあげたり、わからないところを一緒に考えたりというアクションが見られました。 情報の非対称性があることで、それを共有するモチベーションが生まれているようです。何より友達同士で教え合うほうが、先生が直接教えるよりも真剣に受け取っている感じがします(笑)。

インターンシップ受け入れ

話は変わって、隠岐島前地域唯一の高校である隠岐島前高校では、キャリア教育の一環として職業体験を実施しているそうです。今回は一週間のインターンシップ受け入れでした。自分はフリーランスプログラマなので、従業員採用のモチベーションも無ければ、技術職ゆえ手伝ってもらえるような仕事もほとんど無いのですが、隠岐島前地域にはエンジニア志望のインターン先が無いということなので、うちで引き取ってみることにしました。普通は技術職のフリーランスインターンする機会はあまり無いと思うので、ある意味離島ならではという気もします(笑)。

というわけで、せっかくなら色々体験してもらって興味の幅を広げつつ、こちらとしてはプログラミング教育の導入部に関するデータを収集させてもらおうと考えてスケジュールを組みました。

1日目: 業界や仕事内容についてのレクチャー、Scratch 入門 + プログラミング教室手伝い
2日目: Web開発入門(HTML + JavaScript)
3日目: Web開発入門(続き)、3Dプリンタによるお土産製作
4日目: Arduino による電子工作入門
5日目: Unity による3Dゲーム製作入門

本当はメインでやっているスマホアプリ開発も入れたかったのですが、インターン生のデバイスWindows + iPhone だったので、開発環境が無く断念しました。自分で書いたプログラムが手元のデバイスで動くのは結構感動するので、インターン向きの内容ではあるんですが条件がなかなか揃いません。

色々とメニューは用意しましたが、付きっきりになるのは仕事に支障が出るので、教材の評価も兼ねて基本的にはWebページや動画、本などの入門教材で自習してもらうことにしました。

1日目

業界や仕事内容について色々話しましたが、あまり興味はなさそうでした(笑)。まずソフトウェア開発というのがどういうことなのか分からない状態だったので、プログラミングを少しでも体験した後のほうが想像しやすかったかもしれません。 その後はプログラミング教室の手伝いをしてもらうために、スクラッチ2.0アイデアブックという本で予習をしてもらいました。

この本はなかなか良書だったようで、特につまづくところも無くスラスラと読みこなしていました。プログラミング教室の間は Scratch で自由にプログラム書いてもらっていましたが、ちゃんと応用してそれっぽい何か動くものを作っていました。

2日目

2日目はWeb開発入門ということで、ビジュアル言語を卒業して、プログラミング学習サイト ドットインストールの HTML 入門と JavaScript 入門の動画を見ながら自習してもらいました。結論から言うと動画ではほとんど理解に結びつかず、後で動画で説明されていた内容について質問してみてもまったく要領を得ませんでした。

動画教材は「とりあえず何か動くものを自分の手で作る」という体験に主眼が置かれていますが、初学者にとっては言語の基本的な文法などを理解していない状態では、何やっているのか分からずにとりあえず指示に従っているだけで、頭には入りにくいようです。他の言語を1つでも学習していれば、言語の差分で見られるのでスラスラ入ってくると思います。

また、Web上の JavaScript 入門は玉石混交で情報が古かったりということが多々あるため、初学者が自分で最適なページを見つけるのはかなり困難だなと感じました。あと、そもそもの話ですが、最近のデジタルネイティブの人はスマホを使えるけど、PCを使えないという噂を聞いていましたが、せいぜい学校の授業で Word、Excel に触るくらいしか経験がなく、ブラウザとYahoo(のページ)の区別がついてなかったので、噂は本当だということが分かりました(笑)。

まあ結論としては、ブラウザの説明から載っている、その時の最新の JavaScript 入門本を一冊読むというのが初学者にとっては良い選択肢かなと思いました。 ただ、Web開発は HTML/CSS など前提となる知識が色々必要でプログラミング始めるまでの道のりが長いので、最初は Processing などセットアップが容易な言語から始めたほうが良かったかもしれません。

3日目

3日目は前日のWeb開発入門のリカバーで直接講義してみました。ホワイトボードを使いながら変数やら文法やらの説明をして、なんとか FizzBuzz 問題を(半分くらい)自力で解いてもらうところまでは行きました。初学者あるあるですが、エラーメッセージの英語を全然読もうとしない(というか読めない)ので、Webで辞書を引いてちゃんと読むように指導しました。

JavaScript でだいぶ頭が疲れたようなので、午後は3Dプリンタで印刷しておいた活イカ活っちゃんストラップの仕上げ作業を体験してもらいました。ルーターでのバリ取り作業などはわりと無心でできるので、午前の作業とのバランスはとれたと思います(笑)。インターン生が自分で完成させたストラップはお持ち帰りいただきました。

4日目

4日目は趣向を変えて電子工作に取り組みました。この日も懲りずに ドットインストールArduino入門を活用してみました。 こちらはJavaScriptと違ってわりとスムーズにこなしているように見えましたが、ブレッドボード上の配線がどうなっているのかとか、コードの各行が意味するところの理解にはつながらなかったようです。結局かなりアフターフォローを入れつつ、光センサと圧電スピーカーを組合せてテルミンもどきみたいなデバイスができあがりました。

f:id:k-aeg:20170209172119j:plain

本当はこれをユニバーサル基板に移植して、CADでエンクロージャ(箱)を設計して、3Dプリンタでプリントしてミュージックデバイスとして完成させるところまでやれたら良かったんですが、そこまでは今回時間がありませんでした。

でもせっかくなので、後で完成させるつもりです。すでにCADでの設計を終えて箱をプリント済みなので、あとは回路をユニバーサル基板に移植して詰めるだけです(笑)。

5日目

最終日は Unity を使って3Dゲームを作りました。Unity がPCにインストールできないというハプニングがあり、午前中を消費してしまいましたが、こちらは公式のチュートリアルが優秀で、あまり手をかけずに自習できました。

tutorial.unity3d.jp

インターン生がFPS(一人称視点のシューティングゲーム)好きなのもあって、Unity なら比較的簡単に FPS が作れそうという体感を得ると、これまでの開発に比べ俄然やる気が見られました。チュートリアルの途中で時間切れになってしまいましたが、まだ続けたそうだったので、プログラミング教室の小学生もそうでしたが、やはり好奇心駆動開発は強いなと思いました(笑)。

まとめ

一口にプログラミング教育と言っても、プログラミングという行為自体の目的が多様化しているのもあり、どこを目指すのかという方向は教育者側では決められないので、各自の興味をきっかけとしてある程度のレベルまでサポートして、自分で学習できるところまでつないであげるのが教育者としての役目かな、と思いました。

一方で、諸外国ではCS(Computer science: 計算機科学)教育に力点を置いて、プログラミングに限らずコンピュータへの理解を深めようという動きが主流になっているのに対して、日本ではプログラミング教育という行為のみが切り出されてクローズアップされている感があり、コンピュータの本質的な理解に結びつかないのではないかという懸念もあります。コンピュータの可能性を最大限に引き出すには、やはりコンピュータ自体への理解が不可欠です。というわけで、プログラミング教室を名乗ってはいますが、プログラミングをきっかけとしてコンピュータに対する理解を深めるという目的も重視していこうと思います。

と、いきなり話が大きくなったりしてまとまりませんでした(笑)。

ディープラーニングことはじめ

最近はやりの人工知能で注目されているディープラーニングですが、どんなものか良く知らなかったので本を一冊読んでみました。

TensorFlowなどのフレームワークをいきなり触るのはなんだか難しそうだなー、と思っていたところに「ゼロから作る」というコンセプトの本を見つけたので手に取りました。結論から言うとわかりやすくて良い本だったので、入門にはおすすめです。

読んでみて理解したことを備忘録として羅列しておきます。

必要な前提知識

数学

数学の知識としては行列と微分が分かればOKという感じです。行列や微分の定義についてもちゃんと説明されているので、なんとなく分かってる程度でも読み進めることはできます。そこそこ数式も出てきますが、Python のコードを動かしながら進んでいくのでそんなに躓くことはありませんでした。

プログラミング言語(Python)

Python はほとんど使ったことないですが、演算や関数の定義などから説明があるので、他の言語をかじっていれば問題ないレベルです。 多次元配列や行列の計算には NumPy という数値計算ライブラリを使うので、ややこしい演算などはライブラリ側でやってくれます。

理解できたこと

自分が理解した内容の覚書なので、間違っているところもあるかもしれません。 本ではもう少しアルゴリズムの実装寄りの話が詳細に説明されており、実際にコードを動かして手元で確認しながら進みます。

パーセプトロン

ニューラルネットワークのもととなるアルゴリズム。 以下の特徴がある。

  • 複数の信号を入力として受け取り1つの信号を出力する
  • 信号の総和がある閾値を超えると発火(=1を出力)
  • 入力信号に重みバイアスというパラメータを設定
    重み
    各入力信号の重要性をコントロールするパラメータで。各入力信号にそれぞれの重みを乗算する。
    バイアス
    ニューロンの発火しやすさをコントロールするパラメータ。重みを乗算した入力信号の総和にバイアスを加算する。
  • 重みとバイアスを調整することで AND、NAND、ORのような単純な論理回路を表現できる

単層のパーセプトロンでは非線形な表現(XORゲートなど)ができない。
パーセプトロンを重ねることで非線形表現ができる

ニューラルネットワーク = 多層パーセプトロン

パーセプトロンの出力を次のパーセプトロンの入力信号とすることで、多層化することができる(多層パーセプトロン)。 多層化により、XORゲートなどの非線形表現が可能になる。 ニューラルネットワークは多層パーセプトロンとほぼ同じで、以下の特徴を持つ。

  • 入力層、中間層(隠れ層)、出力層に分類される層からなるニューロンのネットワーク
  • 各層には複数のニューロンが存在し、入力層〜中間層(1層以上)〜出力層の順に信号を伝達する(順方向伝播)
  • ある層の各ニューロンが出力する信号は、次の層の各ニューロンの入力となる
    • 例えば、ある層に存在する2つのニューロンの各出力(x1, x2)と重み(w)の和にバイアス(b)を足した値が、次層の3つのニューロン(y1, y2, y3)にそれぞれ伝播する
    • ニューロンから次層のニューロンへの各経路には、それぞれ異なる重みを設定する
    • 重み付き入力信号とバイアスの総和には活性化関数(h)を適用する
    • x1 → y1、x1 → y2 などの経路ごとに重みが違うため、y1, y2, y3 のニューロンへの入力はそれぞれ異なった値となる
      • y1 = h(x1 * (x1 → y1の重み) + x2 * (x2 → y1の重み) + b)
      • y2 = h(x1 * (x1 → y2の重み) + x2 * (x2 → y2の重み) + b)
      • y3 = h(x1 * (x1 → y3の重み) + x2 * (x2 → y3の重み) + b)
  • 活性化関数 入力信号の総和を出力信号に変換する関数 = 活性化関数 → 閾値を境にして出力が切り替わる性質を持ち、非線形関数である必要がある

出力層の設計

機械学習は分類問題と回帰問題に大別されるが、ニューラルネットワークはどちらにも使える。 出力層の活性化関数は問題に合わせて使い分ける必要がある。

  • 出力層の活性化関数
    • 恒等関数 → 回帰問題
    • シグモイド関数 → 2クラス分類問題
    • ソフトマックス関数 → 多クラス分類問題
      • 出力の総和が1になる = 確率として解釈可能
      • 出力層のニューロン数 = 分類したいクラスの数

ニューラルネットワークの推論(順方向伝播)

MNIST データセットを例に推論処理を実装する。

  • MNIST データセット
    • 0ら9までの手書きの数字画像
    • 訓練画像60000枚、テスト画像10000枚を含む
    • 画像データは 28 x 28 のグレー画像(256階調)
    • 各画像には対応するラベルが与えられている

ニューラルネットワークの設計は以下のようにする。

  • 前処理
    • ピクセルの値を 255 で除算(0.0〜1.0の範囲に正規化)
  • 入力層
  • 中間層(隠れ層)
    • 層の数やニューロン数は任意
      • 2つの隠れ層で、1層目が50個、2層目が100個、など
  • 出力層
    • ニューロン数 = 分類するクラス数
      • 10クラス(数字の0から9)に分類 = 10個
  • バッチ処理
    • NumPyなどの数値計算ライブラリは配列の計算を効率良く処理できるように最適化されている
      • 入力データをまとめて処理(バッチ処理)すると効率が良い
      • 入力データから100枚ずつ取り出してNumPy配列として処理する(NumPy配列の演算は配列のすべての値に適用される)

ニューラルネットワークの学習

特徴量 + 機械学習のアプローチでは問題に応じた(人力での)特徴量の設定が必要だが、ニューラルネットワークでは特徴量も機械が学習する。 ニューラルネットワークでは損失関数の値が小さくなるように最適なパラメータ(重みとバイアス)を探索する。

ニューラルネットワークでは、パラメータ解空間の探索方法として勾配法(確率的勾配降下法 = SGD)がよく用いられる。

  • 勾配法
    1. 偏微分により現在のパラメータにおける損失関数の勾配を求めて、最小値の方向を予測する
    2. 勾配から予測した最小値の方向へパラメータを更新する(移動する量 = 学習率)
    3. 1と2を繰り返して最小値へ向かって降下しながら、最小値を探索する

ただし、勾配が指す方向に必ず最小値があるとは限らない(極小値の可能性が高い)。 また、数値微分による勾配の計算は非常に時間がかかる。
誤差逆伝播(バックプロパゲーション)による勾配算出の高速化

誤差逆伝播法については、簡潔に説明するのが難しいので省略しますが、数値微分より大幅に少ない計算で勾配を算出できます。
本では一章丸々使って、計算グラフという表現方法で説明されています。

学習のテクニック
  • パラメータの更新方法
    パラメータの更新方法は学習の効率に大きく影響する。
    • SGD
      • シンプルだが関数の形状によっては探索が非効率
    • Momentum
      • 物理法則に従ってパラメータの移動場所を決める(お椀にボールを転がすイメージ)
    • AdaGrad
      • 学習率を徐々に減衰させる
    • Adam
      • Momentum + AdaGrad
  • 重みパラメータの初期値
    重みパラメータの初期値はモデルの表現力や学習の効率に大きく影響する。
    • Xavier の初期値
    • He の初期値
      • 活性化関数が ReLU の場合に特化した初期値
  • 過学習対策(正則化)
    • Weight decay(荷重減衰)
      • 大きな重みに対してペナルティを課す
    • Dropout
      • 訓練時に隠れ層のニューロンをランダムに消去しながら学習する
      • 実質的に複数のモデルに個別に学習させた平均をとることと同義なので、アンサンブル学習に類似
  • Batch Normalization
    • 2015年に提案された新しい手法
      • 学習の効率が良い
      • 初期値に依存しにくい
      • 過学習の抑制
    • 重みのパラメータの分布を強制的に分散させる
      • 活性化関数の前か後にデータ分布の正規化処理を行う
  • ハイパーパラメータの検証と最適化
    • 自動で学習できない(手動で設定する必要がある)パラメータ = ハイパーパラメータ
      • 各層のニューロン
      • バッチサイズ
      • パラメータ更新の学習率
      • Weight decay 係数
      • その他手法に応じて設定が必要なもの
    • 検証方法
      • ハイパーパラメータがテストデータに対して過学習を起こさないように、ハイパーパラメータ調整用の検証データを用意して検証
        • 訓練データから一部分離するなどして検証データを用意しておく
    • 最適化方法
      • ハイパーパラメータはモデルの認識精度で評価する
      • 試行を繰り返しながら良い値の範囲を絞り込んでいく
畳み込みニューラルネットワーク(CNN)

前述のニューラルネットワークでは全結合層を用いていたため、データの形状は無視されていた。 CNN ではデータの形状を維持する畳み込み層とプーリング層が追加される。 多段の畳み込み層では、前層の情報を元に段階的に高度な情報を認識することができるため、画像認識等の精度が向上する。

  • 畳み込み層

    • 入力データに対してフィルターを適用する
      • 入力データとフィルターの要素を乗算して和を求める(積和演算)
      • 3次元データ(奥行き = チャンネル方向が存在する)の場合、チャンネル毎に畳み込み演算した後、結果を合算して1つの出力を得る(チャンネルは1つになる)
    • パディング
      • 入力データの周囲に固定データを埋め込むことで、出力サイズを調整する
      • パディングを大きくすると出力サイズは大きくなる
    • ストライド
      • フィルターを適用する位置の間隔
      • ストライドを大きくすると出力サイズは小さくなる
  • プーリング層

    • 学習するパラメータがない
    • チャンネル数が変化しない

ディープラーニング(= 多層構造のニューラルネットワーク)

層を深くした多層構造のニューラルネットワークディープラーニングと呼ばれている。

  • 層を深くする意味
    • 理論的にはあまり分かっていないが、実践的には意味のある結果が出ている
      • (コンペティションの結果から)層が深まるほど認識精度が向上している
      • 層を深くすることで、パラメータ数を少なくできる
      • 層を深くすることで、学習データを少なくできる(=学習が高速化する)  
  • ディープラーニングの実装

  • 高速化

  • 実用例

    • 物体検出
      • R-CNN
    • セグメンテーション
      • FCN (Fully Convolutional Network)
    • 画像キャプション生成
      • NIC (Neural Image Caption) = Deep CNN + RNN (Recurrent Neural Network)
    • 画像スタイル変換
    • 画像生成
      • DCGAN (Deep Convolutional Generative Adversarial Network)
    • 自動運転
      • SegNet
    • Deep Q-Network (強化学習)