Stimulator

機械学習とか好きな技術話とかエンジニア的な話とかを書く

MANABIYAで「AI屋さんの1日」なるタイトルで登壇した話とその内容

- はじめに -

以下、MANABIYA techなるイベント内のAIセッションにて登壇させて頂きました。

manabiya.tech

大きなスペースでフザけたタイトルで発表するという最悪さでしたが、満員になり立ち見状態でした。
ありがとうございました。


正当な方向性でいけば登壇スライドを公開して終わりなのですが、会社のアカウントでSlideShareにアップロードするという行為に宗教上耐えきれそうにないため、会社情報を含まない範囲でここに思い出と共に書き残す形にしようかと思います。


 

- 登壇内容 -

登壇では、以下3つをテーマに話をしました。

  • AI屋さんの定義、分類は?

  • 実際AI屋さんって何やってるの?

  • 上手くAIプロジェクトを回すには?

 

AI屋さんの定義と分類

AI屋さんとは、「セッションタイトルが ‘AI’ だったので私が仕方なく付けた名称」です。

そもそも私は、機械学習や統計モデルを少々取り入れて「AI技術」だとか「人工知能技術」「AI企業」「AI部門」と声高らかに語る団体は全て嫌いです。


2012年頃から日本にも「人工知能、AIブーム」と一般的に呼ばれる"波"が来ました。

2016年後頃になると、ブーム自体が一般的に広く認知され、多くの企業が「我が社もAIをやっている」等と言うようになりました。ちょうど認知されていくタイミングと私が就職活動に勤しんでいた時期が重なり「私は機械学習がやりたいだけだ!人工知能、AIという単語を出した企業は全部こちらからお断りだ!」と躍起になっていたのを今でも覚えています。


それから数年、人工知能、AI、データサイエンティスト、機械学習エンジニアといった単語が広く普及した今になってそれらから逃れ仕事をするというのは、現代で「そもそもオタクの語源は〜」と語りながらオタクを続ける程に生きづらいでしょう。

セッションでは、生きづらい人生の歩み方を否定している訳ではなく「こうなったら言葉を潤滑油として利用してやろう」という方向性で、それぞれの言葉を実務に埋め込みながらAI屋の仕事を詳しく世に広める話をつらつら行いました。


f:id:vaaaaaanquish:20180324172357p:plain
登壇スライドより AI屋さんの分類

最初に上記の図で、AI屋の仕事というのは以下の3つに分かれる話をしました。

この分類で大事な点は「それぞれ基盤となる技術は共通」「アウトプットが違う」という所です。

ここで分析の業務とは、主に「MAU、DAUやユーザの行動履歴から広告、CM等の施策の効果を定量化、推論」「市場を分析し次の行動決定を円滑に進める」「ABテストの効果分析」等があたります。分析業務におけるアウトプットは、企業で言えば「データを分析し可視化された結果で人や施策のアクションを決定する」事です。

一方モデリングの業務とは、「データを学習できるモデルを作成する」「学習したモデルのサービスイン」といった所を指します。モデリングのアウトプットは、「実際のサービスで稼働する」となってきます。

モデリング業務は、皆サービスのユーザとしては日々感じている場合が多く、より身近かもしれません。例えば、Webサービス等において「オススメ商品がサジェストされてくる」だとか「写真にタグを自動で付けてくれる」といった類の物です。


分析、モデリングの2つのアウトプットの違いを理解せず人を雇ったり、プロジェクトメンバーを配置してしまうと悲惨な事になりがちです。

広く言われる「データサイエンティストの書くコードは汚い」といった発言は、発言者が身を置く環境が「レベルが低い」か「AI屋の認識にズレがある」という所から来ていると私は考えています。

f:id:vaaaaaanquish:20180324190557p:plain
登壇スライドより AI屋さんの分類

研究業務はさておき、上記の図には、各AI屋さんのそれぞれの中身を少し詳しく書いています。
独断と偏見も混じっていますが、概ね正しいと自負しています(刺されそうです)。


1つ目のスライド図で、分析は「一般的にデータサイエンティスト」、モデリングは「一般的に機械学習エンジニア」のお仕事であると記載しています。2つ目のスライド図では「データサイエンティスト」「機械学習エンジニア」の位置は、それぞれ分析、モデリングに寄りつつも重なった位置に書いています。

"一般的に"という説明から2つ目のスライド図を示した通り、近年における「データサイエンティスト」「機械学習エンジニア」という言葉は、揺らぎが強く、分析、モデリング業務を多岐に行っている場合が多くなっています。
分析業務とモデリング業務のアウトプットはかなり違うのに…


アウトプットまでの課程が変われば、そこで利用するデータや手法、工数割り振り、考え方が変わってきてしまいます。
つまり「分析で出た結果が良いのでそのままサービスインしよう!」「モデリングで出来た物が良いので」というのはかなり厳しい訳です。
これは、分析、モデリングの工程における統計に基づくデータの加工や、機械学習モデルの選択が変わってくるからです。

業務においてプロジェクトを成功に導くには、「データサイエンティスト」「機械学習エンジニア」という言葉から更に深掘りし、どういったアウトプットを要求するかという点を考え、それぞれの業務の経験、得意不得意から適材適所に人を配置しなければいけません。



最後に研究業務ですが、Yahoo! Japanという企業を例に出すと、Yahoo! JAPAN研究所を作り「学会での論文発表」「大学との共同研究」「オープンデータ、ソフトウェアの公開」という業務を行っているようです。

f:id:vaaaaaanquish:20180324184638p:plain
Yahoo! Japan研究所論文発表数:research-lab.yahoo.co.jp/gaiyo/index.htmlより引用

企業で利用できるデータを用いた国内外のトップカンファレンスでの発表、オープンデータの公開といった業務以外にも多分社内向けの分析基盤を作ったりもしているでしょう。
参考:
ソフトウェア/データ - Yahoo! JAPAN研究所 - ヤフー株式会社
研究領域 - Yahoo! JAPAN研究所 - ヤフー株式会社


研究はモデリング、分析とは違い、直接的に事業に貢献できる物ではない場合が多い業務です。
アウトプットも「論文」「機械学習アルゴリズム」「分析ソフトウェア」等になってきます。


AI屋さんのアウトプット基準で分類を定義しました。
大事なのは研究、分析、モデリング全てにおいて機械学習、統計、自然言語処理、画像認識、音声認識、情報検索…といった専門分野が基盤にあるのに対して、アウトプットで見ると全く違うという点です。

皆さんが行いたい「AI」って何ですか?
専門性ももちろんなのですが、「データサイエンティスト」「機械学習エンジニア」という言葉から更に深掘りし、どういったアウトプットを要求するかという点を考え、それぞれの業務の経験、得意不得意から適材適所に人を配置しなければいけません。(大事なので2回言っています)


ただただ「できる機械学習エンジニアが欲しい!」と言ってる人は、「フロントエンド、バックエンドの何がやりたいのか定義せずJavaScriptエンジニアが欲しい!」と言っている人と同レベルです。


 

実際のAI屋さんの業務

AI屋さんの1日を見て、どのように業務を進めているかについても話しました。

実際に私の平均的な1日を図として示しています。

f:id:vaaaaaanquish:20180324191530p:plain:w400
登壇スライドより AI屋さんの1日

