2018年11月28日水曜日

自動運転・電動化・カーシェアが流行るのエネルギー問題に帰着する説

すべてがエネルギー問題になる。

仕事がなくなるのは自動運転のせいではなくカーシェアのせい


本日公開されたニュースによると、GMが管理職を25%, 従業員を15%減らし5つも工場を減らすらしいです。


もちろんGMだけの問題ではありません。
自動車業界ではこれから同じことが各社で起きる可能性があります。
めちゃめちゃ職を失う人が出るわけですが、これは自動運転のせいなのでしょうか。


こんな記事流行りましたね。
たしかに今回の変革は「自動運転にフォーカスするため」と書いています。
が、だったら5つも工場を閉じるのは話が飛びすぎです。

自動運転によってカーシェアが普及する
→車の台数が減るから工場を減らす
→ビジネスモデルが変わるから既存ビジネスの社員減らす

なわけです。

でもカーシェアなんてそんな普及しないっしょ、と思っている方のために次で深堀りします。

カーシェアはエネルギー問題の一つの解決策


前章で「自動運転によってカーシェアが普及する」と書きましたが、厳密には違います。
そもそも今大して自動運転存在しないのにカーシェア普及し始めてますし。

カーシェアが普及すると、

  1. ユーザーが便利: 維持費なく新しい車に必要なだけ乗れる
  2. ユーザーが快適: 車の総数が減るので渋滞も減るし駐車場もガラガラになる
  3. 国が嬉しい: 渋滞、排ガスによる経済的損失が減る←重要

そう、エネルギー問題解決に貢献するのです。国的にはこれ大事。



消費を減らしゴミを減らす。

消費を減らすための一つの答えがカーシェアであり、それを加速するのが自動運転。
そしてゴミを減らすためにガソリン脱却・電動化が求められる。

この清く、正しい考えにより多くの人が失業するわけです。

仕事は増える


とはいえ、消費を減らしてゴミを減らすのは簡単ではないです。

例えばご飯。
ファミレスではメニュー通り料理が提供されますが、毎日大量の残飯が捨てられています。
客の空腹度が数値化できれば料理の量をカスタマイズできます。


例えば電気。
誰もいないオフィスの電気は自動で消せるし、昼の消費量ピーク時は電気代を上げて昼休みをシフトさせたり。

モノづくりよりシステムづくりが増えるだけで、仕事は増えると思いますよ。
という説を提唱する者でした。

おしまい。

2018年10月22日月曜日

[Python] いまさら聞けない「ローパスフィルタ」の基礎

フーリエとかラプラスなんて知らないよ。。
周波数領域?ふーん。なるほどー。(移動平均でいいじゃん。)
そんな方向けにローパスフィルタについてまとめてみます。

まずはフーリエ変換の雰囲気をつかむ


ローパスフィルタを知るにはまず「フーリエ変換」を(雰囲気だけでも)知っておく必要があります。
ネットで調べれば下の図のような説明は多く見かけるでしょう。
しかし物事を理解するには歴史、背景、目的みたいなものを多少でも知ることが大事だと思うのです。


フーリエ変換 = 時系列信号を周波数成分(sin波)に分解する変換

ですが、そもそもなぜこんな変換を昔の人はしたかったのか。
その起源は波動にあります。

例えば音。子供しか聞こえないモスキート音は「周波数が高い」。
あるいは光。紫外線は「波長が短い」。
ラジオなど無線にも「周波数帯」なるものがある。


この世のいろんな信号は「波」に変換され「周波数」なるもので表現されています。
この世のあらゆる信号は波に変換できる(仮)。その変換こそがフーリエ変換なわけで。


上のgifは少し前にtwitterで回ってました。
いろんな周期の波を足せばどんな信号も表現できるのです。

こうして信号をフーリエ変換すると、どの周波数がどれだけ含まれているか、というヒストグラムが出ます。

