情報学部大学生のダラダラ日記

β日記

機械学習や日記っぽいものを書きます

数値微分法についてまとめてPythonで色々してみる

 勾配法あたりでやたらと見る数値微分法について調査し、まとめてみました。

 今回、理論的なことは以下の書籍を参照し、図とプログラムは1から自作したものであり、特にプログラムは筆者がその場で簡易的に考え実装したものです。変数名などおかしい点がありますがご容赦ください。

数値微分法とは

 勾配法においてはある重み{\displaystyle w_1 }において、誤差関数{\displaystyle E(w) }{\displaystyle w }に関して偏微分したものの符号を入れ変えたもの{\displaystyle -\frac{∂E}{∂w} }の方向に重み{\displaystyle w_1 }を更新します。この偏微分という動作をしなくても近似を使うことによって重みの更新をしちゃおう!というのが数値微分法の目的です。

 

 まず、微分の定義を思い出します。

{\displaystyle \lim_{h \to 0} \frac{f(x+h)-f(x)}{h} }

これが見慣れた形ですが今回は文字を変えて

{\displaystyle \lim_{ε \to 0} \frac{E(w_1+ε)-E(w_1)}{ε} }

とします。

f:id:Parco1021:20191215170236p:plain

余談ですが、式だけだとわかりづらいので僕が誰かに微分の定義を説明する時は上みたいな図を描いてこのεを0にもってくとその点での接線になるでしょ??って言います。

 

まず、数値微分法のうち、2点近似を紹介します。図は↑と同様で、式は

{\displaystyle \frac{E(w_1+ε)-E(w_1)}{ε} }です。

 数値微分法では極限などを使わず、手動で限りなく小さいεを設定することで勾配を近似します。例えばεを0.001と設定し、{\displaystyle E(w)=w^3 }{\displaystyle w_1=3 }とすると、

