irisuinwl’s diary

サークル不思議(略)入巣次元の、数学や技術的なことを書きます。

InceptionV3をfine-tuningしてクリクリ画像分類器を作り、streamlitでwebアプリを作る

題名の通り。 streamlitとkerasで遊んだ。

動画デモ:

環境情報

  • 機械学習モデル作成環境: google colaboratory
  • web app環境: windows 10+anaconda 

InceptionV3をファインチューニングする

下記google colabにて実施。

colab.research.google.com

streamlitでwebアプリを作る

下記githubにコードを格納

github.com

  • WIP: deployしたり、精度あげたり

詰まったところ:

anacondaでconda install tensorflow-gpu kerasすると、tf 2.1.0がインストールされるが、windows環境ではAttributeError: ‘_thread._local’ object has no attribute 'value’というエラーが出る。

実際、下記のissueでも議論されている。

discuss.streamlit.io

github.com

ググると、「tf 1.xに下げろ」という方法が散見されるが、google colabのtfは2.x系なので抵抗がある、また、やっても失敗したので下記のように対応した。

  • AttributeError: ‘_thread._local’ object has no attribute 'value’の対処は下記を追加
import keras.backend.tensorflow_backend as tb

tb._SYMBOLIC_SCOPE.value = True
st.set_option('deprecation.showfileUploaderEncoding', False)
  • さらにValueError: Cannot create an execution function which is comprised of elements from multiple graphs.というエラーが出るが、

これはkerasからインポートしているモデル構築モジュールをtensorflow.kerasにして対処。

InceptionV3の場合は下記のようにimport文を変更して対処した。

from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras import backend as K
from tensorflow.keras.optimizers import SGD

イベント発火時(画像をアップロードしたりチェックボックス操作時など)にstreamlitのコードは再実行される。

そのため、機械学習モデルの再構築を再読み込みが行われて時間がかかる。

これはstreamlitのyoloを使った物体認識webアプリのチュートリアル に、機械学習モデル読み込み時にcacheを使って対処している。

@st.cache(allow_output_mutation=True)
def load_inception_v3(weight_path: str):
    """
    指定パスからパラメータ重みを読込、InceptionV3をfine-tuningしたモデルをloadする。
    """

    ...

    model.load_weights(weight_path)

    return model

参考記事

qiita.com

qiita.com

docs.streamlit.io

aidiary.hatenablog.com

~しょばふぇすで遊ぶデータ分析~ ソシャゲのガチャスクショを画像処理してアイテム出現確率を推定した

タイトルの通り

 

最近ショバフェスにハマっております。

スクショを取りまくっていたのですが、これでなんか遊べないかなと思って、ガチャイベ(いっぱいガチャを回してゲームの便利なアイテムを取得するイベント)でガチャからアイテムが出る確率を推定してみました。(Computer Visionの勉強もしているので、それでもなんかやりたかった)

 

一段落付いたのでcolabに纏めて公開しようと思います。

※画像は引用という形で加工して一部分しか出してませんが、著作権的に問題があったら消します。

 

colab.research.google.com

 

具体的にやったことは以下です。

1. ガチャスクショ画像からガチャアイテム画像の抽出(crop)

2. アイテム画像をヒストグラムで特徴化し、類似度でクラスタリングして特徴空間がどんなものかみる

3. kNNが有効そうだと仮説を立てて、データをラベリングし、kNNで交差検証し、ちゃんと判定できることを確認(まあ、固定画像なんだからそらそうかって感じだけど)

4. 今まで貯めたスクショ画像について3. で作ったモデルを用いてラベリング→確率モデリングをして、確率の推定を行う。

 

想定知識は以下です。

メモ(ベルヌーイ分布、二項分布、カテゴリー分布、多項分布)

良くBernoulli, Binomial, Categorical, Multinomialがごっちゃになって、推定量とかってそれぞれどう関係あるんだっけ? ってなるのでメモしておく

結局はカテゴリ分布も多項分布も最尤推定はそのカテゴリが出た数を全体サンプル数で割れば良いという話であった。

 

ベルヌーイ分布のMLE