左を時間領域、右を周波数領域、と表現したりもします。
ではなぜこんな変換をするのか。答えは「ノイズ」です。

一番わかりやすいのは音。イヤホンやラジオの音質は大事ですよね。
あるいは光。UVカットサングラス、はどうやってカットしてるんでしょう??

欲しい信号だけ通して、いらない信号はカットする。それが「フィルタ」であり、
例えば高い周波数のノイズをカットするのが「ローパスフィルタ」なわけです。

次に伝達関数の雰囲気をつかむ


このフーリエ変換、制御的にとても嬉しい点が一つあります。
それは、周波数領域は時間に依存しない表現ができること。
つまり定常状態を表現できるわけです!


例えば車のハンドルを右に切った時。
車がどれくらい遅れて、どれくらい右に動くかを一つの数式で表現できます。

これって実はめちゃめちゃすごいことで、
本当はハンドルを切る時間とか量によって時間領域の信号は毎回違うわけです。
でもそんなの関係ねぇ!という物理的なモデル構築がフーリエ様によって可能になったわけです。


一つの数式(=モデル=伝達関数)で、ハンドルから車までを表現できる。
フーリエ変換のおかげでモデルベース制御なるものが生まれたわけですね。
(雰囲気説明なので多少の誤りはお許しを)

ローパスフィルタの伝達関数


ローパスフィルタはwikipediaを見ての通り、電気系が起源です。
電気信号はとにかくノイズ(高い周波数の不要な信号)が多いので、それを除去したいと。
以下にローパスフィルタの伝達関数を示します。


この図のτ(タウ)を時定数とか呼びます。
時定数の逆数をcut-off frequency(遮断周波数)とか呼びます。
とかそんなことはどうでもよくて。

大事なのは上図の下側、等価変換です。
伝達関数を書けても実装できなければつまらない。
実装しやすくするために伝達関数を変換することも時には必要なのです。

上図を式にするとoutput = input / (1+sτ)
output * (1+sτ) = input
output = (input - output) / sτ

という具合に等価変換できます。
1/sは時間領域では積分に相当するので、これで実装はかなり簡単になりました。


1/sが積分?なぜ??という方はぜひラプラス変換をもっと勉強してみましょう。
そんなわけでローパスフィルタをpythonで実装すると...


一行で完結。

output = (input - output) / sτ
cut_f = 1/τなので cut_f * (input - output)を積分しています。

積分ってそうやって実装するの?という方は下図を見て納得しましょう。
(もちろん他にも実装方法はあります)


おわりに


知人に「ローパスとは」って聞かれて参考リンクでも送ろうと思ってググったら、けっこう敷居の高い記事が多いんですね。社会人になってから知らない分野を勉強するのってやっぱ大変なんだなぁ。自分もちゃんと手計算で等価変換とかしたのは院生になってからだし。ちなみにハイパスはsτ/(1+sτ)でローパスと足すと1になるんですよ。

おしまい。

2018年9月19日水曜日

Pythonで緯度経度をXY座標に変換する方法はいくつかあるらしい

異なる手法で試して値が一致しなくて困惑したのでまとめておきます。

緯度経度をXY座標に変換する


このテーマ自体は調べたら下記二つ分かりやすい記事がありました。


しかし以下のStack Exchangeを試して混乱の時間が始まったのです...
Convert GPS coordinates to Web Mercator EPSG: 3857 using python/pyproj


(メルカトル法で計算した値とpyprojで出てくる値が違うぞ...)

ただ結論から言うと、違ってOKのようですね。
まずはメルカトル法から見ていきます。

Spherical Pseudo-Mercator projection (長い)


Open Street Mapのwikiにpythonコード載ってました。すばらし。
ただこれだと不完全で、上記のStack ExchangeやBokehブログでは地球の半径を基にスケーリングしてます。