微分法:{\displaystyle E'(3)=27 }

数値微分法(2点近似):{\displaystyle E'(3)≒27.009001‬ }となり、誤差は約0.01ほどになります。

 

 では、より誤差を減らす方法はないの?と思ったそこの奥様!あります。三点近似(中心差分)という手法です。図は先ほどと異なります。

f:id:Parco1021:20191215173433p:plain

そして式は

{\displaystyle \frac{E(w_1+ε)-E(w_1-ε)}{2ε} }です。

試しに先ほどの2点近似と同様の条件で計算してみると

数値微分法(3点近似):{\displaystyle E'(3)≒27.000001‬‬ }となり、誤差が0.000001にまで減りました。

 

Pythonで観測

式自体は単純なものなので書く必要もないと思いますが、通常の微分したものとの差をグラフに描画するプログラムを書きます。

import matplotlib.pyplot as plt
%matplotlib inline

Ew = lambda w: w**3
Gw = lambda w: 3*w**2
e = 0.001
w = [-10000,-100,0,2,16,64,100,1000,10000]
_two = []
_three = []

def normal(w):
    E_dashn = Gw(w)
    return E_dashn
    
    
def three_point(w,e):
    E_dashth = (Ew(w+e)-Ew(w-e)) / (2*e)
    return E_dashth

def two_point(w,e):
    E_dashtw = (Ew(w+e)-Ew(w)) / e
    return E_dashtw

for i in range(len(w)):
        _two.append(two_point(w[i],e)-normal(w[i]))
        _three.append(three_point(w[i],e)-normal(w[i]))

plt.plot(w,_two,label='2point')
plt.plot(w,_three,label="3point")
plt.show()

プログラムは単純なものです。式Ewとそれを微分した式Gwを用意し、wを変化させた時の2点近似と3点近似と通常微分との値の差を取っています。

 

結果

f:id:Parco1021:20191215192757p:plain

グラフを観ると、2点近似は単調増加しており、3点近似は変化していません。これは今回の{\displaystyle E(w)がw^3}であることと、それぞれの式を観れば自明です。そして2点近似と3点近似の優劣は関数{\displaystyle E(w) }が変わっても変化しないでしょう。よって計算量が増加するというデメリットがありますが、3点近似を使う方がより誤差を減らすことができます。

参考文献

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

2次方程式や3次方程式の解と係数の関係の導出方法

 解と係数の関係、知っていますでしょうか。結構な頻度で使われるので受験を経験した人達は覚えていると思います。しかしセンター試験レベルだとせいぜい使っても2次方程式の解と係数の関係ぐらいなので暗記でも乗り越えられるのですが、突然3次方程式の解と係数の関係を使う問題がでた時に困ります。そんな時に導出方法を知っていると役に立つと思うので知らない受験生は知り得です。

2次方程式の解と係数の関係

2次方程式{\displaystyle ax^2+bx+c=0 }が2つの解{\displaystyle α,β }を持つとき、

{\displaystyle α+β=-\frac{b}{a} }

{\displaystyle αβ=\frac{c}{a} }

が成り立ちます。僕は「マイナス(-)を忘れる奴はば(ba)か(ca)」と覚えろと教わりました。まず、2つの方法で2次方程式における関係を導出してみます。

 

 

1つ目は解の公式を使います。

 x=\frac{-b±\sqrt{b^2-4ac}}{2a}

この場合、解は{\displaystyle α,β }なので

{\displaystyle α+β=\frac{-b+\sqrt{b^2-4ac}}{2a}+\frac{-b-\sqrt{b^2-4ac}}{2a}=\frac{-2b}{2a}=-\frac{b}{a}}

{\displaystyle αβ=\frac{b^2-(b^2-4ac)}{4a^2}=\frac{c}{a} }

となります。

 

2つ目は因数定理を使います。

※因数定理

{\displaystyle f(x)が(x-α)を因数(掛け算として表したときにその個々の数のこと)持つことはf(α)=0となるための必要十分条件である }

 

これを使うことにより

{\displaystyle ax^2+bx+c=0がα,βを解に持つ⇔A(x-α)(x-β)=0 }とすることができます。

右辺を展開すると

{\displaystyle Ax^2-A(α+β)x+Aαβ=0 }となります。そこで元の式と比較すると

{\displaystyle a=A }

{\displaystyle b=-A(α+β) }

{\displaystyle c=Aαβ }となるのでここから

{\displaystyle α+β=-\frac{b}{a} }

{\displaystyle αβ=\frac{c}{a} }が求められます。

 

2つ導出方法を紹介しましたがどちらを覚えるべきでしょうか?どちらも覚えてほしいですが重要なのは2つ目です。理由は解の公式は4次式までしかありませんし、とてもじゃありませんが覚えるなんて不可能に近いです。とりあえず2つ目の方法を使って3次方程式の解と係数の関係を求めてみます。

{\displaystyle ax^3+bx^2+cx+d=0 }が3つの解{\displaystyle α,β,γ }を持つとき、因数定理より

{\displaystyle A(x-α)(x-β)(x-γ)=0 }となります。展開すると

{\displaystyle Ax^3-A(α+β+γ)x^2+A(αβ+βγ+γα)x-Aαβγ=0 }となるので係数比較すると

{\displaystyle α+β+γ=-\frac{b}{a} }

{\displaystyle αβ+βγ+γα=-\frac{c}{a} }

{\displaystyle αβγ=-\frac{d}{a} }となります。

まだ2次と3次しか見ていませんが何か規則性が"観えて"きますね。ムムッ

1次の時は{\displaystyle α=-\frac{b}{a} }ですし多分解を足したら同じ結果になるんでしょうね。あとは解を掛けたら定数項/aとか。

さいごに

 今回は手計算でごり押し風に3次までやりましたが5次あたりからきつくなると思います。なのでn次として一般化しなければならないのですが、そこは僕も受験生時代お世話になった以下のサイトさんがやっててくれました。

mathtrain.jp

上のサイトにあるならやらなくていいんじゃないかという声が聞こえてくる気がしますが、高校数学あたりの公式の証明って良い頭の体操になるんですよ。それに"調べれば"出てくるという仮定つきなので調べなくても誰かの目に留まればいいなって感じです。自己満です。頭の体操としてやったのでサイトを観ていません。なのでもし間違っているところ等あればこっそり教えてください。

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

予測損失と経験損失について簡単にまとめる

 機械学習の大きな目的は訓練データから未知のデータ、すなわちテストデータに対する損失を小さくすることです。予測損失(テストデータ)と経験損失(訓練データ)についてまとめてみます。

予測損失

 予測損失というよりも汎化誤差という言葉の方が親しみがあるのではないでしょうか。また、他にも期待損失などとも言うようです。仮説{\displaystyle h }の予測損失{\displaystyle R(x) }が、損失関数として{\displaystyle l }、テストデータ{\displaystyle (X,Y) }の分布{\displaystyle D }を用いて以下のように定義されます。

{\displaystyle R(h) = E_{(X,Y)~D}[l(h(X),Y)]}

つまり、テストデータの分布に対してのテストデータの損失の期待値ということです。しかし、テストデータの分布は未知であるためこの予測損失{\displaystyle R(x) }を計算することはできないです。目標は観測データのみからできるだけ{\displaystyle R(x) }を小さくする仮説{\displaystyle h }を求めることです。

経験損失

 標本誤差、経験誤差とも言われています。データ{\displaystyle (X_1,Y_1),(X_2,Y_2),.....(X_n,Y_n) }が観測され、仮説と損失関数を先ほどと同じ文字に設定すると観測データに対する仮説{\displaystyle h }の経験損失{\displaystyle R ̃(h) }は以下のようになります。

 {\displaystyle R ̃(h) =∑_{(i=1)}^nl(h(X_i),Y_i) }

先ほどの予測損失と異なり、観測データは明らかになっているので{\displaystyle R ̃(h) }は求めることが可能です。

 特にこの時、確率{\displaystyle 1/n }{\displaystyle (X_i,Y_i) }を取る時、確率分布を{\displaystyle D_1 }とすると上式は

{\displaystyle R ̃(h) = E_{(X,Y)~D_1}[l(h(X),Y)] }

と表すことができる。この式は予測損失の式ととても似ていますね。違いは従っている確率分布です。つまり、データが同一の確率分布に従うとき、

{\displaystyle R ̃(h) ≒ R(h) }

とすることができます。

結局???

 予測損失を最小にしたいのはわかっていただけたと思います。簡単に説明すると"予測損失を最小にすることが(実質的に)機械学習の主たる目的だから"です。ではなぜ経験損失を求める必要があるのでしょうか?それは上でも述べた通り、経験損失と予測損失が近似できるからです。流れは以下のような感じです。

 

予測損失が最小となるよう仮説を設定したい

テストデータの分布は未知であるため値が求められない

予測損失と近似できる経験損失がある

経験損失は実測値から求められる

 

という感じです。今回は理論的な部分から予測損失(汎化誤差)にアプローチしてみましたが、応用的な部分から観てみるとなぜ予測損失を最小にしたいかが感覚的にわかってくると思います。以下のサイトをご覧になってみてください。

訓練誤差と汎化誤差の理論計算 - Qiita

参考文献

以下の書籍を参考に書きました。

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

モデルを蒸留するのではなくデータセットを蒸留する(論文紹介②Dataset Distillation)

蒸留とは

 中学生の時に化学で学んだ蒸留について、

蒸留(じょうりゅう、Distillation)とは、混合物を一度蒸発させ、後で再び凝縮させることで、沸点の異なる成分を分離・濃縮する操作をいう。

引用元:Wikipedia

 深く、大きいモデルが優秀であることは想像に難くありません。しかし、実際にはそのような大きいモデルが使用できないが機械学習モデルを使用したい場面があります(ラズパイとかでやる時など)。そのような時に、深く大きいニューラルネットワークの知識を蒸留し、より浅く小さいニューラルネットワークへ学習させるために使われるものです。特に大きいモデルを教師モデル、小さいモデルを生徒モデルと言います。つまり性能をできるだけそのままに教師モデルから生徒モデルへ知識の継承を行うことを目的としています。これについての元論文は以下です。

Distilling the Knowledge in a Neural Network,Geoffrey Hinton, Oriol Vinyals, Jeff Dean,2015,https://arxiv.org/abs/1503.02531

日本語でまとめられた文献もあります。

Deep Learningにおける知識の蒸留 | Code Craft House

論文紹介

今後、本記事での画像等の引用は全てこの論文からです。

引用数は9でタイトルはそのまま「データセットの蒸留」です。

概要

 先ではモデルの蒸留を行っていましたが本論文ではデータセットの蒸留をします。具体的には膨大なデータセットをサンプリングすることなく、各クラスごとに新たな画像を生成することでデータセットを圧縮している。

f:id:Parco1021:20191127182634p:plain

引用元:Dataset Distillation

 

イメージとしては上のような感じ。このように新たに画像を生成することで数万枚のデータセットが10~300枚へと蒸留することができている。

アルゴリズム

f:id:Parco1021:20191127184527p:plain

引用元:Dataset Distillation

<!--以下自己解釈

蒸留後データセット{\displaystyle x ̃ }を初期化する。

元データ{\displaystyle x }を取得する。

ある重み{\displaystyle }θ_0^{(j )}において勾配を求め、より良い重み{\displaystyle }θ_1^{(j )}を決定

元データと{\displaystyle }θ_1^{(j )}を使ってロス関数を計算する。

ロス関数の勾配から蒸留後データセット{\displaystyle x ̃ }を更新する。

-->

実験結果

まず、上記のアルゴリズムを繰り返し行う2パターンの実験を行う。

上のアルゴリズムを拡張して2つの方法を用意する。

(a)重み{\displaystyle θ }の更新を複数回行う

(b){\displaystyle x ̃ }の更新を複数回行う

f:id:Parco1021:20191127190345p:plain

引用元:Dataset Distillation

 

実験対象としてMNISTとCIFAR10が用いられたが、(a),(b)どちらの場合にも複数回行った方が正確となっている。

 

次に、ベースライン条件として以下の4つの条件を用意し、それとデータセットを蒸留した時の結果を比較する。

ベースライン条件

  1. ランダム
  2. 学習効果の高かった上位20%
  3. k-means法
  4. 各画像の平均

結果が以下です。ベースライン条件よりも良い結果になっていることがわかります。

f:id:Parco1021:20191127193422p:plain

引用元:Dataset Distillation 

さいごに

 今回は蒸留という手法の新しいアプローチを行った論文でした。どのようなクラスからどのような画像が生成されたかは参考文献の公式リンクから観てみてください。carクラスだったりが1つの画像になっているのは結構面白いです。

英語キチィ~

参考文献

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Python】Twitter apiを使って複数画像を投稿する

はじめに

 Twitter botを作成する際にapiを使って複数枚画像を投稿する方法があまりネットでは見つからなかったり、のっている情報が誤っていたりしたのでメモします。今回はいらすとやさんの画像を使いました。

プログラム

import requests

import twitter

import urllib.request

import requests

from requests_oauthlib import OAuth1Session

import json





CK=''

CS=''

AT=''

AS=''

twitter = OAuth1Session(CK,CS,AT,AS)



url_media = "https://upload.twitter.com/1.1/media/upload.json"

url_text = "https://api.twitter.com/1.1/statuses/update.json"



img_url = ['https://1.bp.blogspot.com/-SWOiphrHWnI/XWS5x7MYwHI/AAAAAAABUXA/i_PRL_Atr08ayl9sZy9-x0uoY4zV2d5xwCLcBGAs/s1600/pose_dance_ukareru_man.png',

            'https://1.bp.blogspot.com/-CSIokkL0VJc/XVKgHNKp2QI/AAAAAAABUHU/znkuxlOlQ5giZ3gDbks7KAK3TJnT2q1XwCLcBGAs/s1600/kotowaza_hato_mamedeppou.png',

            'https://1.bp.blogspot.com/-8sMAiPmvFuo/XVjgKN2BXoI/AAAAAAABUM0/IfTQp8hHWRsVk_u7s84OE6yvFJ5ekpnLwCLcBGAs/s1600/kid_seikaku_uchiki_girl.png',

            'https://1.bp.blogspot.com/-ahlT7Kd7-T0/XVjgJ3hrbFI/AAAAAAABUMw/MV4su85SnoAMYnSitR9DXVgNFuorpprwQCLcBGAs/s1600/kid_seikaku_uchiki_boy.png']  #①



def call():    

    media_id = []

    for i in range(4):

        headers = {"User-Agent": "Mozilla/5.0"}  #②

        request = urllib.request.Request(url=img_url[i],headers=headers)

        response = urllib.request.urlopen(request)

        data = response.read()

        files = {"media" : data}

        req_media = twitter.post(url_media,files = files)  #③

        media_id.append(json.loads(req_media.text)['media_id_string'])

    media_id= ','.join(media_id)  #④

    status = "投稿テスト"

    params = {"status": status, "media_ids": media_id}

    twitter.post(url_text,params=params)

    

        

if __name__ =='__main__':

    call()

解説と結果

  • ①ここで投稿したい画像のURLをリストにいれておいて準備します。僕はURLから画像を取得したかったのでやっていませんが、ローカルのファイルのパスを指定して投稿したい場合は他の方が多くやっていらっしゃるのでそちらを参照してください。
  • ②ユーザーエージェント(どのようなブラウザがサーバへアクセスしているかの情報)をこのようにFirefoxなどに指定しないと権限エラーが出てアクセスできないので注意してください。これについても多くの情報があるので調べてみてください。
  • ③②~③までの間でリスト内の画像URLをサーバから受け取りました。Twitterには直接画像のURLを画像として呟く事ができないので③ではこれをTwitter(url_media)へpostすることでURLを画像コード(数字の羅列)に変換しています。
  • ④今回の主たるところです。media_idが最終的にTwitterへ送る際にはじめはリストを渡せばいいと思っていましたが一枚しか投稿されませんでした。おそらく、['111','112',・・・]となっていることで途中のシングルクォーテーションが区切りと判断されたことが原因だと思います。なので④のようにリストの要素をカンマでjoin結合し、[111,112,・・・]とすることで複数枚投稿が可能となります。

 呟いた結果がこちら↓

f:id:Parco1021:20191123200647j:image

 

さいごに

 今回はTwitter apiの複数枚投稿についてまとめました。4で割り切れない場合などに臨機応変に対応させて複数枚投稿させたい場合はmodなどを使うといいです。僕が作ったbotはそのような設計になっているのでもしよければ観てみてください。

parco1021.hatenablog.com

(あげたあとにあげる必要ないって気づいたけど一応gitにもあげたので…https://github.com/tnb1021/tweetimgs)

参考文献

こちらのプログラムを拡張し、複数枚投稿できるようにしました。

qiita.com

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

最近月曜日と金曜日の雨多くない??

はじめに

 僕は今、月曜日と金曜日に実験の講義があります。そしてその時、軒並み雨のような気がしています。果たしてそれは僕が他の曜日に外出しないが故の勘違いなのかあるいは正しいのか検証してみます。

 '最近'と曖昧にしましたが、実験が始まったのが10月からなので10月1日~昨日(11月21日)までの情報を気象庁さんが提供してくださっているものをcsv保存しました。

f:id:Parco1021:20191122170019p:plain

データは概ねこのような感じです(一応データは隠しました)。csv保存せず、スクレイピングしてもよかったのですが曜日計算がめんどくさかったのと必要な情報が少なかったのでやりませんでした。

※筆者は統計学の学がないです。また、決して曜日と天気に因果関係があることを示唆しているわけではありません。

プログラム

 「このぐらいなら手で数えろよ…」の声が聞こえてきますが嫌です。書きました。

import pandas as pd

f = pd.read_csv('data.csv',encoding='cp932')
f.columns = ['day','dow','precipitation']

count_rain = 0
count_rainexp = 0
count_exp = 0
count_day = 0

for row_index,row in f.iterrows():
    if row[2] != '--':
        if float(row[2]) > 1:
            count_rain += 1
            if row[1] == '月' or row[1] == '金':
                count_rainexp += 1
    if row[1] == '月' or row[1] == '金':
        count_exp += 1
    count_day += 1

'''
for row_index,row in f.iterrows():
    if row[2] != '--':
        if float(row[2]) > 1:
            count_rain += 1
            if row[1] == '金':
                count_rainexp += 1
    if row[1] == '金':
        count_exp += 1
    count_day += 1
'''    

print('雨日:',count_rain)
print('実験で雨日:',count_rainexp)
print('実験日:',count_exp)
print('総合日数:',count_day)

 おなじみのpandasライブラリでf.iterrows()で一行ずつ参照しています。降水量が無の時を表す"--"でないとき他は全て数値なのでfloat型で変換しています。あとはそれぞれ求めたい数値をインクリメントしています。一応月金verと金のみverを書きましたが結果はほぼ同じでした。

実行結果

 今回、総合降水量で判断しているので多少誤差がありますが1mmを超えた時に雨日としました。

雨日: 17
実験で雨日: 7
実験日: 14
総合日数: 52

 つまり実験がある日が14/52、雨の日が17/52、実験の日かつ雨の日が7/52日ということになります。実験がある日という条件の下で雨が降った条件付き確率は7/14=1/2ということになります。さらに、11/4(月)と11/8(金)は変則日課で実験がありませんし雨も降っていません。これを加味すると条件付き確率は7/12≒0.58となります。さらにさらに今日11/22は実験でありさらに雨が降っています。よって8/13≒0.62となります。

さいごに

 補足すると雨かつ火or水は5日、雨かつ土or日は2日でした(ってことは木は3日)。つまり偏りがありますが今回そんなことはどうでもいいんです。重要なのは

ただでさえ憂鬱な実験の日に雨が6割も降って空気ジメジメするしより憂鬱になるんだよ!!!!

ってことです。

 後期も折り返しです。頑張りましょう。

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

Windowsで毎日定時にプログラムを実行する方法

はじめに

 Twitterbotを作るために毎日定時にプログラムを実行したいのでタスクスケジューラを使います。

parco1021.hatenablog.com

手順

  1. プログラム実行用のバッチファイルを用意する
  2. 1のバッチファイルをタスクスケジューラで実行する

まず、バッチファイルを用意します。これについては下の記事を参照してください。

parco1021.hatenablog.com

要するに実行したいコマンドが打ち込まれているファイルが拡張子.batで作られていればいいです。

 次にタスクスケジューラの設定をします。窓からタスクスケジューラを開きます。適当なライブラリで右クリック→タスクの作成を選択してください。名前を設定してから「ユーザがログオンしているかに関わらず実行する」にチェックします。これをしないと貴方がPCを開いていないとプログラムが実行されません。そして「最上位の特権で実行する」にもチェックをします。そしてトリガーを実行したいように設定します。

f:id:Parco1021:20191120152028p:plain

僕は9時ちょい過ぎに毎日実行したいのでこのように設定します。

操作はまず「プログラムの開始」を選択します。そしてプログラム/スクリプトは参照から作成したバッチファイルを選択し、開始(オプション)にはバッチファイルのディレクトリを設定します。これをしないと実行されないので注意してください。僕はこれをしていなくて躓きました。

f:id:Parco1021:20191120153041p:plain

そして次に条件において「タスクを実行するためにスリープを解除する」のチェックをします。

f:id:Parco1021:20191120153345p:plain

しかし、ここで設定しただけではスリープを解除することがPC本体において有効ではないのでそこの設定もいじらなければなりません。そこは以下を参照してください。

qiita.com

あとはデフォルトで大丈夫っぽいです。

さいごに

 Windows内のプログラムを定期実行したい場合はまず一回だけタスクスケジューラから実行できているか確認することをお勧めします。ローカルのプログラムではなく、Herokuにデプロイした場合はHeroku側で定期的に実行してくれるものがあるようなのでそちらもご検討してみてはいかがでしょうか。何かあればコメントでお願いします。

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Python】Fortniteのショップ情報を呟くTwitterのbotを作った

はじめに

 今回の記事は技術的なことになります。どのようなbotかなどは別途以下の記事をみてください。

parco1021.hatenablog.com

 また、今回は全体的なことのみ書いて具体的なことを書いたものは別途書いてこのブログへリンクを追加していこうと思っています。

使用環境

conda 4.7.10

Python 3.7.3

Twitter api

Fortnite Tracker api

処理の流れ

今回作成したbotの処理のフローが以下です。

 

f:id:Parco1021:20191119125250p:plain


この図の①~⑧までの処理を後で別々に書いていこうと思います。

プログラム

import requests
import twitter
import urllib.request
import requests
from requests_oauthlib import OAuth1Session
import json
import time
from datetime import date

key=''
URL='https://api.fortnitetracker.com/v1/store'
CK=''
CS=''
AT=''
AS=''
twitter = OAuth1Session(CK,CS,AT,AS)

url_media = "https://upload.twitter.com/1.1/media/upload.json"
url_text = "https://api.twitter.com/1.1/statuses/update.json"
   


def tweet(media_id,j,result): #⑦、⑧
    now_date = date.today()
    y = now_date.year
    m = now_date.month
    d = now_date.day
    len_pic = len(media_id)
    if len_pic == 4:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n{} {}vBucks\n{} {}vBucks\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'],result[j*4+1]['name'],result[j*4+1]['vBucks'],
        result[j*4+2]['name'],result[j*4+2]['vBucks'],result[j*4+3]['name'],result[j*4+3]['vBucks'])
    elif len_pic == 3:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n{} {}vBucks\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'],result[j*4+1]['name'],result[j*4+1]['vBucks'],
        result[j*4+2]['name'],result[j*4+2]['vBucks'])
    elif len_pic == 2:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'],result[j*4+1]['name'],result[j*4+1]['vBucks'])
    else:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'])
    media_id= ','.join(media_id)
    params = {"status": status, "media_ids": media_id}
    print(params)
    twitter.post(url_text,params=params)
    time.sleep(5)

def pic(media_id,i,j,result): #⑤、⑥
    img_url = result[i+4*j]['imageUrl']
    print(img_url)
    headers = {"User-Agent": "Mozilla/5.0"}
    request = urllib.request.Request(url=img_url,headers=headers)
    response = urllib.request.urlopen(request)
    print(response)
    data = response.read()
    files = {"media" : data}
    req_media = twitter.post(url_media,files = files)
    media_id.append(json.loads(req_media.text)['media_id_string'])
    print(media_id)
    return media_id

def call():
    #②、③、④ここから
    headers = {'TRN-Api-Key' : key}
    r = requests.get(URL, headers = headers)
    result = eval(r.text)
    print(len(result))
    print(result)
    num = len(result) // 4
    mod = len(result) % 4
#ここまで for j in range(0,num): media_id = [] name = [] vbucks = [] for i in range(4): pic(media_id,i,j,result) #⑤、⑥ tweet(media_id,j,result) #⑦、⑧ media_id = [] name = [] vbucks = [] for k in range(0,mod): pic(media_id,k,j+1,result) #⑤、⑥ tweet(media_id,j+1,result) #⑦、⑧ if __name__ =='__main__': call()

 データ数は毎日異なるのでそれに対応させるように書きます。4つずつデータを呟きたいのでまずは4枚ずつできるだけ呟きます。例えば17個のデータだったらnum=17//4=4となります。なのでまずはfor文のところのjを4回まわすことで16個呟きます。そして残りの1を呟く方法としてmod=17%4=1となるのでfor文のところのkをmodの数だけまわします。

 それぞれ値を関数に渡して処理をします。本当は呟く文章の箇所でif-elifを多用したくなかったのですがよくわからなかったのでゴリ押しました。

 

各処理の説明

①毎日定時に実行

parco1021.hatenablog.com

 

②、③呟くデータをAPIを叩いて取得する

parco1021.hatenablog.com

 

④~⑧データを呟く

parco1021.hatenablog.com

 

全体のコードはgithub見てください。コードが汚いのは許してね。

https://github.com/tnb1021/fortnitebot

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

Fortniteショップbotのトリセツ

 今回、Fortniteのショップ情報を呟くbotを作成しました。その説明を書きます。あくまでトリセツなので技術的なことについて深く書きません。技術的な話は別で書きます。情報は元はFortnite Trackerさんです。

  • 呟く内容は「商品名 値段vBucks」となっています。詳細は書きませんが、海外から情報を受け取っているので英語表記となっています。手作業で翻訳することも可能ですが、現在実施する方針はありません。
  • 商品の画像を4枚(Twitterで投稿できる最大枚数)区切りで呟いているので一日の投稿数が(商品数)÷4+1となります。画像付きなので多少ライムラインを圧迫します。
  • 情報の特性上、ある商品の別バージョンがショップに並んでいる場合、値段が0表記になる可能性があります。0vBuckとなっていた場合はそのような解釈をしていただけると幸いです。
  • Fortniteのショップは日本時間の午前9時に更新されますが、本botは9時5分の更新となります。
  • ご意見・ご要望ありましたら本記事へのコメントまたはbotへリプライしてください。しかし全て対応できるわけではないことをご容赦ください。
  • botは予告なく終了する可能性があります。

↓↓もしよろしければフォロー・いいね・RTお願いします!!

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

(個人的)ワンピースEDランキング

はじめに

 あまり目立っていない(と思う)のですがワンピースのEDもOPに引けを取らないぐらいいい歌が多くあります。今回もワンピースEDランキング(TOP5)を作ってみました。例のごとく個人的ランキングです。

OPランキング↓↓

parco1021.hatenablog.com

 

歌リスト

今回もanimateさんからの引用です。また、使用期間はWikiを参照しています。

大槻真希「memories」
大槻真希「RUN! RUN! RUN!
トマトキューブ「私がいるよ」
推定少女「しょうちのすけ」
AI-SACHI「BEFORE DAWN」
The Kaleidoscope「fish」
上原多香子「GLORY-君がいるから-」
Janne Da Arc「Shining ray」
Ruppina「Free Will」
Ruppina「FAITH」
ZZ「A to Z~ONE PIECE Edition~」
shela月と太陽
イクタ☆アイコ「DREAMSHIP」
タッキー&翼未来航海
エイジアエンジニア「エターナルポーズ」
TRIPLANE「Dear friends」
東方神起「明日は来るから」
デリカテッセン「ADVENTURE WORLD」 

第5位

 AI-SACHI「BEFORE DAWN」

BEFORE DAWN

BEFORE DAWN

  • provided courtesy of iTunes

 使用期間は第82話から第94話までです。ドラム王国の最後の方からボンちゃん初登場あたりまでですね。思い出はないです!

第4位

デリカテッセン「ADVENTURE WORLD」 

ADVENTURE WORLD

ADVENTURE WORLD

  • provided courtesy of iTunes

 使用期間は第264話から第278話までです。俗にいうエニエスロビー編の始めから生ぎたいっ!!までですね。ワンピースは途中でEDがなくなるのですが、この歌が最後のEDとなります。視聴者が描いた絵が流れてた記憶があります。

第3位

Janne Da Arc「Shining ray」

Shining ray

Shining ray

  • provided courtesy of iTunes

 使用期間は第119話から第132話までです。アラバスタ編の終盤なので聞いたことがある人も多いのではないでしょうか。普通に好きです。

第2位

大槻真希「memories」

memories

memories

  • 大槻 真希
  • J-Pop
  • ¥255
  • provided courtesy of iTunes

  使用期間は第1話から第30話までです。サンジが仲間になるところまでですね。ワンピースのEDで最も有名で人気な歌だと思います。

第1位

大槻真希「RUN! RUN! RUN!

RUN! RUN! RUN!

RUN! RUN! RUN!

  • 大槻 真希
  • J-Pop
  • ¥255
  • provided courtesy of iTunes

  使用期間は第31話から第63話までです。アーロン編からレッドライン超えるまでです。何も言いません。神歌です。以上!

さいごに

 いかがでしたでしょうか。OPの陰に隠れてはいますがとてもいい歌が多いので他の歌も是非聴いてみてください。OPランキングもよろしければ観てみてください。

parco1021.hatenablog.com

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Python】batファイルにおいてAnaconda環境を呼び出す方法

はじめに

 ファイルを開くだけでコマンドを実行してくれるbatファイルですが、Windowsコマンドプロンプトで行うためライブラリなどの環境が揃っていません。僕のようにPythonは元からライブラリが揃っているAnaconda環境で実行している人は多いのではないでしょうか。逐一必要なライブラリやPython環境を別途用意しても良いのですがせっかくなのでbatファイルでAnacondaの環境を呼び出す方法を調べたので紹介します。

呼び出す方法

 では早速方法です。例えば同一ディレクトリ内のtest.pyを実行したい時、

call C:\Users\{ユーザ名}\Anaconda3\Scripts\activate.bat
python test.py

 call (activate.batまでの絶対パス)とします。つまりAnacondaのactivate.batというバッチファイルを呼び出してます。callってなんやって思って調べてみたところバッチファイル内でバッチファイルを呼び出す時のコマンドです。

 そしてAnacondaの環境が整ったのでそのまま実行します。同一ディレクトリ内なのでpython test.pyを実行してもらうだけです。

参考文献

stackoverflow.com

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Django】Djangoでbootstrapのテンプレートを使う方法

はじめに

 好きなテンプレートをダウンロードしてコピペはいおっけー!とはいかないのです。

今回使ったテンプレートはhttps://templatemag.com/minimal-bootstrap-template/です。

やり方

 まず、お好きなテンプレートをダウンロードして解凍します。静的ファイルなのでまずプロジェクト内にstaticというフォルダを作り、そこに中身のフォルダ(css,js,lib)などをコピペしてください。

 また、この時点でsetting.pyに

STATIC_URL = '/static/'

とない場合は足してください。

templateフォルダにテンプレートをダウンロードした時のindex.htmlなどを入れ、URLおよびビューを設定してからアクセスしてもまだcssが反映されておらず、以下のようになると思います。

f:id:Parco1021:20191111171207p:plain

 はじめに1行目に

{% load static %}

を記述し、staticフォルダを読み込むように宣言?します。そして

<link href="css/style.css" rel="stylesheet">

<link href="{% static 'css/style.css' %}" rel="stylesheet">

とすることでstaticフォルダからの相対パスを指定し、cssなどを読み込みます。すると

f:id:Parco1021:20191111171036p:plain

さいごに

 今までbootstrapのテンプレートを使ったことがなく、使い方もlaravelやrailsでの使い方ばかり見受けられたので(使い方はほぼ一緒)、メモで残します。テンプレート初めて使ったんですけどいいですね、バエます。

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

自動運転に潜む怖さ(論文紹介①Adversarial examples in the physical world)

はじめに

 先日、UberのAI車が死亡事故を起こすという痛ましいニュースが流れました。

news.yahoo.co.jp

 この事故は「歩行者は歩道にいる」というシステム設計から起こった事故ですが、例えばAI車が読み込む標識などに誰かが細工をして「とまれ」を別の標識に認識させるようにしてしまったらどうなるでしょうか?結果は目に見えていると思います。今回はそこに関連する論文を紹介します。 

今回読んだ論文について簡単に

  • タイトル:Adversarial examples in the physical world
  • 発行年:2017(ICLR)
  • 著者:Alexey Kurakin,Ian Goodfellow,Samy Bengio
  • URL:https://arxiv.org/abs/1607.02533

Adversarial Examplesについての先行研究

 まず、Adversarial Examplesについて一言で説明すると、「画像にノイズを加えてモデルに誤った出力をさせてしまう」ことです。

f:id:Parco1021:20191109212451p:plain引用元:Goodfellow et al. (2014)

  元々のモデルの出力は57.7%でパンダとなっています。そこに真ん中の図のようなノイズを加えることでモデルの出力が99.3%でgibbon(テナガザル)となります。このように人間にとって見た目に差がなくても機械学習システムの出力を誤らせてしまうようなモデルに対する脆弱性攻撃のことをAdversarial Examplesといいます。

 機械学習、特にニューラルネットワークにおけるモデルは、モデルへの入力時の微弱な変化に対してとても弱いことがわかっています。また、モデルを複数用意しAdversarial Examplesの実験を行った場合、あるモデルが誤った出力をする時はそのほかのモデルも誤った出力をする可能性が高いことが示されています。

新規性

 上で挙げた先行研究は攻撃が全てコンピュータ内で為されていることを前提にしています。しかし実際に私達が機械学習システムを用いる時は声をSiriなどに入力したり、顔認証でスマートフォンをアンロックしたりなど実世界であることが多いです。今回の論文は特にカメラを通じた画像の認証におけるAdversarial Examplesの生成および実験を行っています。

実験で用いられたAdversarial Examplesの生成方法

 まずは変数の定義を説明します。

  • {\displaystyle X }…入力画像。3次元ベクトルであり、ピクセルの値は[0,255]の整数値
  • {\displaystyle y_{true} }…入力{\displaystyle X }の正しいクラス
  • {\displaystyle J(X,y) }…損失関数
  • {\displaystyle Clip_{\{X,ε\}}X'(x,y,z)=min⁡\{255,X(x,y,z)+ε,max⁡\{0,X(x,y,z)-ε,X'(x,y,z)\}\}} ピクセルが[0,255]の範囲外にならないようにクリッピングする処理