よくわからない人間とのミーティングや雑務を除いて、Qiitaやはてなブログでバズってくるような「機械学習ライブラリを使ってパラメータをイジって学習〜」「データを可視化〜」という部分はかなり上澄みで、実際の業務で使われる時間はどんどん少なくなっています。

いくつかの要因がありますが、主には以下です。


統計、機械学習において最も効果的なのが学習データ、タスクの修正であるという話は、AI屋さんの中では以前より存在するかなり当たり前の話です。

実際に学習データが綺麗になればなるほど、機械学習モデルの精度は上がっていきます。
また、精度が上がりきらなければタスク自体をより機械学習に適したタスクに落とし込むという作業も有効です。

例えば、私は前職現職でもひたすら学習用の画像を見て数日を過ごす事もありました。
また、タスク自体を変更するために、年度やユーザ、特定のルールに基づいてデータを収集しなおしたり、問題設定自体を見直すために正解ラベルが入ったExcelファイルと数週間戦う事もあります。

こういった「泥臭い作業」は、クラウドソーシングで〜という場合もあるにはありますが、基本的には統計、機械学習に関する知見が必要で「これは機械学習で判断できるであろう」という前提を持たなければ出来ない作業です。

加えて、そういった「泥臭くない作業以」はフレームワークやマシンの充実で自動化が進んでいます。
例えば、パラメータの調整手法の充実、機械学習ライブラリや可視化ツール、分散処理技術、GPUスパコンの存在がそれらを支えています。
Yahoo! Japanにはどうやらkukaiと呼ばれるスパコンもあるらしいです(https://about.yahoo.co.jp/pr/release/2017/06/19b/)。
(もちろんこれら基盤にお金が必要だったりという場合もありますがその話はここでは取り上げません)。


適切な環境やツール、手法さえ選び使う事ができれば、泥臭く最も効果のある作業に集中しアウトプットの質を上げる事が可能なのです 。
AI屋さんの仕事のサイクルというのは「泥臭い作業をしながら、泥臭くない作業をガンガン自動化して効率化していく」という所に尽きます。


作業の効率化の方法は、研究業務にも近く、研究業務のアウトプットが社内外の分析、モデリング業務を支えているというイメージです。


 

AIプロジェクトを上手く回すには

AIプロジェクトを回すコツを3つ紹介しました。

  • 使いたいのは誰か決める
  • 泥臭くない作業を自動化する
  • 要件を順に詳しく決定していく

上2つは、今までの話と関連しています。

分析、モデリング、研究とそれぞれ利用する技術は同じでも、アウトプットの形が違います。
「データサイエンティスト」「機械学習エンジニア」といった言葉も良いですが、より深めて見ないとプロジェクト毎倒れてしまいます。

また泥臭くない作業というのは積極的に自動化したい所です。
もちろん自動化しやすい最適なフレームワークやツール、手法の選定はAI屋さんが行うのですが、インフラ屋さんやDB屋さん、果てはハード屋さんの協力も必要でしょう。
時にはお金も必要でしょう。
「AI屋さんにGPU買ったけど日の半分画像フォルダとにらめっこしてる」という事が多くあると思いますが、そういった時に特に自動化を進められるような協力体制が出来ているとプロジェクト全体が良く回るようになるでしょう。


3つ目の要件の決定ですが、目的が決まる毎にAI屋さんと相談すると良さそうです。
大きな理由は以下の2つです。

  • ある目的のために集められたデータが
他目的に使えるとは限らない

  • サービス要件を満たせるかどうかわからない

例えば、泥臭く集めたデータというのはAI屋さんが目的に応じて特定のルールで集め、目的に応じてクレンジング、加工してある物である場合が多いです。
それらのデータをそのまま利用して、他タスクでも成果を出すというのは非常に困難です。
別の目的で利用した時に考えられる、エラーや課題を許容できる場合であれば良いですが、それらが想定しきれないようであればでデータ集めからやり直しとなってしまう場合もありますので相談はお早めに。

また目的によっては、せっかく作ったモデルがサービス要件を満たせないという事もあります。
シンプルな例としてDeep Learningがあります。
Deep Learningにおける巨大なニューラルネットワークモデルでは、GPU推論で数秒かかってしまう場合があります。毎日数万アクセスがあるサービスで、1ユーザの利用で数秒消費するというモデルを利用するのは、企業として相当な体力が必要です。AI屋さんの端くれである私としては、別モデルの利用、転移学習、枝刈り、蒸留…といった回避策が思い付くのですが、目的が曖昧であるとそれら選択肢から選ぶ事すらできません。
目的は徐々に相談しながら決めていくと、プロジェクト全体を見た時に成功しやすいでしょう。


登壇中も言いましたが、拡大解釈していくとこれらはAIプロジェクトに限った話ではない部分も多いかと思います。
しかしながら、泥臭い作業が多い等、AI屋さんならではの話も含んでいるため、それらを考慮し調整しながらサイクルを回す事で、プロジェクト全体が効率よく回るようになるでしょう。


 

- 登壇の感想とか -

実際の登壇はもう少し実例を出して話をしたとは言え、かなり広い話になってしまいました。
より詳しく技術の話をしても良かったのですが、会社のアレコレが面倒なのと、他登壇者、参加者の様子を見て、初めてAIという広い表題を扱いました。

個人的には今後の登壇について考えさせられる事が多く、良い経験となりました。
会社名義で登壇するのは面倒事多すぎるので、自身の技術を自身で強く磨いていかないとと思いました。


クロスセッションでは、AI関連の質問を受けて他登壇者とセッションしたのですが、夢も希望もない話をしてしまったので、夢と希望が持てる話もネタとして持っておかないとなと思いました。


 

- 他のAIセッションの登壇 -

他のAIセッションの登壇を紹介しておきます。
大体全部オススメです。
ブームもあってか他の部屋も盛況だったようです。

Aidemyのハンズオンは多分Aidemyを登録してやれよという事でしょう!
(あとフューチャーアーキテクトの登壇もあったような…)


 

- おわりに -

MANABIYAというイベントですが、最初に貰った資料がペラペラで信用できず、突然のクラウドファンディングで登壇予定の人がキレてTwitterで辞退宣言したり、連絡のやり取りがめちゃくちゃ遅かったり、懇親会の2次募集すると言ってされなかったりと、「本当にこれだけのエンジニア集めて成功に持っていけるのか・・・?」という不安がめちゃくちゃありました。

当日もバタバタしたスタッフとタイトなスケジュールが組まれていたのですが、何とか全てのタスクが回っていて、大炎上するような人は何とか居なかったようです。

イベント初回でこの規模を、レバレジーズという会社の規模で回しきったというのは、素直にすげえなあと思います。
元学校という会場で学祭のようなわちゃわちゃ感で、それなりのクオリティのイベントに収まっていました。
(クオリティが高いのは登壇者がすごいからか…)

 
このイベントが本当にteratailなるサービスの宣伝になっているのか本当に謎ですが、実際にフォロワーに声をかけてもらったり、AIセッション登壇者内でも交流する事ができ、自分としてはそれなりに良い時間を過ごさせて頂きました。





ありがとうレバレジーズ。ありがとうteratail。
teratail登録はしてみたけど、質問する事がないのでこれから考えます。


追記:
より正しい情報があった

追記2:
その場で質問を壁に貼って誰かが答える面白コンテンツが思い出深かったです。


 

xonshのPROMPTにdatetimeを表示する

- はじめに -

xonshで作業をしているとつい時間を忘れてしまうので、時間を表示してやるメモ。

POWERLINEで良くみるやつをxonshrcで実装。


 

- timeを表示する -

コンソール上の右側に表示するにはこんな感じ

from time import strftime
$RIGHT_PROMPT = lambda: strftime('[ %H:%M:%S ]')

f:id:vaaaaaanquish:20180316235141p:plain
こんな感じ


xonshrcを書く - Stimulatorでも書いた通り、コマンド前は$PROMPT、右は$RIGHT_PROMPT、下にバー状に出しておきたければ$BOTTOM_TOOLBARに関数を突っ込む。


上記をlambda使わずに書くと以下
文字列を返す関数をPROMPT系の変数に突っ込んでおけば、キー入力時に評価される。

from time import strftime
def get_time():
    def prompt():
        return strftime('[ %H:%M:%S ]')
    return prompt
$RIGHT_PROMPT = get_time()
$UPDATE_PROMPT_ON_KEYPRESS=True

文字色や背景色などのフォーマットは、xonshのprompt-toolkitの普通のやつと似たような感じにすれば良い。


 

- datetimeを出す -

右にあっても見なさそうだったのでPROMPTに出す。

from datetime import datetime as dt
prompt = " {INTENSE_RED}{user}{INTENSE_GREEN}@{INTENSE_BLUE}{hostname}{INTENSE_YELLOW} [ {cwd} ] {GREEN}$ "
$PROMPT = lambda: dt.now().strftime('[ %Y-%m-%d %H:%M:%S ]')  + prompt
$UPDATE_PROMPT_ON_KEYPRESS=True

キー入力ごとに更新される。
f:id:vaaaaaanquish:20180317003150g:plain


以下参考
https://github.com/xonsh/xonsh/blob/adcd20f72fcbe6962533cb3ad78a4a9ec396e150/xonsh/readline_shell.py
https://github.com/xonsh/xonsh/blob/72f3bc0d089ea91d4e5288bb1c44ebfbe81db43e/xonsh/ptk/shell.py

 

- おわりに -

xonshにはそもそもxonsh.tools内に時間表記のメソッドがあったりするが、イマイチだったのでtime、datetimeを入れてきた方が早そう。
(Tools (xonsh.tools) — xonsh 0.8.3 documentation)


リアルタイムに表示したくなって数日試したけど、あんまり良い方法がなかったのでアイデアが欲しい。
xonshではなくprompt-toolkit側を見ないとダメそうなのでちょっとしんどそう


 

Qiitaの特定記事やタグ付記事をいいね、ストックしているユーザを見るPythonスクリプト

- はじめに -

Qiitaは、プログラミングに関する知識を記録・共有するためのサービスです。

Qiitaアカウントには企業情報が紐付いている場合があり、Qiitaの様々な記事から情報を取得し分析する事で「機械学習を記事を多くストックしている勉強熱心な会社はここだ!」等といった事が分かるのではないかという思いから、Qiitaのアカウント情報を取得するスクリプトを書きました。

その時のただのメモです。


 

- Qiita API -

QiitaにはAPIが存在します。

以下のQiita記事でAPIPythonクライアントを書いている人が既に居たので、こちらを利用します。
Qiita API v2のPythonラッパー実装した - Qiita

pipで導入します。

pip install qiita_v2

以下から「個人用アクセストークン」にread権限を付けて発行します。
https://qiita.com/settings/applications

その際表示されるtokenをメモしておきます。

これで後はいいね数を取得するだけなのですが、実際にこのPythonクライアントの中を見てみると、APIに存在する「いいね数の取得」に対応していませんでした。
qiita_py/client.py at master · petitviolet/qiita_py · GitHub

仕方ないので以下のようにメソッドを追加しつつ、記事のID(stock_id)に対していいねしたユーザとストックしたユーザを取得するスクリプトを書きました。

from qiita_v2.client import QiitaClient

def list_item_likes(self, item_id, params=None, headers=None):
    return self.get("/items/{}/likes".format(item_id), params, headers)
QiitaClient.list_item_likes = list_item_likes

stock_id = ''
token = ''
client = QiitaClient(access_token=token)

# いいねしたユーザ
res = client.list_item_likes(stock_id)
like_users = [x["user"]['id'] for x in res.to_json()]
for i in range(int(int(res.result_count)/20)):
    res = client.list_item_likes(stock_id, params={"page":i+2})
    like_users += [x["user"]['id'] for x in res.to_json()]

# ストックしたユーザ
res = client.list_item_stockers(stock_id)
stock_users = [x["id"] for x in res.to_json()]
for i in range(int(int(res.result_count)/20)):
    res = client.list_item_stockers(stock_id, params={"page":i+2})
    stock_users += [x['id'] for x in res.to_json()]

APIの制限は認証している状態で1000回/時、そうでなければIPアドレスごとに60回/時です。
数記事であれば大丈夫でしょう。


 

- ユーザ情報の取得 -

list_item_likes、list_item_stockersのresponseとなるjsonには""organization""なるキーが含まれています。

しかし、Qiitaプロフィールで表示されるものには「organization」と「Organizations」が存在しており、Qiita Organizationに登録されていない会社は前者、登録されている会社は後者に含まれ、APIでは前者しか取得できないのが現状です。

データ分析のため、後者のOrganizationsを取得したい事からユーザ情報取得のスクリプトを書きました。

import requests
from bs4 import BeautifulSoup
import time

def get_accounts_org(accounts):
    data = {}
    for account in accounts:
        res = requests.get("https://qiita.com/{}".format(account))
        bs = BeautifulSoup(res.text, "lxml")
        organization = [y.attrs["content"] for y in [x.find("meta") for x in bs.findAll("li", attrs={"itemprop":"memberOf"})]]
        host = [x.text.strip() for x in bs.findAll("div", attrs={"class": "newUserPageProfile_info_body"}) if x.find("i", attrs={"class": "fa-building-o"}) is not None]
        data.update({account: {"org":organization, "host":host}})
        time.sleep(5)
    return data

like_orgs = get_accounts_org(like_users)

like_usersリストに入っているユーザ情報から「organization(host)」「Organizations(org)」を取得する事ができました。


 

- 実際に見てみる -

実際に「記事にいいねしたユーザ」について見てみました。

テストとして以下の記事を選びました。
技術共有サービスQiitaで開催されていた2017年Advent Calenderにて、いいね獲得数ランクによってIBM、Greenという会社から表彰された記事ですので、いいね数もそれ相応かと思います。
qiita.com

集計は適当にCounterで

from collections import Counter

d = Counter()
for y in [(k,v) for k,v in like_orgs.items() if v["org"] or v["host"]]:
    for x in y[1]["org"]:
        d[x]+=1
    for x in y[1]["host"]:
        if x not in y[1]["org"]:
            d[x]+=1
for x in d.most_common(10):
    print(x)

結果は以下のようになりました

('株式会社リブセンス', 21)
('株式会社ミクシィ', 5)
('フューチャーアーキテクト株式会社', 4)
('フリーランス', 4)
('スタディプラス株式会社', 4)
('株式会社オールアバウト', 3)
('株式会社モバイルファクトリー', 3)
('アイレット株式会社(cloudpack)', 3)
('IBM Japan', 3)
('株式会社ゆめみ', 3)

記事の著者もリブセンスという会社ですが、やはり同僚の記事はいいねしたくなる傾向にあるのでしょうか。
私も社内SNSに「アイツの記事バズってるよww」みたいに同僚の記事を貼る人間を見たことがあるので、そういう影響もあるでしょう。

いかんせん、データ数が少ないので何も言えませんが、取得して見るまではできました。


 

- Qiitaの特定タグのついた記事を集める -

Qiitaには、記事にタグを付ける機能があります。

特定のタグがついているAPIを叩くため、上記と同じくQiitaClientに新しくメソッドを追加して実行します。

from qiita_v2.client import QiitaClient

def get_tag_items(self, item_id, params=None, headers=None):
    return self.get("/tags/{}/items".format(item_id), params, headers)
QiitaClient.get_tag_items = get_tag_items

tag_name = '機械学習'
token = 'hoge'
client = QiitaClient(access_token=token)

res = client.get_tag_items(tag_name)


ひとまず機械学習タグのついた記事を100 * 20 件分取得してみます。
QiitaのAPI制限を考えると、一度取得した情報はcacheしておくのが正解だと思います(以下では一切やっていません)。

ids = []
users = []
for i in range(100):
    res = client.get_tag_items("機械学習", params={"page":i+1})
    ids += [x["id"] for x in res.to_json()]
    users += [x["user"]["id"] for x in res.to_json()]

上記スクリプトにより、機械学習タグのついた記事を投稿しているユーザ、投稿された記事のidリストが取得できました。


 

- 機械学習記事を投稿、いいねしたユーザ情報を見てみる -

前述したget_accounts_org関数を利用して、機械学習タグ付き記事を投稿したユーザが属する企業、機械学習タグ付き記事をいいねしたユーザが属する企業について、Countをとってみます。

以下が直近2000記事で見た「機械学習タグのついた記事」を多く投稿する社員のいる企業です。

('TIS株式会社', 6)
('株式会社トップゲート', 5)
('株式会社ブレインパッド', 4)
('Team AI', 4)
('株式会社リブセンス', 4)
('株式会社 ドワンゴ', 4)
('Nuco Inc.', 4)
('株式会社Nextremer', 4)
('株式会社アカツキ', 3)
('株式会社クラウドワークス', 3)

Qiitaで機械学習記事といえば、あのアカウントとあのアカウントとあのアカウントかな…?という一覧になりました。
データが増加してもQiita活動家が社内に居るか居ないか、に寄ってしまいそうです。

これ以下はほぼ1~2だったので面白い結果を得るまで数を増やすのは少し大変そうです。
 
 
以下は直近2000記事で見た「機械学習タグのついた記事」にいいねを多くした社員のいる企業です。

('株式会社リブセンス', 31)
('Fringe81株式会社', 24)
('株式会社クラウドワークス', 22)
('TIS株式会社', 21)
('株式会社VASILY', 16)
('株式会社リクルートライフスタイル', 12)
('Retty株式会社', 12)
('フューチャーアーキテクト株式会社', 11)
('P&D – Planning and Development – ', 11)
('株式会社アカツキ', 11)
('Shinonome, inc.', 11)
('株式会社LIFULL', 10)
('株式会社トップゲート', 10)
('株式会社オールアバウト', 10)
('株式会社ゆめみ', 9)
('フリーランス', 8)
('株式会社 ドワンゴ', 8)
('株式会社Nextremer', 8)
('株式会社ACCESS', 8)
('株式会社エイチームライフスタイル', 8)
('株式会社エイチームブライズ', 8)
('株式会社BitStar', 8)
('The University of Tokyo', 7)
('株式会社div(ディブ).', 7)
('株式会社WACUL', 6)
('株式会社Fusic', 6)
('Kyoto University', 6)
('株式会社Rosso', 6)
('株式会社サイバーエージェント', 6)
('エムスリー株式会社', 6)

リブセンスという会社はQiitaに相当な時間を使っているという事がわかりました。
こちらも上位は「あのアカウントかな…」と個人が見え隠れする結果となりました。

こちらは、東大、京大やフリーランスがトップ30に入ってきた辺りを見るに、データが集まれば少し改善しそうです。


 

- おわりに -

APIの制限数によって1日ではこの程度でした。

多くデータを集めた上で、「機械学習タグのついた記事にいいねするユーザ」の数を企業単位で集計することで、特定の技術に興味関心が強い企業が見られるかも…という結果になりました。

Qiita APIではユーザに紐付いたLinkedinやFacebookTwitterのIDも取得できるため、次回はそれらを含めた集計を出せればと思います。


 

『人工知能プログラミングのための数学がわかる本』が機械学習研究入門書としてとても良さそうだった

- はじめに -

本を読んで筆者に媚を売る記事シリーズです。

人工知能プログラミングのための数学がわかる本」という書籍を筆者の石川 聡彦(Aidemy)@akihiko_1022さんから譲り受けました。

人工知能プログラミングのための数学がわかる本

人工知能プログラミングのための数学がわかる本

明日2/24発売ですが、筆者である石川さんがCEOを務めるAidemyさんと人工知能機械学習のイベントにてご縁があり頂く形になりました。


そもそもAidemyは、Python及び機械学習のための知識と実装に関する学習を行えるWebサービスです。

aidemy.net

似たサービスではUdemy(https://www.udemy.com/jp/)というアメリカのサービスがかなりのシェアを誇っています。

Aidemyは後発ですが、丁寧な日本語解説と内容の質の高さから、機械学習界隈でも「Aidemyは良い」という声を聞く程優良なサービスです。
こういった初学者向けのサービスの僅かなミスを論う意地の悪い界隈でも評判が良いのがすごい。

私自身も最初のコースだけやりましたが、よく出来たWebエディタと正しい導き方を見て素晴らしいなと思いました。


筆者がそのAidemy CEOの石川さんという事で、丁寧な導きと潔い切り口で書かれた本でした。


 

- どんな人が読むと良さそうか -

個人的には以下のような人にオススメです
- 機械学習の研究室に入りたい、研究をはじめたい
- 機械学習の論文が読みたい
- 機械学習における数式を噛み砕いて理解したい
- 高校、大学数学の知識を呼び戻したい
- これからMLPシリーズや高レベルな書籍を読む

とにかく「機械学習の研究室に一冊あるとめっちゃ捗る」。
これだけは間違いなく声を大にして言えます。
研究入門として素晴らしい構成です。

以下書籍の雰囲気です。

f:id:vaaaaaanquish:20180223211609j:plainf:id:vaaaaaanquish:20180223211600j:plain
めっちゃ丁寧できれい

本当に高校数学から大学における確率、線形代数までこの優しさで解説されているのでGoodです。

 
対して「機械学習を業務でやる」「データサイエンスの知識が欲しい」人には直結して学習効果の高い本ではなさそうです。

直結して効果が薄い、というのは実際の業務や実装では「これくらい知ってて当然」という場合が多々あると思われるからです。私の知っている機械学習エンジニア各位なら、10分で読了して、内容に準じた小テストまでこなせるでしょう。
ただそういった人達でも、自分の復習と理解の落とし込みのためであればかなり良い書籍であるという事は間違いないと思いました。

加えて「数学、線形代数をより理解したい」という人は満足できないでしょう。高校、大学数学の基礎から、機械学習への導入の持っていき方が素晴らしい書籍であって、定義を明確に数式を展開していくものではないです。


 

- 書籍の良かったところ -

前述の通り、高校、大学数学の基礎から、機械学習への導入の持っていき方は非常に滑らかに感じました。

数学といっても本当に2次方程式平方根、指数関数といったレベルから説明が入ります。
三角関数、集合、行列、ベクトル、確率、…と進み総復習のような形です。

それらの説明に対し全ての節に「人工知能ではこう使われる!」という説明が入っています。
これがなかなか一般的な書籍にない所で、「この為に勉強してるんだ」という実感が持てる所が、入門書としての格を上げています。

f:id:vaaaaaanquish:20180223230129j:plain:w400
こう使われる!

また、数式内にも色や線を利用して丁寧に解説が挟まれていたり、イメージの図もより優しい表現が使われています。

 
機械学習の仕組みを読み解く上での基礎となるワードが配置されているかつ、実際の機械学習に使われる箇所まで説明される書籍というのはなかなか無く、研究をはじめる前に読んでおくことで他の少しレベルを上げた書籍が一気に読みやすくなるでしょう

そういった点からタイトルを「機械学習研究入門として良さそう」としています。

 
加えて、最後の章では実際に「Boston Housing Dataset」「青空文庫」「MNIST」といった入門向けデータセットを利用してデータ分析、自然言語処理、画像認識の実体験を進める事ができます。

これらもコードがGithubで見られるようになっており、実際に学んだ知識を使いながらスムーズに体験できる所が最も素晴らしい所だと思います。

 
あと以下の記事の時にも書きましたが、こういった書籍のコラムは本当に良いです。

vaaaaaanquish.hatenablog.com

機械学習界隈で使われるワード」というのは意外と外に出回るものではありません。
機械学習界隈の人間同士の会話の中で自然に出てくるワードの知見が得られるのも書籍の良いところだと改めて感じました。


 

- 書籍で足りないところ -

導入までが素晴らしい書籍ですが、「じゃあこの本で得た定義で機械学習の研究室や勉強会でドヤ顔できるか」と言われたらできないでしょう。

最終章でDeep Learningニューラルネットワーク誤差逆伝播法、勾配法をピックアップしてより詳しく説明していますが、それでもさらに話を進めて研究レベルに持っていくには一歩足りないイメージです。
ただ「連続とは何か」みたいなレベルから書いていたら辞書みたいなサイズになってしまうので、どこかで情報を切らないといけない訳ですが、そういう意味では潔い書籍であるとも言えます。
さらに深く学ぶにはより専門的な書籍を探しましょう。

(これはつまり「この後Aidemyをやれ」という事なのかも…)

 
個人的にはこれ以上批判すべき所がなく「面白くねえな…」「これ普通に高専で研究始める前とかに読みたかったわ…」となりました。


 

- おわりに -

「松尾豊氏推薦!」という強めのワードと、なかなか可愛い表紙が特徴的な一冊です。

あと姑息な宣伝ですが、そんなAidemyの石川さんと私が登壇するMANABIYAというイベントがあるらしいです。
石川のハンズオンは既に満員みたいですが是非私の与太話を聞きに来て下さい。
manabiya.tech


今回Aidemyのステッカーも貰ったので、さらに媚を売るためにPCに貼った写真で終わりにしたいと思います。

f:id:vaaaaaanquish:20180223205736j:plain:w400
かわいい表紙

普通に研究室や会社に一冊あると、ふとした時に復習できる良書籍だと私は思いました。

 

人工知能プログラミングのための数学がわかる本

人工知能プログラミングのための数学がわかる本

 

共同通信と朝日新聞の記事URLを含むツイートを削除するPythonスクリプト

- はじめに -

この記事の起点となったのは、2018年1月25日、共同通信が配信した「山中氏、科学誌創刊に深く関与か」というタイトルの記事が、同日午後8時頃「山中所長が給与全額寄付」というタイトルの記事に書き換えられていた件である。

下記ツイートの通り、追記や編集の知らせ無しにネットメディアが大幅に修正された場合、記事公開当初と意見の辻褄が合わず、自身の発言に責任が取れなくなる場合がある。


自身が良いと共有した記事が卑猥、卑劣な記事になっている場合を防ぐため、特定のメディアの記事に言及していたツイートを削除するスクリプトについてメモしておく。


事前に必要な要件は以下の通り


 

- スクリプト -

最初に全体のスクリプト

API周りのKeyは、http://phiary.me/twitter-api-key-no-japanese から電話番号をアカウントに紐付けた後、https://apps.twitter.com/ にて取得する。

全ツイート情報を含むCSVは、Twitter公式のSettingsから、全ツイート取得の申請を出すと登録しているメールアドレスに30分程でダウンロードリンクが送られてくる。

f:id:vaaaaaanquish:20180126231631p:plain:w300

import tweepy
import urllib
import csv
import urllib.request

CONSUMER_KEY = ''
CONSUMER_SECRET = ''
ACCESS_TOKEN = ''
ACCESS_SECRET = ''
CSV_PATH = 'tweets.csv'
DOMAIN_LIST = ["this.kiji.is", "www.asahi.com"]

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
api = tweepy.API(auth)


def expand(url):
    req = urllib.request.Request(url, method='HEAD')
    resp = urllib.request.urlopen(req)
    return resp.url


def expand_url(url):
    eurl = expand(url)
    while eurl != url:
        url = eurl
        eurl = expand(url)
    return eurl


def main():
    with open(CSV_PATH, 'r') as f:
        reader = csv.reader(f)
        header = next(reader)
        for i, row in enumerate(reader):
            flag = False
            for x in list(set(row[9].split(","))):
                if x != "":
                    try:
                        y = expand_url(x)
                        for domain in DOMAIN_LIST:
                            if urllib.parse.urlparse(y).netloc == domain:
                                flag = True
                    except KeyboardInterrupt:
                        raise
                    except:
                        pass
            if flag:
                api.destroy_status(row[0])

if __name__ == '__main__':
    main()

print等は適宜。

ツイートが削除されるスクリプトなので確かめながら使う。


 

- 適当な色々 -

以下は駄文である。

このスクリプトを書くにあたっての実験的な色々とか。

短縮URLの展開がurllibだけでできるようになってた

短縮URL 展開 Python」みたいに適当にググると、Python2系のhttplib.HTTPConnectionを使ってHEADメソッド投げるスクリプトが沢山でてくるのは知ってたけど、3系からurllib.request.RequestでHEADできるの知らなかった。

Python3系で短縮URLを展開するのは以下みたく

import urllib.request
root_u = "http://hogehoge"

def expand(url):
    """curl --head url"""
    req = urllib.request.Request(url, method='HEAD')
    resp = urllib.request.urlopen(req)
    return resp.url

def expand_url(url):
    """短縮URLをできるだけ展開する"""
    eurl = expand(url)
    while eurl != url:
        url = eurl
        eurl = expand(url)
    return eurl

print(root_u, expand_url(root_u))

個人的には使い所は今のところないがハッピーな気がする

 

CSVの読み込み

CSVは大体30分くらいでメールが来て、ツイート数226Kで40Mくらいのzipになってた。
前回ダウンロードした時より大分大きくなってる気がした。

試しに1000件くらいやってみたけど、割りと接続できないURLがあったので、そちらも削除した方が良いような気がした。

import urllib
import csv
with open('tweets.csv', 'r') as f:
    reader = csv.reader(f)
    header = next(reader)
    for i, row in enumerate(reader):
        # 複数URLはカンマ区切り
        for x in list(set(row[9].split(","))):
            if x != "":
                try:
                    y = expand_url(x)
                    print("base: {}\nexpanded: {}\ndomain: {}".format(x, y, urllib.parse.urlparse(y).netloc))
                except KeyboardInterrupt:
                    raise
                except:
                     print("Not Found : ", x)
        if i > 1000:
            break

headerはtweet_idとexpanded_urlsしか使ってないけど、textとか時間も考慮した方が良い気がした。

 

記事の書き換えについて

全体を通して嫌な気分になる話だったが、解決方法が見当たらず難しい問題だと思う。

日本の今の社会形態からして、記者が常に誠実かつ知識を多く習得し続けるというのは難しいだろうし、それらを補正するには専門家の意見を割く事になる。
記者側としても「スピード感持って数多くの読まれる記事を出したい」という気持ちは強いだろうし時間の制約は大きい。

その点ネットでは公開直後から意見が集まる訳なので、今回あくまで修正方法が下衆だったという話にして、今後「指摘があったので修正しました」「間違っていたので差し止めます」が気軽に言える社会になっていけば良いなと思う。

法律の範囲内であれば、間違う事自体は決して悪い事ではない。


 

- おわりに -

花金の飲み会おわりの勢いで書いた。

間違ってたら修正すればええねん。


 
追記 2018/01/27 0:14 :
ミスを指摘されたのでサイレントで修正しました。


 

自動運転シミュレータのCARLAを動かす

- はじめに -

Python APIを備えた自動車運転シミュレータである「CARLA: An Open Urban Driving Simulator」を動かすまでの記事です。

CARLAはConference on Robot Learning 2017でも発表された、Unreal Engine 4を使ったシミュレータパッケージです。
自動運転技術開発のための様々なカメラ、センサー情報をPythonで取得し、車操作に反映する事ができます。

とやかく言っても仕方ないので以下YouTubeの動画を一回参照して下さい。

www.youtube.com

本記事はCARLAの導入と触りまでを記述するものです。

特に物を作ってどうこうしてるアレではありません。

 

- CARLAについて -

CARLAは、CoRL2017発表論文のAbstにもあるように、自動運転技術の発展のためのOSSです。

作者

作者はAlexey Dosovitskiy、German Ros、Felipe Codevilla、Antonio Lopez、Vladlen Koltunらで、IntelTOYOTAの研究所、Computer Vision Centerのメンバーです。
(Toyota Research Instituteなのでシリコンバレーの方だと思います)

 

競合

競合パッケージではMicrosoftのAirSimが一番有名だと思います

CARLAと同じくUE4を利用しており、C++, Python, C# and Javaのクライアントがあります。
また、CARLA同様、カメラ画像情報だけでなく深度やSegmentationのセンサー情報を利用できます。
車だけでなくドローンも対応しており、Windowsバイナリもあるのでパパっと始められる点で優位です。

強いてCARLAを使った理由は環境(天気とか)が変えられる事くらいです。
正直buildしんどかったのでAirSimの方が良いのかなと思ったりしています。

あと他にもUdacityの教材リポジトリもありました。
GitHub - udacity/self-driving-car-sim: A self-driving car simulator built with Unity
こちらはUnityを直接触る内容のようです。
こういうのがちらほらあります。

 

CARLAパッケージ情報

Github
github.com

Document:http://carla.readthedocs.io/en/latest/

CoRL2017発表論文:http://vladlen.info/papers/carla.pdf

 

動作環境

Documentには、WindowsLinuxの項目がありますが、現在Windows版の説明部分はComing Soonとなっています。
How to build on Windows - CARLA Simulator


Linuxでは、Ubuntu 16.04かそれ以降のバージョンを推奨しています。
How to build on Linux - CARLA Simulator

他に環境構築をしていて気になった点は以下です

  • pyenvやvirtualenv環境下のPythonではPATH周りで死ぬ
    • 素直にaptでpython3-dev入れるのが現状良い
  • ストレージがそれなりに必要
    • UnrealEngine本体のbuildと素材のダウンロード
    • 50GBでやったら足りませんでした
  • sudoersアカウント欲しい
  • Unreal Engine 4がOpenGL 3.x or 4.xを使う
  • 別途Windowsが必要
    • Winからしかダウンロードできないパッケージを使う
    • .NETFrameworkも必要
    • UE4の権利関係の問題


正直注意点が多いのでクリーンでストレージも多いUbuntu 16.04が入ったハード1つ用意出来るならそれがベストです。
その中でVMWindows動かすとかが良いでしょう。


 

- CARLAインストール -

buildしていきます。
一応ドキュメントに従っていきますが、まあまあ大変です。
How to build on Linux - CARLA Simulator

 

私の環境

一応私の環境を書いておきます

MacbookPro上のVMware Fusion
Ubuntu 16.04
python3-dev
ストレージ 100GB
コア数 4
メモリ 8GB
(UE4のEditor開くだけでもmmapで1.5GBくらい確保してたのでそれなりに必要)

別途適当なWindows10端末

 

依存パッケージのインストール

CARLA依存パッケージは以下コマンドで導入
途中でrequestsが必要になったのでここでインストールしています。

sudo apt-get install clang-3.9 cmake ninja-build python-dev tzdata sed curl wget unzip autoconf libtool python3-dev libxml2-dev libxslt-dev git build-essential python3-pip python3-requests
pip3 install protobuf requests


以下を参考にUnrealEngineのbuildの依存パッケージを導入
Building On Linux - Epic Wiki

# Ubuntu 16.04
sudo apt-get install mono-mcs mono-devel mono-xbuild mono-dmcs mono-reference-assemblies-4.0 libmono-system-data-datasetextensions4.0-cil libmono-system-web-extensions4.0-cil libmono-system-management4.0-cil libmono-system-xml-linq4.0-cil cmake dos2unix clang-3.5 libfreetype6-dev libgtk-3-dev libmono-microsoft-build-tasks-v4.0-4.0-cil xdg-user-dirs


各Setupスクリプトでchmodコマンドが幾つか使われているので、自身のアカウントをsudoersに入れておく。
Ubuntuでsudoersに自身を入れるには以下

sudo gpasswd -a {アカウント名} sudo


Unreal Engineとの依存関係と互換性問題を解決するには、コンパイラC++ runtime libraryを全て統一する必要がある。
今回は素のUbuntuが用意できたのでドキュメントの通り、clang3.9とLLVMのlibc++を使用した。

sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/lib/llvm-3.9/bin/clang++ 100
sudo update-alternatives --install /usr/bin/clang clang /usr/lib/llvm-3.9/bin/clang 100

update-alternativesによってclang提供のメッセージが出ればOK

 

Unreal Engine 4のインストール

UnrealEngineをcloneしてくるが、EpicGamesのGithubリポジトリはcloseしているため、開発者として登録する必要がある。

以下URLの右上からサインアップしてGithubアカウントをProfileに記載する必要がある。
https://unrealengine.com

ここ
f:id:vaaaaaanquish:20180105214109p:plain:w400

サインアップしたら登録したメールアドレスの認証も行っておく(認証してないと後述の自動車素材がダウンロードできない)


サインアップ後、右上に人型アイコンができるのでそこから開発者用Profileページへ。
「接続済みアカウント」に行って下にスクロールしていくと、Githubアカウントを記載するフォームがあるので書く。
f:id:vaaaaaanquish:20180105214406p:plain:w400


https://github.com/EpicGamesとか適当にgithubページに行くと招待状が届いている。
invitationを表示してjoin memberする
f:id:vaaaaaanquish:20180105214423p:plain:w400
(背景が黒いのは自分が拡張しているから)


これでやっと以下スクリプトが通るようになるので、clone時にGithubアカウント認証して設定スクリプトを走らせてmakeする。

makeでは[x/N]みたいな表示が何回か出るし、素材ダウンロードもあるので適当なマシンでやると4時間くらいかかる。
最初適当に50GBくらいVMで容量設定したが、make時足りなくなって途中で止まったのでGPartedを久々に使う事になった。
ストレージは多めに見積もる必要がある。

git clone --depth=1 -b 4.17 https://github.com/EpicGames/UnrealEngine.git ~/UnrealEngine_4.17
cd ~/UnrealEngine_4.17
./Setup.sh
./GenerateProjectFiles.sh
make

 
Setup.shでは、「Success」となっていてもその下にエラーメッセージが表示されている場合がある(大抵権限周りで)。
~/.configを触る権限がないとかなのでsudoersでやり直し。

Setup.shの真のSUCCESSは以下画像参照
f:id:vaaaaaanquish:20180105215246p:plain:w400


makeする時もsudoersに入ってないアカウントで作業して、sudo等の扱い間違えると権限の関係で以下辺りで死ぬ。
chmodやchownコマンドで権限を読み書きできるようにして無理やり通しても、後続のCARLAビルドする時に死ぬので諦めてやり直すのが吉。

Refusing to run with the root privileges. (rootじゃmakeできないよー)
Access to the path "~~~~~" is denied (Access権限足りんよー)
CrushReport-linux-Shippingのレシピで失敗しました

  
権限周りを丁寧にやっていてもUE4Editorのレシピだけ失敗する場合がある。

Makefile:188: commands for object 'UE4Editor' failed
 make: *** [UE4Editor] Error 137

依存パッケージのビルド順の問題だったので以下のように1つ1つ愛のある手作業でビルドしていくと通った。

make ShaderCompileWorker
make UnrealLightmass
make UnrealPak
make UE4Editor
make CrashReportClient-Linux-Shipping RequiredTools UnrealFrontend

UnrealFrontend-Linux-Shippingじゃないの…と思ったけどUnrealFrontendっぽい。
参考:Compilation error: make: *** [UE4Editor] Error 137 - UE4 AnswerHub


もしUEのbuildをやり直したい時はmake cleanがないので以下のようにARGSを設定する
(Building On Linux - Epic WikiのEnhancing the Makefile)

make ARGS=-clean

 

CALRAのインストール

CARLAをcloneしてきてbuildする。
~/CARLA/Unreal/CarlaUE4/Contentへの追加や色々ダウンロード等が入るので、これもまた1時間ほどかかる。

(後で知ったけどCompiled versionもダウンロードできるっぽい…)
Release CARLA 0.7.0 · carla-simulator/carla · GitHub


Windows端末が必要な作業が後半にあるので、Setup中に出来る所までやっておくと吉。

ここでpyenv使ってる人はfaildやskippedが出たり、protobufやpyconfig.hが見つからないよと出る。
pyenv global systemして、UE4の関連パッケージインストールからやり直せば大丈夫。

git clone https://github.com/carla-simulator/carla ~/CARLA
cd ~/CARLA
./Setup.sh

SUCCESSとなったら設定おわり
f:id:vaaaaaanquish:20180105215841p:plain:w400

 
この後まさかのWindows端末が必要になる。
これも時間がかかるのでSetup中に出来る所まで以下やっておくと吉。

~/CARLA/Unreal/CarlaUE4/Content/配下に、追加で手動で自動車素材となるAutomotiveMaterialsを入れる作業である。
http://carla.readthedocs.io/en/latest/how_to_add_automotive_materials/

WindowsにAutomotive Materialsを追加したダミーのプロジェクトを作り、プロジェクト内にあるAutomotiveMaterialsディレクトリをLinux端末にコピーしてくる(現状ライセンスの関係で自分で入れる形になっているらしくこの方法の改善に取り組んでいるらしいが…)

 
以下URLからパッケージを0$で購入してダウンロードする訳だが、そのダウンロードがWindowsのLauncherアプリからしかダウンロードできない。
Automotive Materials by Epic Games in Epic Showcase,Materials - UE4 Marketplace

Windows端末で上記のパッケージのURLにアクセスして、右上の「ダウンロード」からEpic Games Launcher自体のインストールためのInstallerを落としてくる。

そしてInstaller起動してよしなにWindowsにインストール。
インストールできたらLauncherを起動して「次へ」をおしながら、.NETFrameworkが必要だったりするので、ウィンドウの表示に従ってポチポチしていけば良い。

起動したらLauncher内でマーケットプレイスに行けるので移動して、Automotiveで検索。
バージョンを4.17に合わせてプロジェクトを作成する(最新が4.18になってたので注意)。
f:id:vaaaaaanquish:20180105220528p:plain:w400
プロジェクト作成したらダウンロードがはじまる。

上記作業が終わったら、Windowsの「プロジェクト作成」で作ったプロジェクト配下にある{プロジェクト名}/Content/AutomotiveMaterialsディレクトリをコピーして、scp等でどうにかLinuxマシンに移動する。


Linuxに送信したら、Linux端末の~/CARLA/Unreal/CarlaUE4/Content/配下に送信してきたAutomotiveMaterialsディレクトリを丸々コピーする。
(ContentディレクトリはSetup.shによって生成される)

以下のようにPathを設定しておく

echo 'export UE4_ROOT=~/UnrealEngine_4.17' >> ~/.profile
source ~/.profile


Rebuildスクリプトを走らせて、素材ファイルのリンクと周辺のビルドをする。
OpenGL 3.x環境の場合はUE4Editorの起動時の引数に-opengl3が必要になるので、Rebuild.shの編集が必要。

Rebuild.sh 最後の方(65行目くらい)にある以下を変更
- ${UE4_ROOT}/Engine/Binaries/Linux/UE4Editor "${PWD}/CarlaUE4.uproject"
+ ${UE4_ROOT}/Engine/Binaries/Linux/UE4Editor -opengl3 "${PWD}/CarlaUE4.uproject" 
UE4_ROOT=~/UnrealEngine_4.17 ./Rebuild.sh


リンク作業のためにUE4Editorが起動する(ここでOpenGLが3以上でないと詰む)
初回起動時は初期化が入るのでそれなりの時間を要する。

f:id:vaaaaaanquish:20180105221116p:plain:w400
死んでいる様子

リンク作業は以下参照
http://carla.readthedocs.io/en/latest/how_to_add_automotive_materials/

コンテンツブラウザでContent/Static/Vehicles/GeneralMaterials/MaterialRedirectorsに行って「RedirectorInstance」を開き検索フォームで「Parent」を検索。DummyCarをM_Carpaintに名前を変えて上書き保存して終わり。
https://carla.readthedocs.io/en/latest/img/materials_screenshot_00.png
https://carla.readthedocs.io/en/latest/img/materials_screenshot_01.png

多分この作業で失敗すると人や車が表示されないので何度かやってみる。

 
以下のようにxbuild周りでエラーが出た場合は、UEのmakeをやり直すか権限設定を見直す。

ERROR: UBT ERROR: Failed to produce item
not found xbuild


 

- CARLA Serverの実行と操作 -

CARLAの操作はServerを建ててPython Clientから操作という形になる

具体的にはC lang APIを叩いており、ドキュメントにある図で言うとこんな感じ
https://carla.readthedocs.io/en/latest/img/carlaserver.svg

http://carla.readthedocs.io/en/latest/how_to_run/

ドキュメントの通りbuildに成功していれば~/CARLAディレクトリ直下に以下スクリプトができているので実行すると、UE4が起動しCarla Serverが動き始める。

./CarlaUE4.sh /Game/Maps/Town01 -carla-server -benchmark -fps=15

ない場合はbuild失敗してるか、compile済みのlatestから取ってくるか。

操作用のクライアントsampleを動かのに必要なパッケージを入れる

sudo pip3 install numpy Pillow pygame

別コンソールを開いて~/CALRA/PythonClient/内にあるsampleを動かせばひとまず操作できるようになる。

python3 ~/CALRA/PythonClient/manual_control.py

f:id:vaaaaaanquish:20180109215835p:plain:w400

manual_controlの操作は以下の通り

    W  : 進む
    S  : ブレーキ
    A  : 左
    D  : 右
    Q  : バッグ
    Space : ハンドブレーキ
    R   : restart

とりあえず楽しいです。


 

- おわりに -

ひとまず動作させるまでで終わりです。

本当は年末年始でAirSimも試し、クライアント作りまでやって設定色々書こうくらいまで思っていましたが、UE4のbuildに何回も失敗したり、Ubuntuが死んだり、CARLAが起動しても人Moduleが表示されなかったりとまあまあ辛かったのでここまでになりました。


CARLAが動けばAirSimも動くはずなのでチャレンジします。


次は自身で自動運転操作するまでの工程とか、CARLAのパラメータsettingについて書いていきたいと思います。

がんばるぞ。

 

Xonshのconfigを書く

- はじめに -

//------------------------
追記 2018/06/22:

以下の通り、config.jsonはサポートされなくなり、xonshrcになりました。

WARNING! old style configuration
(/Users/xxx/.config/xonsh/config.json)
is no longer supported. 
Please migrate to xonshrc.

xonshrcは以下にまとめました
vaaaaaanquish.hatenablog.com

//------------------------


この記事は、Xonsh Advent Calendar 2017 - Qiita 21日目の記事です。

xonshには.xonshrcに加えて、staticなjson形式のconfigファイルで設定するパラメータがある。

本記事では、config.jsonの書き方について記載する。


xonshrcについては以下
vaaaaaanquish.hatenablog.com


 

- config.jsonとは -

config.jsonはデフォルトでは ~/.config/xonsh/config.json に配置する。

より正確なPathは $XONSH_CONFIG_DIR/config.json である。

このファイルは、xonshrcより前に読み込まれ、外部シェルからのデータロードや、xonshrc内でも採用されるような重要な環境変数の設定、xontribの記載などを行うものである。

以下参考
http://xon.sh/xonshconfig.html


 

- configを書く -

現状keyとして読み込まれるのは、envxontribsforeign_shellsの3つ。

ここに書いておくと良い点も含めて下記に示す。

 

env

xonshrcファイルでも設定できるけど環境変数

静的なjsonファイルというだけなので、現状xonshとしてenv設定出来てメリットがあるのは以下くらいか。

{
    "env": {
        "XONSH_DEBUG": 1,
        "FOREIGN_ALIASES_OVERRIDE": True
     }
}

XONSH_DEBUGでデバッグ設定しておけば、xonshrc等のデバッグができる。
FOREIGN_ALIASES_OVERRIDEは、外部のShellのエイリアスを優先するかどうか。

Examples等では$EDITORとか設定してるけど、xonshrcの方が管理しやすい良い気がする。
Windowsなら$ALLUSERSPROFILEにrcファイルへのPathを書いておいてもよい。
Python系ならjupyterやpyenvへのPathなんかはここで書いても良い(気がする)。

 

xontribs

xontribsは、xonshの拡張であるxontribをlistで書いておくところ。

xonshrcでは以下のようにloadしないといけない所、パッケージ名をlistで書くだけになるのでちょっと楽。

xontrib load hoge

Sampleで自分のやつ。
名前を書いておくだけでよい。

{
    "xontribs": ["z","docker_tabcomplete","fzf-widgets"]
}

xontribは以下で書いたので参考に
vaaaaaanquish.hatenablog.com

 

foreign_shells

foreign_shellsでは、subprocessで呼び出す外部シェルの情報が記述できる。

より正確には、以下で呼び出されるforeign_shell_data()内で、subprocessとしてshellが一度起動され、該当shellのenvとaliasを読み込んでくる。
xonsh/foreign_shells.py at adcd20f72fcbe6962533cb3ad78a4a9ec396e150 · xonsh/xonsh · GitHub

 
list形式でdictを設定していく。dict中のkeyとしては以下が設定できる。
http://xon.sh/xonshconfig.html#foreign-shells

{
    "foreign_shells":[
        {
            # 起動したいshell
            "shell": "/bin/zsh",
            # 対話起動するか(しなくてもenv読み込めるshellなら不要)
            "interactive": True,
            # ユーザとしてlogin必要か
            "login": False,
            # 起動shellにおけるenvコマンド
            "envcmd": "env",
            # 起動shellにおけるaliasコマンド
            "aliascmd": "alias",
            # 起動するshellの引数(str)
            "extra_args": [],
            # 手動で起動shellにenv設定するためにdict
            "currenv": {},
            # 例外を安全に処理するか(Falseにするとraiseされる)
            "safe": True,
            # 色々読み込む前後にshellで実行させるコマンド
            "prevcmd": "",
            "postcmd": "",
            # 呼び出すshellのrcみたいなもん(以下参考に)
            # https://github.com/xonsh/xonsh/blob/adcd20f72fcbe6962533cb3ad78a4a9ec396e150/xonsh/foreign_shells.py#L33:title
            "funcscmd": "",
            # 呼び出したshellでsourceするファイル
            "sourcer": "",
            # 該当shellでスクリプトを実行する時のコマンド
            "runcmd": "",
            # 該当shellでexit-on-errorを設定するためのコマンド
            # "set -e"や"if errorlevel 1 exit 1"
            "seterrprevcmd": "",
            "seterrpostcmd": ""
        }
    ]
}

foreign_shellsで既に設定しているshell(xonshに乗り換える前に使っていた色々)をそのまま流用できたりする。


 

おわりに

あんまり書く機会がないかも知れないが、configについて記述した。

env、xontribs、foreign_shellsしか今の所書く事はないがxonshrcがちょっと簡略化される所がメリットか。


ひとまずアドベントカレンダー埋めた感じです。

qiita.com