Apache Spark: PythonとScalaのどっちを使うべきか比較する
データサイエンスプロジェクトで Spark を使う場合、必ず議論に上がるのがPythonとScalaのどちらのプログラミング言語を採用すべきかということです。
Sparkは元来Scalaで書かれているため、Scalaで処理コードを書いていくのが直感的にも自然なことです。しかし、データサイエンティストの多くはPythonに親しみがあるため、Sparkから取得したデータに対してPythonで書いた機械学習モデルや処理コードをそのまま適用したいということがあります。
そこで、近年台頭してきたのがPySparkです。PySparkとは、PythonでApache Sparkを実行するためのAPIです。PySparkの発展により、PythonによるSparkの扱いやすさは劇的に改善してきており、ScalaとPythonのどちらを使うべきかという論争は大きな盛り上がりをみせています。
本記事では、PythonとScalaのどちらでSparkを扱うべきかということについて、それぞれのメリットとデメリットを紹介しながら比較していきます。
Apache Spark とは
どのプログラミング言語を扱うべきかという比較に入る前に、Apache Sparkの概要について確認していきましょう。
Apache Sparkとは大量のデータに対して高速に分散処理を行うOSSフレームワークです。APIとしてはPython, Java, Scala, R などのプログラミング言語が用意されています。大規模データを扱う分散アプリケーションを開発する際にはSparkの利用が必ず検討されるといってもよいでしょう。
類似の分散処理フレームワークとしてHadoopがありますが、HadoopはJavaで書かれているのに対して、SparkはScalaで書かれています。また、HadoopとSparkの大きな違いとして、HadoopではMapReduceにおける入出力のたびにストレージにアクセスする必要があったのに対して、Sparkではデータをメモリに保存することで高速化を図っています。これはインメモリ処理と呼ばれ、機械学習などのように入出力処理が頻繁に発生するようなアプリケーションでは実行性能が100倍程度改善することもあります。
Apache SparkではSpark MLという機械学習ライブラリが備わっているのも特徴です。これによって、ユーザは複雑な分散処理を考えることなく、高速で動作する機械学習手法を実装することが可能です。
SparkML以外にも、Spark上で使える機械学習パッケージがいくつかあるので詳しく知りたい方は別記事を参照してみてください。
hktech.hatenablog.com
Python vs Scala
Sparkを扱う際に、PythonとScalaのどちらを選択すればよいのでしょうか。それぞれのメリットとデメリットを比較していきます。
実行速度
まずは、PythonとScalaを実行速度の観点で比較します。
平均的に、ScalaはPythonより約10倍の速さで実行することが可能です。Scalaは実行時にJava Virtual Machine (JVM) を使用するのに対して、Pythonは動的型変換を伴うインタプリタ言語であるため、その実行速度の差は歴然です。さらにSparkのライブラリはすべてScalaで書かれているため、Pythonでこれらを使用しようとすれば、Scalaそのものでライブラリを扱うよりは実行速度が遅くなることは明らかです。
したがって、実行速度の観点ではScalaが圧倒的に優位です。
扱いやすさ
次にPythonとScalaを扱いやすさの観点で比較していきます。
まずは、実装のしやすさという点では、Pythonに圧倒的な軍配が上がります。ご存知の通り、Pythonは学習コストが低いプログラミング言語のひとつとして知られており、データを扱う多くのエンジニアやデータサイエンティストはPythonに慣れているということがあります。一方で、ScalaをマスターするためにはJavaの基本的な理解が必要であるため、情報系出身者ではない多くのデータサイエンティストがここで脱落します。さらに厄介なことに、Javaに習熟しているものでもScalaの特殊な構文に慣れるには時間がかかるといわれています。このようなことから、チーム全体の実装スピードや運用コストという点でもPythonのほうが優れているといえるでしょう。
Scalaの実装が簡単ではないということを説明しましたが、Scalaを扱えることができればSparkのフレームワークをより簡単に活用することができます。SparkのライブラリはScalaのAPIコレクションを活用しているため、これを理解しておけば内部的な動作を把握することができるほか、用途に応じた修正をすることが可能です。また、動的型変換を行うPythonと比較すると、Scalaは静的に型が定義されるため、コンパイル時にエラーを発見することができるという点で安全性が高いです。
結論
実行速度では、ScalaのほうがPythonより早く、扱いやすさという点では、Pythonのほうがやや優勢であるということがわかりました。
結局、PythonとScalaのどちらを使えばよいのでしょうか?
例えば、大規模データを処理してレポーティングをしたいという場合にはPythonが有効です。商用システムでない場合、実行速度は大きな問題ではないため、すばやく実装でき、可視化ライブラリなどが充実しているPythonを選ぶのがおすすめです。特に、機械学習系の案件であれば、データサイエンティストの多くはPythonに慣れているはずなので、こちらを使うのが無難でしょう。
商用のシステムでSparkを活用したい場合、PythonとScalaのどちらを選ぶかは会社の形態やリソース状況によって変わると思います。
事業会社で、大規模データを扱うシステムまたはサービスを長期的に開発する場合はScalaがよいでしょう。学習コストがかかってしまうものの、Sparkを本質的に理解するためにはScalaの理解は欠かせないほか、パフォーマンス観点や最新のSparkライブラリにアクセスしやすさからもScalaを選択することが賢明です。
一方で、コンサルや短納期での実装が求められるような会社においてはPythonを選択するのがよいでしょう。特に、受注をするような場合は保守がしやすく、実装できる人材が多いプログラミング言語を選択することが一般的であり、Sparkにおいてもこれは当てまります。
コンサルでデータサイエンティストとして働く
コンサルティングファーム(会社)におけるデータサイエンティストの求人が近年増加しています。かつては経営戦略などに力を入れていた外資系コンサルティングファームや、大規模なシステム開発などに強みがあった IT 系コンサルティング企業も、デジタル領域でのデータを活用したビジネスに大きな期待を寄せています。本記事ではコンサルタントとデータサイエンティストの役割の違いについて触れながら
- コンサルでデータサイエンティストとして働くために必要なスキル
- データサイエンティストが求められている理由
ということについて、実際にコンサルでデータサイエンティストとして働いている立場からご紹介します。コンサルにデータサイエンティストとして入社したい就活中の学生や、転職を考えている方にとって少しでも参考になれば幸いです。
目次
- データサイエンティストとは
- データサイエンティストの分類
- データサイエンティストに必要なスキル
- コンサルでデータサイエンティストが求められる理由
- データサイエンティストとしてコンサルに就職する
- まとめ
データサイエンティストとは
データサイエンティストの定義は個人や企業によって解釈が様々となっています。専門職としてのデータサイエンティストの役割は、統計学または機械学習 ×プログラミングによる課題解決をすることであると考えています。
Excelでピボットテーブルを組んでクロス集計をしたり、BIツールでユーザーの行動を解析するといった仕事もデータアナリティクスの重要な仕事ではあるものの、これらはコンサルティングファームのコンサルタントであれば順当に持っているスキルであるため、このような仕事を専門に行う職種は本記事におけるデータサイエンティストのスコープ外とします。
データサイエンティストの分類
データサイエンティストとは大きくデータアナリストと機械学習エンジニアの2種類の職種に分けて考えることができます。
データサイエンティストと機械学習エンジニアは別物として解釈する場合もありますが、コンサルでははっきりと区別されていないことが多いです。そもそもコンサルティングファームにおいては、データアナリストの方が機械学習エンジニアよりもはるかに数が多いというのがその理由であるともいえます。しかし、人工知能を画像認識システムやチャットボットのサービスなどに実装していくような案件が増えつつある昨今のコンサル界隈では、後者の機械学習エンジニアへの需要も高まっています。ここでは、データアナリストと機械学習エンジニアの違いについて説明していきます。
データアナリストとは、データ分析で得た示唆を通してビジネス上の意思決定を支援する職種です。彼らはクライアントの業務やサービスを深く理解し、クライアントと密にコミュニケーションをしながら分析を企画、設計、実行していきます。場合によっては、データ分析で得た示唆を施策に落とし込んでいくサポート役を担うこともあります。
機械学習エンジニアとは、サービスやシステムに機械学習を用いた機能を実装していく職種です。彼らは機械学習モデルを商用のサービスやシステムに耐えうるレベルで実装を行います。人工知能やAIと言われるようなシステムの開発は彼らが担っていると考えてよいでしょう。
これらの2つの職種は、重複があるものの求められているスキルが微妙に異なります。データサイエンティストに必要なスキルにはどういったものがあるのでしょうか。
データサイエンティストに必要なスキル
データサイエンティストに必要なスキルは、一般的に以下の3軸で考えることができます。
優れたデータサイエンティストはこの三角形に示されたスキルを一定レベルで満たしていることが条件となります。機械学習・統計はデータアナリスト及び機械学習エンジニアの両方に必要な必須スキルであるものの、データアナリストは左側のビジネス寄り、機械学習エンジニアは右側のエンジニアリング寄りといったように、多少のスキルの偏りがあることが一般的です。
① 機械学習・統計のスキル
機械学習・統計のスキルとは、データを適切に解釈し、様々な機械学習や統計的手法のなかから問題解決に結びつくものを取捨選択し、実装・分析を進めていく力です。こちらはデータサイエンティストとして当然持っておくべきスキルであり、これが欠けている場合は他のエンジニアやコンサルタントとの違いが無いと言えるでしょう。基本的な数学の知識から、統計学・機械学習に関する知識に加え、最新の論文を読解するリサーチ力や特定の分野(自然言語処理、画像認識、異常検知、時系列データなど)に関する理解など、多くが求められています。しかし、データ分析のみで価値を生み出すことは年々難しくなっているため、近年では機械学習や統計のスキルが突き抜けているからといって、一流のデータサイエンティストを名乗れるような状況ではなくなってきています。
② エンジニアリングスキル
エンジニアリングスキルとは、プログラミングやサーバ・データベースなどのインフラに関する知識をはじめとしたスキルを指します。イメージとしては、情報工学科の授業で学ぶような内容に加え、実務で使用するWebフレームワークや、AWSやGCPなどのクラウドサービス、ビッグデータを扱うソフトウェア(Spark, Hadoop, Hive)に関する知識が求められています。
③ ビジネススキル
ビジネススキルとは、データ分析を通して顧客に価値を提供するスキルを指します。事業会社であれば自社サービス、コンサルであればクライアントのサービスやドメインについて深く理解した上で、社内外とコミュニケーションをとりながらデータアナリティクスプロジェクトを円滑に進めることが求められています。また、データ分析を完璧に理解していないような方に対して、分析の方針や結果をわかりやすく説明するといった能力も必要です。
コンサルでデータサイエンティストとして働く場合、高いビジネススキルは当然のように求められることが多いです。機械学習・統計やエンジニアリングのスキルについては、関わる案件によって求められるレベルに大きな幅があります。案件ごとに技術を素早くキャッチアップできるような高い学習意欲や、手戻りが発生しないように分析を設計できる力が重要視されるといってよいでしょう。
コンサルでデータサイエンティストが求められる理由
データサイエンティストという職種は、幅広いスキルセットと深い知見が求められるということがわかりました。このような役割が、なぜいまコンサルティングファームで求められているのでしょうか。
コンサルでデータサイエンティストが必要とされている理由について考えていきます。
コンサルタントとは従来よりクライアントの課題に対して、深い知見と高いスキルによって解決策を提示し、変革を推し進めるという役割を担っています。コンサルにおけるデータサイエンティストはデータ分析という強力な武器をもったコンサルタントです。
データ分析が課題解決のひとつの手段として確立した背景には、冒頭でご紹介した通り、国内・国外のコンサルティングファームの売上の多くが経営・戦略コンサルティング事業から、デジタルやITといったドメインでのソリューション提供といった事業にシフトしているということがあります。そのような状況のなかで、昨今のデータ分析や人工知能ブームが火をつける形で、データ分析や機械学習システムの開発に関連する案件が急激に増えています。例えば、従来ではExcelなどで行っていた要因分析は、PythonやRによる多変量分析に取って代わられたり、多くのコンサルティングファームが得意としていたオペレーションの自動化は、機械学習を含むアルゴリズムによってより高度化されています。
また、より上流の意思決定に携わるコンサルティングにおいてもデータという武器は極めて有効です。クライアントの役員になにかを提案しようとするとき、その業界に関する知識では到底勝つことができません。しかし、データによる示唆を説明すれば新たな発見を与えることができます。客観的な情報であるデータとクライアントのドメイン知識を繋ぐ役割として、データサイエンティストが必要不可欠な存在となっています。
データサイエンティストとしてコンサルに就職する
コンサルティングファームでいかにデータサイエンティストが求められているかということが伝わったかと思います。読者の方の中には、データサイエンティストとして就職先を探している学生の方や、転職先の候補としてコンサルでデータサイエンティストを視野に入れている方もいるでしょう。
データサイエンティストは多くのスキルや知識を必要とする職種です。しかし、就職や転職をするタイミングですべてのスキルが必要であるというわけではありません。多くの業界でデータサイエンティストが不足している状況にあり、未経験に近い形で採用される方も会社によっては一定数いると聞きます。コンサルティングファームでは、多くの場合にプロジェクトにいきなりアサインされることが多いため、最低限のスキルとして以下は身につけておきたいです。
私自身は paiza というオンライン学習サイトを中心に python を学びました。現在では、UdemyやAidemyといったデータ分析や機械学習プログラミングに特化したオンラインコースを提供するサイトも増えてきているので、一通りやってみるというのもよいかもしれません。上記スキルに加えて、学習意欲が最も大切です。これがあればコンサルティングファームでもやっていけるでしょう。
データサイエンティストとしてコンサルで働くメリット
データサイエンティストは多くの会社で求められていますが、コンサルでデータサイエンティストとして働くメリットとして、多様な業界のデータ分析プロジェクトに触れることができるということがあります。また、プロジェクトベースで動くため、自らが立ち上げメンバーとなってより実践的なスキルが身につけることができるという利点もあります。
一方で、多くのコンサルティングファームでは分析だけでプロジェクトが終わってしまい、実装に入れないケースも多々あります。先にも述べた通り、まだまだ機械学習のエンジニアリングが強くない会社も多く、開発は外注していることも多々あります。
したがって、現時点でデータサイエンティストとして機械学習エンジニア寄りのスキルを伸ばしていきたい方に、コンサルでデータサイエンティスト職に就くことは強くおすすめできません。そのような方は、ウェブ系のサービスを持ったメガベンチャーで働くほうが、エンジニアリングスキルを成長させていくことができるように思います。(あくまで、個人的な意見です)
まとめ
コンサルティングファームでデータサイエンティストとして働く立場から、データサイエンティストという職種の役割や、データサイエンティストが求められている背景についてご紹介しました。データサイエンスに必要なスキルは多岐にわたりますが、コンサルティングファームではプロジェクトごとに必要なスキルを身につけていくのが一般的です。本記事を読んで、データサイエンティストという職種に興味を持っていただける方がいれば幸いです。
pandasのTimestampで決まった範囲の時刻リストを作る
Python で日時関連のデータ操作をするときにdatetime モジュールを使用されている方も多いと思いますが、pandasを使ったTimestamp関連の操作が便利なので個人的にはおすすめです。本記事は時刻を含むデータを処理する際に、決まった範囲の時刻リストを作りたいというときに見返すためのメモ記事となります。
時刻リストとは次のようなイメージです。
['2018-12-19 08:00:00+00:00', '2018-12-19 08:01:00+00:00', '2018-12-19 08:02:00+00:00', '2018-12-19 08:03:00+00:00', '2018-12-19 08:04:00+00:00']
ある時刻範囲のループをまわして、なにかしらの処理をしたい場合などにご活用ください。
現在の時刻を取得
Python での実装をご紹介します。
まず、次のように現在の時刻を取得します。
$ time = pd.Timestamp.now(tz='GMT').floor(freq='T')
このとき、用途にあわせて時刻のタイムゾーンを指定することができます。
とします。
また .floor を指定することで細かい時刻の端数を丸めることができます。
ここでは、freq=’T’ としているので分単位に丸めています。(ちなみに H が1時間単位、Dが1日単位になります)
このように、GMTタイムゾーンで現在時刻を取得することができました。
$ time Timestamp('2018-12-19 11:02:00+0000', tz='GMT')
時刻リストの取得
時刻リストを取得します。
今回は、現在の時刻の2分前から、現在の時刻の2分後までの時刻リストを取得したい場合を考えます。
ここではpandasの date_rangeメソッドを使って配列を作っていきます。
$ time_range = pd.date_range(pd.Timestamp(time, tz='GMT') - pd.offsets.Minute(2), pd.Timestamp(time, tz='GMT') + pd.offsets.Minute(2), freq='T')
pandasの date_rangeでは、開始時刻、終了時刻、周期を引数に指定します。
今回は分単位のリストがほしいので freq=’T’ としています。
また時刻の指定においては、pd.offsets を使用して時間単位で分数を足したり引いたりしています。datetimeモジュールなどと比較すると、かなり直感的に時刻を加算・減算することができます。
ちなみにdatetimeモジュールでは下記のように記述する必要がありました。
$ from dateutil.relativedelta import relativedelta $ dt + relativedelta(minutes=1)
実際に取得したリストをみてみましょう。
$ time_range ['2018-12-19 11:00:00+00:00', '2018-12-19 11:01:00+00:00', '2018-12-19 11:02:00+00:00', '2018-12-19 11:03:00+00:00', '2018-12-19 11:04:00+00:00']
現在時刻の11:02から前後2分の時刻リストが取得できていることが確認できました。
Timestamp型から UNIX time に変換
pandas の Timestamp型データは簡単にUNIX timeにも変換することができます。
取得したリストを一気に変換したい場合は、リスト内包表記を使って次のように変換可能です。
$ [t.value // 1000000 for t in time_range] [1545217200000, 1545217260000, 1545217320000, 1545217380000, 1545217440000]
まとめ
pandas の Timestamp で時刻リストを作る方法について簡単に紹介しました。特定の時刻範囲のループをまわす処理を書きたいときには、本記事でご紹介したpandasのTimestampを利用してみてはいかがでしょうか。
【3D物体検出論文】Orthographic Feature Transform for Monocular 3D Object Detection をまとめた
3D object detection (3D 物体検出) に関する2018-2019期の最新の論文『Orthographic Feature Transform for Monocular 3D Object Detection』*1について読んでまとめました。
3D Object detection とは、自動運転などにおいて 3次元空間における物体の位置情報を画像データから予測する物体検出タスクです。本記事では、3D object detection の概念について通常の物体検出と比較しながら紹介した後に、提案された最新の3D物体検出手法について解説していきます。
目次
3D Object detection とは
3D Object detection (3D 物体検出) とはどういったものなのでしょうか。実際の予測画像を紹介しながら、ほかの一般的な画像認識タスクと比較をしていきます。
画像認識タスクには一般的に以下の4種類があります。
- Classification(分類)
- Classification + Localization(分類 + 位置推定)
- Object Detection(物体検出)
- Semantic segmentation(領域分割)
3D Object detection はこれらのいずれにも含まれない新たな画像認識タスクとして、近年注目され始めています。
通常の物体検出 (2D Object detection) は様々な用途におけるニーズを伸ばしており、多くのアプリケーションで実用化されています。しかし、自動運転などにおいては通常の物体検出では不足している部分があります。例えば、下図の左画像のような2次元の物体検出では画像内に自動車が映っていることはわかりますが、画像に映っている自動車までの距離情報を認識できないという問題があります。
そこで、物体の奥行き情報も考慮した3D Object detection(3次元物体検出) が登場しました。3D Object detection とは、物体の3次元空間における位置情報(3次元の直方体の位置、大きさ、角度)を予測するタスクです。
自動運転などでは、従来 LiDARと呼ばれる光を用いたリモートセンシング技術を用いて周辺の車両の位置推定を行っていました。
画像: https://medium.com/@jhkoh/object-detection-with-lidar-point-cloud-algorithm-94a241fd3f49
しかし、LiDARが精密機械ゆえに自動車搭載に不向きであることや、安いものでも50万円程度と高価であることから、カメラ画像から 3D 空間の物体検出を行いたいというニーズが高まっています。
このような理由から、カメラ画像による 3D Object detection タスクが誕生しました。
論文の要旨
3D Object detection の概念をお伝えしたところで、ここから論文『Orthographic Feature Transform for Monocular 3D Object Detection』の解説に入っていきたいと思います。
本論文の特徴は以下の通りです。
- 1台のカメラで撮影した画像から 3D Object detection を行う
- 2次元画像空間における特徴を現実の 3D 空間にマッピングすることで3次元空間の特徴を捉える
- 3D 空間における特徴マップに対して Orthographic space(正投影空間)に変換する機構を加えることで計算量削減
本論文は、2018年11月に arxiv に登場した時点では 1台のカメラ画像による 3D 物体検出手法で State-of-the-art を達成しています。つまり、共通のデータセットで評価を比較した際には最も良い精度が出ているということになります。
3D 物体検出までの流れ
本論文の提案手法について、ネットワークの学習および推論までのステップについて解説していきます。
提案手法では、複数のネットワークを組み合わせた大きなネットワーク構成となっています。共通の損失関数からすべてのネットワークの重みを学習することができることから、本ネットワークは End-to-end network であるといえます。
提案手法のネットワークアーキテクチャは下図の通りです。
この図に書かれている各ネットワークの詳細について、ひとつずつ解説していきます。
ResNet による特徴抽出
はじめに、画像が入力される最初のネットワークについて説明いたします。
ここでは、一般的な画像認識タスクでも多く使われている ResNet という Convolutional Neural Network (CNN) に画像を入力し、入力画像の特徴マップを抽出します。
このとき、入力画像に対してマルチスケールな特徴マップを抽出することで、画像の大まかな特徴から細かな特徴といった多様な特徴を捉えた特徴マップを得ることができます。
画像特徴マップを 3D 空間へマッピング
提案手法では、現実空間の特徴をより捉えるために画像空間ではなく 3D 空間で物体検出を行います。ここでは1つ目の CNN で抽出された特徴マップを 3D 空間にマッピングしていきます。
画像の最小の解像度はピクセルで表されるように、筆者らは現実の 3D 空間の最小の解像度をボクセルで表しています。
1つのボクセルを1辺の長さが r の立方体だとすると、カメラで撮影した立方体のボクセルは画像空間内では下図のような六角形に映ります。
ボクセルの中心座標を (x, y, z)、カメラの位置を()、カメラの焦点距離を fとすると、画像空間内に映るボクセルのバウンディングボックス座標は下式で求めることができます。
ボクセルが画像空間内でどのような映るかがわかったところで、画像空間における特徴マップを 3D 空間にマッピングしていきます。
中心座標が (x, y, z) のボクセルの特徴マップ g(x, y, z) は、上記で求めたバウンディングボックスに含まれる範囲の特徴マップに対して Average pooling(平均プーリング)をかけることで求めることができます。
特徴マップのテンソルを繰り返し足し合わせる処理は計算量増大の原因になってしまいます。そこで、提案手法では Integral images(積分画像)による高速化を図っています。ピクセル (u, v) の Integral map を F(u, v) は、再帰関数の利用により下式のように表すことができます。
求めた積分画像を用いると、ボクセルの特徴マップ g(x, y, z) は下式のように書き換えることができます。
積分画像については、こちらの方の記事を読んでみるといいかもしれません。
画像処理 Integral Image(積分画像) - のんびりしているエンジニアの日記
Orthographic Feature Transform(正投影空間への変換)
3次元空間に特徴をマッピングすることで 3D 空間の情報を抽出することができました。しかし、このまま 3次元空間の特徴マップを用いて物体検出をしようとすると計算量が膨大になってしまうことは明らかです。
そこで、提案手法では 3次元の特徴マップを高さ方向で圧縮して 2次元にマッピングしています。これを Orthographic Feature Transform と呼んでいます。
実空間にマッピングした特徴マップ (Voxel features) のy軸方向の高さを Hとすると、正投影空間における特徴マップ h(x, z) は下式で求めることができます。
求めた正投影空間における特徴マップ h(x, z) を再び CNN に入力し、出力に対して Confidence map、位置、大きさ、向きに関する 4つの損失関数を最小化するようにネットワーク全体を学習していきます。
画像空間ではなく実空間に対応する特徴マップを入力するため、カメラから遠い物体をカメラから近い物体と同様に扱うことができるというのが提案手法の大きな特徴です。
3D 物体の位置推定
物体の位置推定ステップでは一般的な背景・物体の分類問題を解く手法ではなく、物体の中心座標の存在確率を表す Confidence map を回帰する手法を利用します。
下記の中心座標を持つ N 個の既知の物体(学習データ)があるとすると
正投影空間における点(x, z) の ground truth Confidence score は次のガウス関数で表現することができます。
ここで定義した ground truth Confidence map と予測した Confidence map の差を l1 損失関数で表し、学習時にはこの損失関数を最小化するように学習していく。
さらに、位置・大きさ・向きについても損失関数を用意することで精度向上を図ります。
評価
KITTI の 3D Object detection データセットを用いて学習・テストを実施し、評価を行っています。
KITTI データセットの中身については、次の方がまとめてくださっています。
評価実験は下記の諸元で実施しています。
*Features | |
Front-end network | ResNet-18 |
Feature map scales | 1/8, 1/16, 1/32 |
3次元空間のグリッドサイズ | 80m × 4m × 80m |
グリッド解像度 r | 0.5 m |
Topdown network | 16-layer ResNet |
Data Number (Training, Validation) | 3712, 3769 |
Data augmentation | Random cropping, scaling, flipping, camera parameters |
Training epochs | 600 |
物体検出結果を画像で確認していきます。ご覧のとおり、画像上に正投影空間に投影した Confidence map が描画されているのが確認できると思います。また、bird-eye's-view(鳥瞰図)でみると、画像内の車両位置と対応するように、Confidence mapで描かれた円がプロットされていることがわかります。
定量的に結果を確認していきます。ここでは、カメラを2台使った従来手法である
3DOP*2 と、1台のカメラ画像を使った従来手法であるMono3D*3を比較します。
KITTI ベンチマークでは正解と予測の重複が 0.7 以上のものを予測成功と定義されています。
Mono3D と比較すると精度が改善していることがわかります。また、2台のカメラを使用する 3DOP に近い精度を達成しています。特に、物体の重複がある場合や物体が遠方なときの Hard カテゴリでは精度が大きく改善していることがわかります。これは、画像空間ではなく実空間に対応する特徴マップを入力するため、カメラから遠い物体をカメラから近い物体と同様に扱うことが可能だからです。
まとめ
3D Object detection の最新論文についてまとめました。
対象論文『Orthographic Feature Transform for Monocular 3D Object Detection』では単一のカメラで撮影した画像を使って3次元空間における物体の位置情報を検出する 3D 物体検出手法が提案され、2018年末時点での State-of-the-art を達成しました。
まだまだ実用化に向けて精度を改善していかなければいけないフェーズですが、カメラ画像を使った 3D Object detection は今後も注目され続ける分野だと思います。今後も画像認識に関連した新しい手法について調べてまとめていきたいので、ご期待ください。
高い圧縮率を誇るbz2拡張子ファイルを圧縮・解凍する方法
サーバ上やローカルのLinuxで作業していると、直近で必要のないファイルが溜まって容量が不足してしまうことがありますよね。
そんな問題を解決してくれるのが圧縮・展開系のコマンドです。
zipやgzipなどさまざまなコマンドがありますが、それらと比較して高い圧縮率で圧縮できるのがbzip2コマンドです。
bzip2コマンドや、bz2拡張子を持つファイルに馴染みのない方も多いと思いますが、サーバの容量を圧迫したくないときなどにはおすすめなコマンドです。
今回はそんなbzip2による圧縮・解凍コマンドを備忘録としてまとめておきます。
目次
bz2ファイルへの圧縮方法
bzip2 コマンドによる圧縮方法は次の通りです。
$ bzip2 compression.log
圧縮後は以下のように拡張子.bz2を持つファイルに圧縮されます。
compression.log.bz2
圧縮処理自体に時間はかかりますが、ファイルによっては50倍以上の小ささに圧縮することができます。
また、ディレクトリ(フォルダ)ごと圧縮したい場合は以下のように圧縮することができます。
tar cvjf compression.tar.bz2 logs/
bz2ファイルの解凍方法
bz2拡張子を持つファイルの解凍方法は2通りあります。
bunzip2コマンドを使う場合は以下の通りです。bunzip2は解凍専用コマンドなので特にオプションは必要ありません。
$ bunzip2 compression.png.bz2
bzip2コマンドを使う場合は以下の通りです。d オプション (decompression) をつけることでファイルを解凍・展開することができます。
$ bzip2 -d compression.png.bz2
さきほどディレクトリごと圧縮する方法を紹介しましたが、このような場合の解凍方法は以下の通りです。
$ tar xvjf compression.tar.bz2
まとめ
bzip2 コマンドを使ったbz2拡張子ファイルの圧縮・解凍方法について紹介しました。さまざまな圧縮コマンドがありますが、Linux環境ではbzip2をおすすめします。実際の業務では、サーバの容量に制約条件があったりするので覚えておいて損はないと思います。容量があふれそうだけどファイルを消したくない、そんなときに試してみてはいかがでしょうか。
SSH先でJupyter notebook を使用する方法
Raspberry Pi や AWS EC2など、ローカルからリモートサーバに接続してPythonのプログラムを書く際にJupyter notebookを使いたくなることがあると思います。今回はSSH先でJupyter notebookを立ち上げて、ローカルで使用する方法についてご紹介します。
目次
SSH接続したリモート先の設定
リモートサーバ側の設定方法について確認していきます。
RaspberryPi でJupyter notebookを使用したい方は こちらの記事、AWS EC2で使用したい方は こちらの記事を参考にしていただいてもよいかもしれません。
まずは外部接続環境用のJupyter notebook 設定ファイルを作成します。
mkdir ~/.jupyter
設定ファイル (config file) をviエディタで編集していきます。
vi ~/.jupyter/jupyter_notebook_config.py
ファイルが空の場合は下記の2行を書き込みましょう。
c.NotebookApp.ip = '0.0.0.0' c.NotebookApp.port = 8888
ほとんどの場合、このファイルは空ではないので、該当行を探して編集しましょう。
vi ではスラッシュで文字列を検索できます。先頭のコメントアウト文字列#を消して、上の例のように2行分を編集しましょう。
/c.NotebookApp.ip
編集が完了したらファイルを保存してエディタを終了します。
:wq
最後に、Jupyter notebookを作成したいディレクトリに移動し下記のコマンドを実行します。
jupyter notebook
正常に起動できていれば、下記のようなメッセージが表示されます。
Copy/paste this URL into your browser when you connect for the first time, to login with a token: http://(raspberrypi or 127.0.0.1):8888/?token=abcabc123efg456xyz
リモート側の設定は以上となります。
ローカルの設定
ローカル側では特に設定は必要ありません。
適当なブラウザを開いて、URL欄に先ほどのURLを入力しましょう。
以下の画面が表示されれば無事にすべてのステップが完了です!
まとめ
SSH先でJupyter notebookを使用する方法についてご紹介しました。Python でプログラムを実装したり、データ解析などをしたい場合はJupyter notebookをリモートサーバだからJupyter notebookが使えないというのももったいないので、この記事を参考にしながら設定をしてみてはいかがでしょうか。
参考記事
RaspberryPi の場合
RaspberryPiでJupyter notebookを使う場合の設定方法はこちら
qiita.com
AWS EC2 の場合
AWS EC2でJupyter notebookを使う場合の設定方法はこちら
blog.roy29fuku.com
Pythonでk-NNをフルスクラッチで実装してみた
Scikit-learnを始めとしたパッケージが充実してきているおかげで、データ分析に関わる人もスクラッチから機械学習モデルを実装する機会が少なくなっています。
しかし、機械学習モデルを理解するためにはそのモデルを実装してみるのが一番早いと言われています。たとえパラメータをいじるだけの作業であったとしても、モデルの理解が深い人とそうでない人では、問題解決の質が変わってきます。
本記事では、最も基本的な分類モデルである k-NN (k-Nearest Neighbor) 法をフルスクラッチで実装したのでご紹介します。
目次
k-Nearest Neighbor法
k-Nearest Neighbor 法 (k-NN) は k近傍法とも呼ばれ、分類モデルの中でももっともシンプルに実装できるものとして広く知られています。
k-NNとは、特徴量空間にデータをプロットしたときに、プロットと距離が近い学習データを近いものから順にk個選び出し、それらの学習データのクラスを多数決することでデータのクラスを決定する分類モデルです。
図のように、青四角クラスと赤丸クラスの学習データが配置された特徴量空間を考えます。
k-NNのkは、テストデータ(星型)から何個の近傍点をクラス予測時に考慮するかということを決定するパラメータです。この例の場合、k=3のときは赤い学習データのほうが多いため赤クラスに分類されます。一方で、k=5のときは青のほうが多数となるため、テストデータは青クラスに分類されます。
k-NNをPythonで実装する
k-NNの概要については理解していただけたと思います。実にシンプルなモデルであるため、スクラッチから実装することはさほど難しくないです。それどころか、データサイエンティストであればこれくらいは実装できるのが最低要件だと思います。
シンプルである一方で、テストデータと複数の学習データとの距離をそれぞれ計算する必要があるため、計算量が多いという欠点があります。
こちらが実装したコードです。
import numpy as np import pandas as pd from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import f1_score import time def load_data(): iris = load_iris() return train_test_split(iris.data, iris.target, test_size=0.3) def predict(k, test_plot, X_train, y_train): dist_dict = {} for i, train_plot in enumerate(X_train): dist = np.linalg.norm(train_plot - test_plot) if len(dist_dict) < k: dist_dict[dist] = y_train[i] elif dist < np.max(list(dist_dict)) and len(dist_dict) == k: dist_dict.pop(np.max(list(dist_dict))) dist_dict[dist] = y_train[i] count = np.bincount(list(dist_dict.values())) pred = np.argmax(count) return pred def predict_test_data(k, X_train, X_test, y_train, y_test): pred_list = [] for test_plot in X_test: pred = predict(k, test_plot, X_train, y_train) pred_list.append(pred) return f1_score(y_test, pred_list, average='macro') if __name__ == '__main__': X_train, X_test, y_train, y_test = load_data() start_time = time.time() fscore = predict_test_data(3, X_train, X_test, y_train, y_test) process_time = time.time() - start_time print('F-score: {:.3f}'.format(fscore)) print('Process time: {:.3f} sec'.format(process_time))
実装したモデルをirisデータセットを用いてF値で評価すると、次のような結果となりました。
F-score: 0.978 Process time: 0.118 sec
クラスの分類がうまくいっていることを確認することができました。
k-NNの特徴としてすべての点との距離を求める処理が必要となることから計算量が大きくなってしまうということがあります。そのため、プログラムの実行時間を計測できるような処理を実装しています。今回は何も考えずに最も単純な方法で実装したため計算量がかなり大きくなってしまっています。
Scikit-learnなどで実装されているk-NNは、この問題をできるだけ解決するように実装の工夫がなされています。実装を工夫した際のコードについてはまた別の機会にご紹介できればと思います。
まとめ
k-Nearest Neighbor法をフルスクラッチで実装してみました。まずは計算量などを考慮せずに最低限の精度が出るモデルの実装ができたので、次のステップとして高速化を考えていきたいです。k-NNは最も単純な機械学習モデルのひとつです。この記事を参考にしつつ、一から実装してみてはいかがでしょうか。
関連記事
決定木分類器をフルスクラッチで実装した際の記事です。
hktech.hatenablog.com