変数の定義がされたので今回の論文で用いられた手法を3つ説明します。

Fast Method

 上でも示したGoodfellow et al. (2014)による手法です。

{\displaystyle X^{adv}=X+εsign(∇_X J(X,y_{true} )) }

ざっくり式の説明をすると{\displaystyle ∇_X J(X,y_{true} ) }によって勾配ベクトルを求め、符号を求めるsign関数に引数として渡します。それが正ならば正の方向、負ならば負の方向(=正解クラスの遠ざける方向)へノイズを加え、より正解から遠ざける方法です。εは変数です。

Basic Iterative Method

 Fast Method を繰り返し行う方法です。

{\displaystyle X^{adv}_{N+1}=Clip_{X,ε}\{X^{adv}_N+αsign(∇_X J(X^{adv}_N,y_{true} ))\}}

 繰り返し行うのでピクセルの値が範囲外とならないようにクリッピングを行っています。

Iterative Least-Likely Class Method

{\displaystyle y_{LL}=argmin\{p(y|X)\} }

{\displaystyle X^{adv}_{N+1}=Clip_{X,ε}\{X^{adv}_N-αsign(∇_X J(X^{adv}_N,y_{LL} ))\}}

 Basic Iterative Methodと符号と損失関数の引数が違いますね。yLLはモデルが出力するクラスのうち、最も確率の低いものを示します。なのでこの方法は最も"あり得ない"クラスに寄せています。