http://www-ikn.ist.hokudai.ac.jp/~yasuhiro-suzu/Bernoulli%20Distributin.pdf

 

分布パラメーターの推定(BinomialのMLEが載ってる)

http://lbm.ab.a.u-tokyo.ac.jp/~omori/meiji2/sec5/sec5.html

 

多項分布のMLEとMAP estimation

http://sleepyheads.jp/docs/multinomial_dist.pdf

 

multinomial, categoricalの違い

https://r9y9.github.io/blog/2013/07/31/multinomial-categorical-diff/

 

Bernoulli distribution(enwiki)

https://en.wikipedia.org/wiki/Bernoulli_distribution

 

Categorical distribution(enwiki)

https://en.wikipedia.org/wiki/Categorical_distribution

 

 

とんかつDJあげ太郎がヤバすぎた

はじめに

最近とんかつDJあげ太郎を読みました。アニメも見ました。名前は知っていたのですが、最近やっと読みました。

 

結果、めちゃくちゃ面白くて、ものすごい衝撃を受けました。

この記事では、その面白さを語ります、あとオマケ程度にアイマスアイカツの話をしたりします(?)

 

web漫画ならばジャンプ+で4巻まで無料で見れます。

https://shonenjumpplus.com/episode/10833497643049550155

 

アニメはニコニコDアニメ会員であれば全話見ることができます。(一話なら無料で見れます)

https://www.nicovideo.jp/watch/so28641399

 

絵はすごく人を選ぶ感じですが、話は正統派ジャンプ、正統派音楽モノ作品です。個人的音楽・芸能モノで好きな作品上位はアイカツアイマス、プリパラ、ラブライブ、SB69、少年ハリウッドでしたが、そのレパートリーに入るレベルの作品でした。

あと漫画を買わなかったことを後悔してます。あの感動をもう一度噛み締めたくて何度も読み返したくなるし、単行本の解説などがあったので…

 

続きを読む

アズールレーンをN倍楽しむために資料をまとめる

最近アズレンアズールレーン)にハマりました。

きっかけはアニメみてキャラが可愛かったから(安直なオタク)

アニメに釣られてアプリを遊んでみると、ジャンルはSTGで好きなゲーム性で、更に周回がきつくならないためにオートモードが完備されており非常に楽しんでプレイでき、ハマりました。

(オートのAIが、人力でプレイするよりは弱いが、ストレスなくプレイできるのでゲームAIのデザインがかなり秀逸なのも惹かれた点でした)

さて、この記事ではアズールレーンを楽しむ(?)ために史実の艦船資料を探してみた結果ならびにそのメモを記録します

(これでアズレンと学ぶ系の同人誌とか作れたらなぁとか考えたり)

続きを読む

ABC 139 Eが解けた話

戦いたい選手をキューで詰めていってマッチングしたら戦わせる。 対戦(i,j)をグラフとしてDFSという方法がeditorialに載っているが、pythonでそれを表現したらTLEした。 (pythonでグラフ構造を効率よく表現する方法を知らなさすぎる) この方法で普通に解けたと思ったけどwhileループ中で抜けた場合の初期化処理をしていなくてWAした。

from unittest.mock import patch

testcases = """3
2 3
3 1
1 2
""".split('\n')

def solve():
    N = int(input())
    tournament = [list(map(lambda x:int(x)-1, input().split())) for _ in range(N)]
    map_que_tournament = {i:[] for i in range(N)} # player iがjと戦いたがってる
    competition_num = -1
    que_player = list(range(N)) #それぞれ戦えるプレイヤーをqueueにつめていく
    
    while que_player:
        day_process_flag = False
        new_queue = [] # 次のステップ更新用のqueue
        # print(que_player)
        for player in que_player:
            if tournament[player]:
                # トーナメントの対戦希望表から抜き出す
                match_player = tournament[player].pop(0)
                # ぶじマッチング相手が見つかったら
                if map_que_tournament[match_player] and player == map_que_tournament[match_player][0]:
                    # print(player, match_player)
                    day_process_flag = True
                    new_queue.append(match_player)
                    new_queue.append(player)
                    map_que_tournament[match_player].pop()
                else:
                    map_que_tournament[player].append(match_player)

        # 戦える人がいた場合に一日進める
        if day_process_flag:
            if competition_num < 0:
                competition_num = 1
            else: competition_num += 1

        que_player = new_queue
        
    # 途中でやめた場合
    for t in tournament:
        if t:
            competition_num = -1
            break

    print(competition_num)

