投稿

5月, 2019の投稿を表示しています

グルメ画像自動分類器を作った話

イメージ
こんにちは、ぐぐりら(<a href="https://twitter.com/guglilac">@guglilac</a>)です。 今回は、最近趣味で作っていた飯テロ画像自動分類器についての記事を書こうと思います。 飯テロ画像とここで呼んでいるのはご飯とかお酒の画像のことです。 僕のTwitterをフォローしてくださっている方はご存知と思いますが、僕はよく美味しいお店を開拓してよくご飯やお酒の写真をとってツイートしています。 技術関連のアカウントとして運営していこうというつもりなのですが、半分くらいはこの飯テロツイートに費やされている現状です。 そんな飯テロ系エンジニアのぐぐりらですが、どこかマメなところがあるので撮ったグルメ画像をgoogle driveにいちいちアップロードしてiphoneから削除するということをこつこつやっています。 大学はいってからなのでもう5年以上はこの生活をしているんですね、今気づいたけど恐ろしい。 そこで今回は「退屈なことはpythonにやらせよう」ということで、この「ご飯やお酒の画像だけgoole driveのグルメフォルダにアップロードする」 という処理を自動化します。 いろいろやってみた結果、最終的にやったことはかなり簡単なことだけだったので大したことはないのですが、せっかくなのでまとめてみます。 ## 構成 iphoneで撮影した画像を分類してgoogle driveのグルメフォルダにuploadするわけなので、 * iphoneで撮影した画像をとってくる * 画像を分類する * 分類した画像をgoogle driveに入れる ぐらいのcomponentに分解しました。 iphone上で機械学習モデルを回すこともできるのでしょうがそこまでしたくなかったし、どこかサーバーを借りてそこでモデルを回すなどもお金かかりそうだったので見送り。 今回は自分のPCに画像を持ってきて分類することにしました。 iphoneの画像をmacに持ってくる(しかもわざわざそのための操作はしたくない)という部分はgoogle photoを使うことで実現しました。 google photoはgoogle drive上のフォルダとして扱うことができるので、一度iphon

テューキー回帰を実装して実験してみた

イメージ
こんにちは、ぐぐりら(<a href="https://twitter.com/guglilac">@guglilac</a>)です。 前回のロバスト回帰を勉強してまとめてみた記事で、テューキー回帰を解説しました。 ロバスト回帰(フーバー回帰,テューキー回帰)を勉強してみた 今回は理論編ではなく実装編ということで、テューキー回帰を実装して、外れ値を含むような人工データを生成して実験してみます。 ベースラインとして、ただのlinear regressionと比較しています。 ## 実装 pythonで実装しました。 Tukey回帰には、 $$ f_\theta(x)=\theta_1x+\theta_2 $$ を用いました。直線モデルです。 ```python class TukeyRegression: def __init__(self, eta, epsilon=1e-10, iter_num=10000, seed=None): self.eta = eta self.epsilon = epsilon self.seed = seed self.theta = np.random.randn(2) self.iter_num = iter_num def fit(self, x, y): np.random.seed(self.seed) const = np.ones(len(x)) Phi = np.stack([const, x], axis=1) for i in range(self.iter_num): W = self.get_W(Phi, y) theta = np.linalg.solve( np.dot(np.dot(Phi.T, W), Phi), np.dot(np.dot(Phi.T, W), y)) if np.linalg.norm(theta - self.theta) <

One-vs-RestとOne-vs-Oneを実装してみた

イメージ
こんにちは、ぐぐりら(<a href="https://twitter.com/guglilac">@guglilac</a>)です。 今回は、2クラス分類器を多クラス分類器へと拡張する手法である、One-VS-Rest(一対他) とOne-VS-One(一対一)を実装して、 ロジスティック回帰に適用する実験を行ってみます。 ## 多クラスへの拡張 モデルによっては、2値分類しか扱うことができないものがあります。 最小二乗回帰やSVM,ロジスティック回帰など、むしろオリジナルの分類器は2値分類であることの方が多いのかもしれません。 多クラス分類を行う手法として、直接多クラス分類を行うモデルを構築するのが一つの手です。 deep learningの出力層にsoftmaxをいれて、クロスエントロピーを目的関数に持ってくるとか、そんなかんじのがよくある例だと思います。 もう一つ、直接多クラスの分類モデルを構築するのではなく、2値分類を行う分類器をいくつか組み合わせることで多クラス分類を行う手法があります。 それが、今回扱うOne-VS-Rest(一対他) とOne-VS-One(一対一)です。 以下、$C$個のクラスがあるとします。 ## One-VS-Rest(一対他) One-VS-Rest(一対他)は、$C$個の2値分類器を学習します。 一つ目の分類器は、クラス1を正例、その他のクラスを負例とする分類器になるように学習します。 同様に、$i$番目の分類器はクラス$i$が正例に、その他のクラスを負例として学習します。 推論時は、$C$個の分類器全てに予測させて、一番正例である確信度が高いと予測されたクラスを最終的な予測結果とします。 確信度を用いるので、2値分類器には各クラスに属する予測確率(またはそれに比例するなんらかの数値)を出力できるモデルを用いる必要があります。 その他のクラスを負例とする、という部分がRestに対応していますね。 利点としては、クラスの個数だけ分類器を学習すればいいので次に紹介するOne-VS-One(一対一)よりは分類器の個数が少なくて済みます。 短所としては、各分類器の学習に用いるデータの正例負例の割合が偏ってしまうことが挙げられます。 ## One