εの決定

 先ほどの数式におけるεを決定するための実験です。

f:id:Parco1021:20191109235316p:plain引用元:Alexey Kurakin et al.

εが8を超えたあたりから滑らかになりますね。また、誤認率はl.l方法が最も高いです。

f:id:Parco1021:20191110000319p:plain引用元:Alexey Kurakin et al.

 上の画像を観てもわかる通り、εが8でも人間の目からはノイズが加わっていることはわからないと思います。 

実験の方法

 実験の方法はまず、画像を印刷します(a)。そして印刷した画像を携帯電話のカメラで写真を撮り(b)、自動でトリミングしたもの(c)をモデルへ入力します。

f:id:Parco1021:20191110001702p:plain引用元:Alexey Kurakin et al.

 以上のように入力は完了しました。また、本実験では

①Average case

②Prefiltered case…あらかじめ画像をフィルタリングし、元のモデルの出力を0か1かになるようにする

の2ケースが用意されていますが、②は考えずに①のみ結果を示します。

f:id:Parco1021:20191110003217p:plain引用元:Alexey Kurakin et al.

 Photosがカメラで撮った画像であり、Source imagesが元の画像です。Adv. imagesがノイズ込みの画像。

 表を見ると、例えばfast method のε=16の時、カメラを介すると誤認率がtop-1だとおよそ2/3、top-5だと1/3となっておりかなり低くなっています。元の画像においてはl.l.方法がAdversarial Examplesの誤認率が高く、fast methodが最も低いです。しかし、カメラを通じると、fast methodが最も誤認率が高くなっています。つまりカメラを介する場合とそうでない場合とでAdversarial Examplesの作成方法の優劣が変わっています。