何をやっているかというと、
地球を完全な球と仮定して、地球を風呂敷のように広げてX, Yに変換しているイメージです。
これで世界中どこでもX, Yが得られますが、とても簡単で大雑把な仮定なので精度がイマイチというウワサ。

EPSG-based projection


一方最初の記事のEPSGコードに基づく変換は、地球を細かく区切ってエリアごとに風呂敷を広げるイメージ。
そのため、

  • 精度は前のやつより良い
  • エリアごとにEPSGコードが違う
  • 始点(X=Y=0)の位置もエリアごとに違う

というわけでした。そりゃ値違うわ。

さいごに


pythonのコードはGithubで公開してます。
(わざわざレポジトリ作るまでもなかったか。。。)
おしまい。

2018年8月26日日曜日

自動運転をめぐる"思想"

安全重視かお金重視か。自動運転実現に向けた思想の話をします。


自動運転は二つある


自動運転と聞いて最初に思い浮かべる会社はどこでしょうか。
最先端っぽいGoogleか、2018年5月に事故を起こして話題になったUberか
話題性盛りだくさんのTeslaか、バスを方々で走らせているSBDriveか


他にも自動車メーカー、ITメーカー、Startupなどたくさんあります。

昨今のニュースではなんでもかんでも「自動運転」。
しかも「レベル3」とか「レベル5」とか、レベル付けまでされています。


しかし正直、レベル付けなんてどうでもよくて
あなたは安全重視か、それともお金重視か
というところがとっても大事です。

設計思想が全く違う


安全重視というのは、以下のような機能を載せた自動運転。(レベルで言うと0~2)
この派閥の人達はどうすれば事故を減らせるかに興味があります。

  • 緊急ブレーキ・レーン逸脱防止のようにドライバーのミスを補う機能
  • レーン維持などドライバーの負荷を減らす機能 

一方お金重視は、バスやカーシェアを使った新しいビジネスを狙った完全自動運転。(レベル4~5)
この派閥の人達はどうすればお金が稼げるかに興味があります。

  • 公共交通のない地方の新しい交通手段
  • シャトルバスの無人化
  • 配車・駐車を自動化し効率化されたカーシェア
    (空車の場合は駐車する、ユーザーの家の前まで迎えに行く、など)


この二つの自動運転がどれくらい違うかをスターウォーズで例えると、
ドロイドとクローンくらい違います。


ドロイドはジェダイの戦闘機操縦を助けてくれます。
いろんな情報も教えてくれます。人間にはできないデータ処理もします。
クローン兵はタイファイターの出撃から帰還まで完璧にこなすことができます。

しかし目的が違う以上、二つは異なる進化を遂げます。
ドロイドがクローン兵になることは何年かかってもないです。

そう、この二つの自動運転、全く違うんです。

クローン兵(Chauffeur) vs ドロイド(Guardian)

この思想は基本的に相容れない宗派のようなものです。

安全重視というのは中々に茨の道です。毎日何百万台も作る車には当然機械としての誤差が産まれます。乗り手もさまざまな運転をします。年に数回しか運転しないようなドライバーもいれば、毎日運転するドライバーもいて、どちらも必ず事故を起こします。速度制限なんて概ね守られていません。(例: 左折時徐行してる車なんて半分もいない)

安全機能なんて保険と同じようなもので、ビジネスとしてめちゃめちゃ儲かるものでもないはずです。それでも事故を減らしたい、そういう人達がGuardian派になるわけです。


一方お金重視(Chauffeur派)はリスクは少ないです。何百万台もいきなり作るわけでもないし、ビジネスモデルさえ確立すればセンサーはいくらでもつけられる。初期投資にお金をかけられます。乗用車やトラックの価格が今の倍になるとなれば大騒ぎですが、ロボットカーが何百万円してもそんなに気にする必要がないのです。

自動運転は技術的に成熟してきている、と信じている人はこのChauffeur派になりやすいです。私はGuardian派で、無事故達成できればChauffeur派に転身予定です。