【論文紹介】Residual Attention Network for Image Classification(CVPR2017)

イメージ
こんにちは、ぐぐりら(<a href="https://twitter.com/guglilac">@guglilac</a>)です。 Residual Attention Network for Image Classification(CVPR2017)を読んだので、まとめてみます。 ## 3行まとめ 画像認識タスクにおいて深いCNNネットであるresnetとかのfeed forwardニューラルネットに、attentino機構を組み合わせることで性能の向上を図る研究. ## contribution * stacked attention module によりresidual attention networkを提案 * 学習をうまく進めるためのresidual attention learningを提案 * bottom-up top-down feredforward attentionをmask branchに使用 ## 関連 se-netの前身のモデルらしい。 SE-netの論文も読んで記事にまとめました。 こちらになります。 Squeeze-and-Excitation Networks(CVPR 2018)を読んだ ## 提案手法 attentnion moduleをいくつか積み上げたものがresidual attention networkである。 moduleの中身はmask branch とtrunk branchがあって、trunk branchはいわゆる今までのCNNの部分。(特徴量を獲得するレイヤー) mask branchはsoft attentnionを計算する部分で、各モジュールごとに計算されて対応するtrunk branchの出力と掛け合わされる。soft attentionである。 掛け合わせる部分をナイーブにやると学習がうまくいかないので、residual attentnion learning を提案している。attentionの部分をresidualにするという工夫。 こうじゃなくて <div class="separator" style="clear: both; text-

【論文紹介】Squeeze-and-Excitation Networks(CVPR 2018)

イメージ
こんにちは、ぐぐりら(<a href="https://twitter.com/guglilac">@guglilac</a>)です。 今回は、Squeeze-and-Excitation Networks(CVPR 2018)を読んだのでまとめてみます。 ## 3行まとめ CNNによって得られる特徴マップをそのまま出力するのではなく、チャンネル間の関係に対して適応的にattentionをかけて重み付きの特徴を出力するSqueeze-and-Excitation Networksを提案。 ## Squeeze-and-Excitation 基本的にはSqueeze-and-Excitationモジュールはattentionといっていいくらい似ている。 resnetとかが吐いた特徴マップを空間方向にglobal average poolingしてチャンネルの長さのベクトルに潰して(squeeze)それをFCレイヤに二回通して(excitation)sigmoidをかけて0~1に正規化して得られるattentionもどきのベクトルをresnetが吐いた特徴マップとchannel-wiseに掛け合わせて重みつけて出力する。 チャンネル間の関係を考慮して重みづけできるのがいいらしい。 計算時間やモデルのパラメータ数的な負担はほぼなく、非常にエコ。実装も楽だしこれで精度が上がるならいいねっていう(というかresnet自体が重量級なのでそれに比べたらっていう) ## 関連 空間方向に関してはあったけどチャンネル間は初めてだぜ、だって 基本的にresidual attention networkと似ている。 ## SE module 全体図はこちら <div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-c2za49pYaJ4/XNToelpgGCI/AAAAAAAAAm4/MxC8QNHz3CkOXVUa5HyfDsXZmtv1MwHcwCLcBGAs/s1600/model.png&qu

ロバスト回帰(フーバー回帰,テューキー回帰)を勉強してみた

イメージ
こんにちは、ぐぐりら(<a href="https://twitter.com/guglilac">@guglilac</a>)です。 今回は、ロバスト回帰についてまとめてみます。 勉強したので整理もかねて。 今回勉強したのはロバスト回帰のフーバー回帰,テューキー回帰についてです。 ## ロバスト回帰とは?? 回帰問題は大丈夫かと思います。 年収とか、明日の気温とか、ある値を予測する機械学習のタスクです。 ロバスト回帰とは、モデルの訓練に用いるデータに外れ値があった場合に、その外れ値の影響を小さくするような学習方法のことを指します。 実際の応用上ではデータセットの中には観測の際に手違いなどから外れ値が入り込む可能性があるので、そういうデータが入っても影響を小さくして最終的に得られるモデルがあまり変わらないと嬉しいよね、というモチベーションです。 単純な二乗誤差($l2$損失)を使う回帰、いわゆる最小二乗回帰では、外れ値の影響が二乗のオーダーで効いてきてしまいます。 $$\sum_{i=1}^n (f_{\theta}(x_i)-y_i)^2$$ ロバスト回帰では、用いる損失の形をうまく設計することで外れ値の影響を小さくしていきます。 ## $l1$損失 一番簡単なロバストになる損失は$l1$損失です。 $$ \sum_{i=1}^n |f_{\theta}(x_i)-y_i| $$ 予測値と正解の値との絶対値誤差を損失に用いるものです。 これにより、外れ値の影響は線形にしか効いてこなくなるため、二乗誤差より外れ値の影響が小さくなります。 $l2$損失よりも$l1$損失の方が外れ値の影響が小さくなるのは、平均と中央値の性質の関係に似ています。 よく年収の例などが挙げられますが、平均年収を計算すると、一部のとても高収入な層の影響を受けて実態よりも高めの値が出ます。 マジョリティをうまく表現できるのは中央値だったりします。 実は、 $l2$損失を最小化することで得られる解は期待値であり、$l1$損失を最小化する解は中央値なので、当然といえば当然ですね。 $l1$損失は外れ値に対してロバストではありますが、逆に外れ値でないどのような点に対してもあまりデータ点を見ないで出力して