さいごに

 今回は、僕達の身近なケースであるカメラを通じたAdversarial Examplesの論文を読みました。機械学習もセキュリティも初心者なのですが先輩や先生に教えていただきながらなんとか読み切ることができました。内容としてはとても興味深いものであり読んでいて楽しかったです。

 カメラを介するケースとそうでないケースで攻撃側の優劣が異なるということは防御側もテストをコンピュータ上で行うのではなく、カメラを介さなければいけないということであり、これもいたちごっこになっているそうです。

参考文献

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

"コレ"に登録するだけでブログの収益が増える…かも?

はじめに

 タイトルであんなふうに書きましたが実際の収益に影響するかどうかはブロガーさん次第です。貴方は商品のリンクを貼る時、Amazonのリンクを貼っていますか?それとも楽天のリンクを貼っていますか?あるいは両方貼っていますか?自分はAmazonを使っているけどユーザーさんは楽天しか使っていないかもしれない。そんなことを考えなくても良いのがもしもアフィリエイトです。既に使っている人も多いと思いますが…。

もしもアフィリエイトについて

 では、もしもアフィリエイトを使うと何が嬉しいのか早速結論に移ります。

 例えば上のように1つの商品辺りにAmazon楽天及びYahooショッピングの3つのリンクを貼ることができます。