以上を踏まえて、自動運転のレベルを2派に分類するとこうなります。


市販の車は概ね安全派に分類され、お金派はそれらと全く異なるセンサーや車でLevel 4を実現します。が、双方を兼ね備えるLevel 3とか、どこでも完全Level 5なんてものは未来永劫登場しないと思っています。今後ニュースで出てくるLevel 3は全てLevel 2に分類できるでしょう。

さいごに

もし自動運転に携わりたいエンジニアがここまで読んだ場合、この派閥はよく考慮して就職活動をすると良いです。R2D2派は自動車メーカーや部品メーカー、クローン兵派はIT企業に行くとマッチング率高いと思います。思想強めな投稿でした、おしまい。

2018年8月6日月曜日

Ubuntuでログインループにハマる2つの理由

Ubuntu (nvidia GPU使用) PCを新規にセットアップしようとすると毎回ハマるので一旦まとめてみます。
(English Instruction is available in github issue)

はじめに  


パスワードを入れるとまたログイン画面に帰ってくる現象、その名もログインループ。


今まではコンソールからログイン(Ctl + Alt + F1)してから
Ubuntuアップデートしたらログインできなくなった(nvidia GPU使用)の通りnvidiaドライバをダウングレード:

sudo dpkg -l | grep nvidia
sudo add-apt-repository ppa:xorg-edgers/ppa
sudo apt-get update
sudo apt-cache search 'nvidia-[0-9]+$'
sudo apt-get install nvidia-352

すればうまくいっていたが、、、今回はsecure bootがオンになっていることが原因でした。

Secure bootをオフにする 


1. まずはコンソールからログイン(Ctrl + Alt + F1)してmodprobe

sudo modprobe nvidia

これで
  • 何も表示されなければsecure bootはオフ (勝ち)
  • Required key not availableと表示されたらsecure bootがオン (2へ進む)

2. オフにするにはPC起動時にF2だかF10だかを連打してこんな画面へ移動 
(参考: Disabling Secure Boot )


3. Bootタブに移動してsecure bootを設定する画面にいければ勝ち確定。
  1. Secure bootをDisabledで選択する
  2. OS TypeをWindows UEFI modeからOther OSに変更する
の2パターンあります(私は後者でした)
おしまい。

(おまけ: ブログでのコマンドラインの説明をおしゃれにキメる)


2018年7月9日月曜日

Windows 7(+GPU)でSSD-Keras動かしてみる

今時はWindows 10なブログが多いですが、Windows 7(+GPU)でDeep Learningしたかったのでそのまとめです。

はじめに


歩行者検知といえばDeep Learning, YOLOかSSDといえばSSDでしょ、という昨今。
今回はKeras (backendはtensorflow)でSSDというこちらを動かします。

環境構築

Python + Tensorflow + Kerasの基本環境はminicondaベースで入れました。
Udacity Nanodegreeのものをベースに色々アップグレードしていきます。

  • Tensorflow: 1.8
  • Keras: 2.1.6
  • Numpy: 1.14.3
  • Beautiful Soup: 4.6.0

GPUない人はこれだけでSSD-Keras動かせますが、GPUある人はもう少し作業が必要です。
ちなみにGPUありなしはデバイスマネージャーで見れます。


GPUある人はcuda9.0cudnn7.0.5 for CUDA 9.0を入れます。
(最新版のcuda9.2とcudnn7.1では動かなかったです)


テスト


あとは

  1. モデルダウンロードして
  2. Jupyter notebook起動して
  3. SSD300_inference.ipynb開けば

動かせます。次は噂のBDD100kとか使って転移学習でもします。
おしまい。

(2018/07/10 追記)
動画およびUSBカメラのパイプラインも書きました

参考

2018年5月20日日曜日

【Python x OpenCV】道路標識のデータセットを拡張

