Google Colaboratory できゅうりを選別する。
最近少しずつ趣味でディープラーニングを勉強しているのでそのアウトプットとして2年ほど前に話題になったキュウリを仕訳してみます。
モチベーション:写経だけじゃなくてもう少し踏み込んだところで機械学習をしたかった。
- 使用するモジュール:Keras
- 使用するアルゴリズム:CNN
jupyter notebookでゼロから作るディープラーニングを写経していたのですが、思った以上に学習に時間がかかることがわかりめちゃくちゃだるくなったため、 似たようなサービスであるGoogle Colaboratoryを利用してディープラーニングやってみます。
まだまだ勉強中につき深いことはわかりませんが、なんとなくでも実装できないかしら?と思ってやってみた。結果としてできたけどふわっとしてる
わかったこと:
- Google Colaboratoryの使い方がわからなかったため、めちゃくちゃつまづいた。
- さらにきゅうりの画像の読み込み方はさっぱりわからなかった。
- 前処理が教科書だとざっくりとkeras.dataset使えとかなんとか書いてあるけど、きゅうりの場合それがそもそもわからなかった。 そこでゼロから作るディープラーニングのMNISTのやつをちゃんと読んだ。 冗談かもしれないがそれでもわからなかったのでさらにcifar-10のやつやQiitaなどを読んだ。そしてほぼ丸々パクった。
わからなかったことがわかったこと:
- 途中の変数の
nb_train_samples
が何なのかわからない。 - CNNのsequentialの実装だがこれはたぶんだけどいろいろ流儀というかモデルの作り方があるみたいだ。今回は畳み込み層が2層と結合層が1層の畳み込みニューラルネットワーク・・だよね?
以下ソース
#まずはファイルをアップロードする。 from google.colab import files uploaded = files.upload()
アップロードするのはGithubからダウンロードしたやつ
ダイアログボックスが出るのでアップロードする。
ファイルの解凍
#ファイルを解凍する。 !tar -zxvf cucumber-9-python.tar.gz
解凍できているみたいだ。
#解凍したファイルを読み込む # def unpickle(f): import pickle fo = open(f, 'rb') d = pickle.load(fo,encoding = 'latin-1') fo.close() return d #訓練データを読み込む nb_train_samples = 2475 x_train = np.zeros((nb_train_samples, 3, 32, 32), dtype='uint8') y_train = np.zeros((nb_train_samples,), dtype='uint8') for i in range(1,5): fpath ='data_batch_' + str(i) batch_dict = unpickle(fpath) data = batch_dict['data'] labels = batch_dict['labels'] x_train[(i-1)*495:i*495, :, :, :] = data.reshape(495, 3, 32, 32) y_train[(i-1)*495:i*495] = labels #教師データを読み込む data = unpickle("test_batch") x_test = data['data'].reshape(495,3,32,32) y_test = data['labels']
次にデータを3つにわける
#処理したデータを3個に分割する。 from sklearn.model_selection import train_test_split x_train1,x_valid,y_train1,y_valid = train_test_split(x_train,y_train,test_size = 0.175)
次はモデルの設計図となるSequentialをデザインする。ここでCNNかRNNかNNかとかそういったいろいろが決まる。
#Sequentialの実装。ほぼコピペ。元画像がMNISTだと28*28*1だがきゅうりの場合は32*32*3なのでそれにあわせて書き換える。 #あと出力層はMNISTの場合10だがきゅうりの場合は9だとかなんとか from keras.models import Sequential from keras.layers import Dense,Dropout,Flatten from keras.layers import Conv2D , MaxPooling2D import keras model = Sequential() model.add(Conv2D(32,kernel_size = (3,3),activation = 'relu' , input_shape=(32,32,3))) model.add(Conv2D(64,(3,3),activation = 'relu')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Dropout(0,25)) model.add(Flatten()) model.add(Dense(128,activation='relu')) model.add(Dropout(0,5)) model.add(Dense(9,activation = 'softmax'))
データをきれいにする。
#データの正則化。なぜやるのかよくわからない。 x_train = x_train.reshape(x_train.shape[0],32,32,3) x_valid = x_valid.reshape(x_valid.shape[0],32,32,3) x_test = x_test.reshape(x_test.shape[0],32,32,3) x_train = x_train.astype('float32') x_valid = x_valid.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_valid /= 255 x_test /= 255 y_train = keras.utils.to_categorical(y_train,9) y_valid = keras.utils.to_categorical(y_valid,9) y_test = keras.utils.to_categorical(y_test,9)
最後に学習とデータの確認。 なんかわからんけど出来ているようだ。
#学習させる。 from keras.optimizers import RMSprop model.compile(loss='categorical_crossentropy', optimizer = RMSprop(), metrics=['accuracy']) history = model.fit(x_train,y_train, batch_size = 120, epochs=10, verbose=1, validation_data = (x_valid,y_valid))
https://colab.research.google.com/drive/1o7gosgj5NytGGAXvjHxlnuXjW9bxk5E2
パクリ元:
spotifyとLast.fmを接続する
Last.fm知っていますか?様々なアプリやソフトウェアから音楽を再生すると専用のソフトをインストールすることで自分の音楽遍歴を見返すことができるWebサービスです。
Spotifyでももちろん聞いた曲履歴をLast.fmに登録することが可能で、設定さえきちんとすれば勝手にたまっていくので重宝して使っていたのですが、Spotifyアプリ内からは5月のアップデートからLast.fmの方に登録出来てなかったみたい。
なんで?とは思ったものの、調べてみるとどうやらそもそもLast.fmというサービス自体知らない方からの問い合わせが多かったらしく、アプリ内でのLast.fmのログインを廃止したとのことでした。
ではLast.fmにはもう登録できなくなったかというとそうでもなく、今度はLast.fm側からの登録が必要となりましたので、それを解説していきます。
1.まずはLast.fmにログインし、「設定」ページを開きます。
ページは右上の自分のアイコンをクリックしたら出てきます。
2.設定内のアプリケーションをクリックします。
一番右のタブです。
3.アプリケーション内の「SpotifyでScrobble」の右の「接続」をクリック
4.Spotifyの画面に代わりますのでログイン後、接続してください。
以上です。ちょっと面倒になりましたが変わらず出来たので安心でした。
PythonでResasAPIにアクセスする
アイデアソンがあるみたいなので・・
さくっとPythonでrequests使って問い合わせてみた。
ここを参考にした。
www.kmiura.net
都道府県表示させるやつよりも少しふみこもうとしたらわからんかったのでメモ
import requests import json def resas_api_request(): api_key = "【API_KEY】" url = "https://opendata.resas-portal.go.jp/" url += "api/v1/cities" head = { "Content-Type":"application/json", "X-API-KEY":api_key } payload = {'prefCode':1} req = requests.get(url,headers=head,params=payload) print(req) json_obj = json.loads(req._content.decode('utf-8')) print(json_obj) return resas_api_request()
みんなで分析しようぜ
ベイズ統計学
図解・ベイズ統計「超」入門 あいまいなデータから未来を予測する技術 (サイエンス・アイ新書)
- 作者: 涌井貞美
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2013/12/17
- メディア: 新書
- この商品を含むブログ (15件) を見る
なんとなく買ってみて読んでいるが、ベイズ更新のやり方だけでも十分に旅館の計数管理には役に立ちそうな気がする。
たとえば宴会の原価を推定するのにベイズ更新を使えば月ごとに結構正確な原価率が推定できるんじゃなかろうかとか
まぁ原価率なんて実際に使用額/売上で算出できるので力技でもいいけど、計画立てるときにはもう少しふわっとしているしね
確率も原価も同じ%だから勘違いしそうになるていうか、ベイズ更新的な手法だとどのような形になるのだろうか?
同じように計画をベイズ的に解くには?なんか色々興味が湧いてきます。
React周りの必要なモジュール
React
- react-dom
Redux
- react-redux
- redux-thunk
React-router
- react-router-dom
- react-router-redux
- history
このあたりの使い方はちゃんと押さえておく。
あとはreduxのreducerでどこまでの処理を書くかってところが知りたい。
これほんとわかりやすかった。
React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)
- 作者: 穴井宏幸,石井直矢,柴田和祈,三宮肇
- 出版社/メーカー: 翔泳社
- 発売日: 2018/02/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
web extensions書き直した。
どうにも昨日作ったweb extensionがきもちわるいかったので書き直した。
popup.jsでどうこうするやつはスコープの生き死にがわかりづらかった。
てことで現在はpopup.jsではなくbackground scriptsで管理するようにした。
async/awaitとfetchAPIを使って書き直した。
非同期はわかりづらいけど最終的には各スクリプトにイベントリスナを追加する形で受ければ上手くいった。
イベントリスナで受けるのは思い付きだったけどうまくいった。よかった。
popup.js
//background scriptにリクエストを送る。 browser.runtime.sendMessage({text:''},function(response){ document.getElementById('title').innerText = `you have selected ${response.artist}` }) //background script からリクエストが来たらその通りにレンダリングする。 browser.runtime.onMessage.addListener(function(request,sender,sendResponse){ console.log(request) render(request) sendResponse({text:'message received'}) }) function render(request){ const similar_artist = request.state.similar_artist console.log(similar_artist) document.getElementById('title').innerText = `you have selected ${request.artist}` let html = '' for (key in similar_artist){ html += `<br /><div><img src = ${similar_artist[key].image[1]['#text']}>${similar_artist[key].name}</div>` } document.getElementById('artist').innerHTML=html }
background.js
//初期値の設定、選んだアーティストと似ているアーティスト console.log('background start!') //まずはAPIを叩くFunctionを作る。asyncなやつ async function getSimilarArtist(artist) { var state = { artist_name: artist, status: "none", similar_artist: "", } const api_key = '6365215872671c325787a220ef38ae1c' var url = `http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist=${artist}&api_key=${api_key}&limit=10&format=json` fetch(url).then(async(response) => { var results = await response.json() state.status = "fetched" state.similar_artist = results.similarartists.artist //console.log(state) //最後にmessageをpopupに送る browser.runtime.sendMessage({ artist: artist, state: state }) }) } browser.runtime.onMessage.addListener(function(request, sender, sendResponse) { //現在のタブを取得する browser.tabs.query({ currentWindow: true, active: true }, function(tab) { browser.tabs.sendMessage(tab[0].id, { text: '' }).then(function(response) { getSimilarArtist(response.str) }) }) })
content-script.js
//単純にメッセージが来たらそこにレスポンスを返すだけ browser.runtime.onMessage.addListener(function(msg,sender,sendResponse){ title = document.title str = document.getSelection().toString() console.log(str) sendResponse({title:title,str:str}) })
web extensions 作ってみた。
これ以上web extensions勉強しても知見が得られそうにないので実際に作ってみた。
generator-web-extension使用。
インストール方法はコチラ
やりたいことはボタン押したら選択範囲を検知してその選択範囲がアーティストならlast.fmAPIを利用して
似たアーティストを返すというもの。
ソースはこっち
やっぱ実際に書いてみるのが非常にわかりやすくてよかった。
つまづいたところ、というかなおしたいところ
popup.js
import LastFM from 'last-fm' browser.tabs.query({ currentWindow: true, active: true }, function (tab) { browser.tabs.sendMessage(tab[0].id, { text: '' }).then(function (response) { const title = response.title const str = response.str document.getElementById('title').innerText = `you have selected ${str}` searchSimilarArtist(str) } ) }) function searchSimilarArtist(artist) { //authentificate const auth = new LastFM('6365215872671c325787a220ef38ae1c') // for debug:console.log(artist) //return artist similar to given name const data = { isFound: false, result: "ea" } auth.artistSimilar({ name: artist }, (err, data) => { if (err) { data.isFound = false data.result = err console.log(data) } else { data.isFound = true data.result = data //for debug:console.log(data) let html = "" for (var i = 0; i < 10; i++) { html += `<br /><div>${data.artist[i].name}</div>` } console.log(html) document.getElementById('artist').innerHTML = html } }) }
この中のfunction searchSimilarArtist
のauth.artistSimilar関数のコールバック処理
ここで全部分けてるからそれを別の処理に移したいのだけどlet html ~
の部分をdataをreturn するまでのfunction にして以降にdataをレンダリングfunctionに切り分けたいのだがうまくいかない。
dead objectがどうのって怒られた。
多分非同期的にプログラムが進んでてdataが返ってくる前に次に進んじゃっているのが原因のはず。
うまくレンダリングできるようにならないかな。
これからやりたいこと:
- これをreduxのフローに沿って書き直してみたい。
- うまくフローに乗せれたら次は色々(アーティストの画像とか)も表示できるようにしたい。
さてうまくいくかな