使い方

 まず、以下のリンクにアクセスして会員登録を済ませてください。 

https://af.moshimo.com/

サイトの登録などを済ませてから「サイトの運営」→「かんたんリンク」を選択します。

f:id:Parco1021:20191108162713p:plain

おそらく、デフォルトだとAmazonとの連携ができていないので申請をしてから数日待ってください。僕は4、5日かかりました。

 連携がとれているのを確認してから商品を選択するとjavascriptのコードが生成されるのでそれをコピペするだけです。とても簡単なのでまだやっていない方は早めの登録をお勧めします。

 

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村 PVアクセスランキング にほんブログ村

(個人的)ONE PIECEのOPランキング

はじめに

 2つ足で歩く前からワンピースが好きな自分が個人的に好きなアニメのOPのTOP5を発表したいと思います。もう一度言います。

個人的

ランキングであり、僕個人の歌の好みや好きな話のイメージなどが顕著に表れているので〇〇がないなんてファンじゃない!などの断定はやめてください。ファンです。ランキング外でも当然好きな歌はたくさんあります。

OPリスト(2019年11月現在)

animateさんがリストを挙げてくださっているので引用します。(歌手名)「(歌名)」となっています。

きただにひろしウィーアー!
Folder5「Believe」
ザ・ベイビースターズ「ヒカリヘ」
Bon-Bon BlancoBON VOYAGE!
BOYSTYLE「ココロのちず」
D-51「BRAND NEW WORLD」
7人の麦わら海賊団「ウィーアー! ~7人の麦わら海賊団篇~」
タッキー&翼Crazy Rainbow
5050「Jungle P」
東方神起ウィーアー! ~10周年Ver.~」
東方神起「Share The World」
矢口真里とストローハット「風をさがして」
The ROOTLESS「One day」
安室奈美恵「Fight Together」
きただにひろしウィーゴー!
新里宏太「HANDS UP !」
AAA「Wake up!」
GENERATIONS from EXILE TRIBE「Hard Knock Days」
氣志團きただにひろし「ウィーキャン!」
安室奈美恵「Hope」
V6「Super Powers」
きただにひろしOVER THE TOP

 では早速第5位から