AI(機械学習, 深層学習, ディープラーニング, ニューラルネットワーク)を使って道路標識を分類したい時に使うデータ拡張の備忘録。

データセット拡張 (data augmentation)


ニューラルネットワークで必要になるトレーニング用のデータセット。

German Traffic Sign Datasetの様に枚数があれば良いのですが、
現実には整備済みデータセットはまだまだ少ないというのが現状です。。

そこで必要になるのがデータの水増し。
人工的にデータ増やしてしまおう作戦です。既に


など分かりやすい解説はあるので、

  1. 左右反転
  2. 明るさチェンジ
  3. 上下左右にシフト

の3つのopencvバージョンでも紹介します。
コードはこちらからどうぞ。

1. 左右反転


opencvでの左右反転は
flipped = cv2.flip(img,1)
の一行でおしまいです。1は反転方向を左右に指定してるだけです。ちょろい。

2. 明るさチェンジ


def change_brightness(image):
    image1 = cv2.cvtColor(image,cv2.COLOR_RGB2HSV)
    image1 = np.array(image1, dtype = np.float64)
    # can be changed the brightness at here (currently 2.0)
    random_bright = 2.0 #+np.random.uniform()*.4 
    image1[:,:,2] = image1[:,:,2]*random_bright
    image1[:,:,2][image1[:,:,2]>255]  = 255
    image1 = np.array(image1, dtype = np.uint8)
    image1 = cv2.cvtColor(image1,cv2.COLOR_HSV2RGB)
    return image1

rgb空間だと明るさ変えられないのでhsv空間に変換してからゲインかけてるだけです。
2.0のところを小さくすれば暗くなりますし、ランダムにもできます。ちょろい。

3. 上下左右にシフト


def shift(image,trans_range):
    rows,cols = image.shape[0:2]
    # Translation
    tr_x = trans_range*np.random.uniform()-trans_range/2
    tr_y = trans_range*np.random.uniform()-trans_range/2
    #tr_y = 0
    Trans_M = np.float32([[1,0,tr_x],[0,1,tr_y]])
    image_tr = cv2.warpAffine(image,Trans_M,(cols,rows))
    return image_tr

x, y方向にtrans_rangeに応じたピクセル数だけずらしてるだけです。ちょろい。

ということで、結果はこちら。


関数にしとくとシフトと明るさチェンジの両方適用したりが簡単です。
手前方向に回転(ワープ処理)とかは気が向いたら実装します。

おしまい。

2018年4月1日日曜日

危険な交差点を見つけたのでデータあげた話

おじいちゃんドライバーに轢かれそうになったので激昂しかけたけど、よくよく調べると交差点に問題がある気がしたので方々にデータ上げた話でも書きます。

轢かれそうになった交差点


下記Google street viewの道を直進しようとしたら右から猛スピードでおじいちゃん軽が突っ込んできました。



その時はおじいちゃんに毒づいて終わりでしたが、おじいちゃん側が走ってきた道を見てみると中々の難易度であることが判明。



この電柱の左と草の右に道があって交差点になってるんだけど、初見で分かる人いるんですかね、これ。

一応僕側(東→西で交差点進入側)には止まれ標識あります。



しかしおじいちゃん側(北→南で交差点進入)には何の情報もありません。
せめて止まれ標識か停止線があれば自動運転的にもなんとかできるけど、現状は無理ゲーすぎるので4ヶ所に情報あげました。

  1. 警察: webページからメール
  2. 土木事務所: 区のwebページからメール
  3. Safety Map: Hondaが提供している交通安全用地図
  4. Mapillary: Street Viewの全員参加型バージョン

1, 2の反応が悪い場合は先人のように区役所行ってみます。
(参考:「危ない道路」の改善を求めてみたら、意外にすんなり対応してくれた件)

3のSafety Mapはまぁ備忘録的な位置付けなんですが、4のMapillaryは今回初めて見つけました。

Mapillary