with patch('builtins.input', side_effect=testcases):
    solve()

TLEしたグラフDFSしたpythonコード Nを最大にすると8秒くらい最初の読み込みでかかってしまう

def solve():
    fix_index = lambda x,y: (x,y) if x < y else (y,x)
    N = int(input())
    tournament_graph = {} # N^2
    tournament_graph_dom = {} # N^2
    search_vertex = {}
    max_path = -1
    
    for i in range(N):
        vertex_pre = None
        for j in map(int, input().split()):
            j = j-1
            vertex = fix_index(i,j)
            if vertex not in tournament_graph: # vertex not in tournament_graph
                tournament_graph[vertex] = []
                tournament_graph_dom[vertex] = []
                search_vertex[vertex] = True
            if vertex_pre:
                tournament_graph[vertex_pre].append(vertex)
                tournament_graph_dom[vertex].append(vertex_pre)
                
            vertex_pre = vertex
    
    vertices = []
    for vertex in tournament_graph_dom:
        # 点が存在して、入ってくる辺が無いもの
        if search_vertex[vertex] and (not tournament_graph_dom[vertex]):
            vertices.append(vertex)
            search_vertex[vertex] = False
    
    while tournament_graph:
        # ここで探索する
        new_vertives = []
        if vertices:
            # print(vertices)
            if max_path < 0: max_path = 0
            for v in vertices:
                while tournament_graph[v]: 
                    cod = tournament_graph[v].pop(0)
                    tournament_graph_dom[cod].pop(0)
                    # つぎ検索する箇所を選定
                    if search_vertex[cod] and (not tournament_graph_dom[cod]):
                        new_vertives.append(cod)
                        search_vertex[cod] = False
                    
            max_path += 1
        else:
            # DAG ならばdom(v) = \emptysetとなるvが存在しない
            break
            
        vertices = new_vertives
    
    print(max_path)
    
solve()

英語を学ばないと死ぬ

こんにちは、いりすです。

 

最近は英語の勉強をしています。

NHKの英会話ラジオを聞き、シャドーイングをしています。

英語を学ぶ理由は、海外のデータサイエンティストと英語でミーティングをしているからです。

私はデータ分析も行うエンジニア(AIエンジニアやデータサイエンティストとはちょっと違うキャリアだと思う)をしているのですが、

データ分析市場は日本より海外の方が利益を産んでいると感じるし(kaggleの主催企業を見ていると実感するが、ここはマーケティングレポートなどを示したい)、それまでデータ分析をしてきた経験を海外支社のデータサイエンティストと協力して新たな取り組みができないかということでミーティングが始まりました。

 

自分がエンジニアとして成長できる機会なので絶対に逃したくないです。

しかし、私は、英語で情報収集しドキュメントを見ることはできますが、喋ることやリスニングは全くで、いざ会議に参加しても一切しゃべることはできませんでした。

ミーティングで発言、アウトプットしない人間はいる意味ある? と感じることが多いですが、いま自分がその立場になることを実感し、そしてこのままでは成長の機会を逃してしまうのではないかと思っております。

なので、英語の勉強を頑張ってますし、今度オンラインの英会話に挑戦しようと思っております。

 

まさか自分が英会話に挑戦するとは思ってなかったし、「人間万事塞翁が馬」というやつですね。

自分のスキルセットがあがることは楽しいです。SLGRPGのオタクなので。

私は強くなるので、成長を楽しみにしていてください(厚顔)

 

自分は高校生のときに数学を好きになって大学で研究するとは思ってもなかったし、

社会人になって数学の道は閉ざされたと思いましたが、製品開発に数学的な知識を盛り込むことは多く、また組織として認められるとは思ってもなかったです。そして、また研究できることになるとは思ってもなかったです。

意外に人生思いもよらない方向にいくし、なんとかなりますね。そして、学ぶことはとても楽しいんですよね。