第5位

The ROOTLESS「One day」

One day

One day

  • provided courtesy of iTunes

  頂上戦争あたりの歌ですね。あまりワンピのことを知らないような人でもこの歌は知っているので知名度としてはウィーアー並だと思います。僕個人としてもとてもいい歌だと思います。頂上戦争編があまり好きではないので5位です。

 

第4位

 ザ・ベイビースターズ「ヒカリヘ」

ヒカリへ

ヒカリへ

  • provided courtesy of iTunes

  アラバスタ編の終盤から空島編の中盤までのOPだったイメージです。アラバスタ終盤でバチバチにロビンが敵描写されているにも関わらず、このヒカリヘにてメリー号に自然に乗っているという伝説のネタバレ曲でもあります。ゆったりとした声がいいですね。

 

第3位

5050「Jungle P」

Jungle P

Jungle P

  • 50/50
  • J-Pop
  • ¥250
  • provided courtesy of iTunes

 エニエスロビー編終盤からスリラーバーク編序盤までの歌です。特にイメージに残っているのはアニオリであるドンアッチーノ編で流れていたことですね。ドンアッチーノ編は正直嫌いなのですが、そのマイナスのイメージよりも歌の好みが勝っているので3位です。

 

第2位

Folder5「Believe」

Believe (第48-115話OP)