ただの画像共有サービスかと思いきや、semantic segmentationがサービスに含まれてたり、データセットも公開してたり、標識認識やその結果をマップ上に重ねるとこまで提供してたり。

すごいぞ、これ。
今まで横断歩道をラベリングしたデータセット全然なかったし。

次回、横断歩道検知、5月中に投稿!(自戒)
おわり。

2018年3月15日木曜日

Dempster Shafer Theory (DST)とかいうやつ

日本語の分かりやすい説明が見当たらないので少し考えてみました(合っているかは保証しません)。

Dempster Shafer Theory (DST)を3行で


Wikiに書いてありますが、ざっくりまとめると
  • ベイズの拡張(一般化)バージョン
  • ベイズよりあいまいさに寛容
  • いろんなデータをfusionするの得意


みたいです。ベイズに関してはWiki含めたくさん解説記事あるのでそちらに任せます。

ベイズの拡張(一般化)バージョン?


例えばベイズのwikiにクッキーの例がありますが、ベイズでは全ての事柄に確率が存在します。ボウル1からプレーンクッキーが出る確率、ボウル2を選ぶ確率、なんでもかんでも確率です。しかし、そんなになんでも確率を計算できるのでしょうか?いくつかイジワルな質問を並べます。

  • ボウルの中でクッキーが割れている確率は?
  • 知らない間に誰かがクッキーを食べていた確率は?
  • クッキーが湿気でくっついている確率は?

これらは極端な例ですが、要はあらゆる事象に確率を付与するのは現実的ではない、という話です。

分からないものは分からない、それでいいじゃないか。
いろんな事柄に重みをつけてミックスして尤もらしい情報を計算しようよ。

こうしてDSTは産まれたのです(適当)。

ベイズよりあいまいさに寛容?


ベイズの定理でググると、P(A)だのP(B)だの出てきます。
ベイズさんはAである確率、Bである確率、みたいな感じでなんでも確率を付与したがります。


でもAかBか分からない場合もあるし、AとB両方だったりAでもBでもない可能性もあるわけです。
これがCとかDとか増えると更にわけわからなくなります。

例えば、家に帰って自分のプリンが冷蔵庫から消えていた時。
家には父、母、妹の3人の容疑者がいます。


父は甘いものが嫌い、母は真面目、妹は前科があるとします。
ベイズ的に考えると圧倒的に妹が不利な条件ですが、DSTはもう少し寛容です。

そもそもプリンは本当に誰かが食べたのか?
もしかしたら誰も食べてなくて移動されただけかもしれない。
間違えて母が捨てたのかもしれない。
自分の記憶違いでもう食べたんじゃないか?

などなど、あらゆる可能性を考えるのですぐに妹に攻撃はしません。

DSTのような大人でありたいものですね(適当)。

いろんなデータをfusionするの得意?


さて、そろそろ真面目な話をすると、ベイズやDSTはoccupancy gridなどでよく使われます。


移動ロボット、自動運転などで障害物の位置を計測・記憶しておくアレです。

ここでノイズのないセンサ1個で障害物を探す場合はベイズさんで余裕ですが、現実はそんなことはありません。
カメラ、レーダー、ライダー、いろんなセンサのいろんな不確定要素を考慮した上で1つのoccupancy gridを算出するのは結構大変です。

そんないろんなセンサ情報をfusionする、いわゆるsensor fusionにおいてDSTは活躍します。


DSTのwikiにも書いてありますがあらゆるセンサの時系列情報を累積的に取り込むので、全センサ情報を有効活用しますよ、という懐の深さを持っています。
(ただ当然DSTの方が複雑かつ計算コストは増えます)

おわりに


以上、いまいち分かりづらいDSTを噛み砕いてみましたが、簡略化しすぎてそんなに正確な説明ではありません。
DST面白そうやん、と思った方は気合を入れてwikiを読むことをオススメします。
(codingはIn Progressです、またいずれ。。。)

おわり。