Believe (第48-115話OP)

  • Recitativo
  • アニメ
  • ¥153
  • provided courtesy of iTunes

  アーロンさんあたりの話です。ファンの間でもとても人気のある歌であり、僕の幼馴染の友達はこの歌が一番好きだと言っていました。テンポがよく好きな歌です。

 

第1位

 安室奈美恵「Hope」

Hope

Hope

  • provided courtesy of iTunes

  WCI編です。あまり"ワンピースっぽく"ない歌なのですが、王道JPOPが大好きです。あと、WCI編が僕的に一番好きです。なぜこの歌が好きなのか言語化できませんがまあヨシ!

番外編

 (本当はBON VOYAGEが一番好きなんだけどitunesにようわからんカバーしかなく、良さが伝わらないと判断したので今回は外しました。本家は御自身で探してください。なので個人的順位はそれぞれ+1したものです。)

BON VOYAGE! (From

BON VOYAGE! (From "ワンピース")

  • 小川美加
  • アニメ
  • ¥150
  • provided courtesy of iTunes

さいごに

 itunesアフィリエイトを使いたかったので今回は個人の好みでしかないワンピースOPランキングを作ってみました。先にも述べている通り、他にもいい歌ばかりなので是非良ければ聞いてみてください。EDにも映画にも大好きな歌が多くあるので後日別途EDと映画の主題歌ランキングを作ります。

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村 PVアクセスランキング にほんブログ村

スポンサーリンク