【VGG16にて転移学習】花の分類

  • はじめに
  • 実験1 まずはそのまま
  • 実験2 classesの追加
  • 実験3 検証データのImageDataGeneratorの変更
  • 実験4 Activationの変更
  • コード
    • Fine-Tuning_vgg16.py
    • main.py
  • まとめ

はじめに

こんにちは、がんがんです。ポケモンの転移学習が上手くいかなかったため、以下の記事を参考にしてまずは花の分類をしていこうと思います。

aidiary.hatenablog.com

ベンチマークを試すことにより、学習データがきちんとしてないのか、それともモデルに問題があるのかを調査するために実験を行いました。

続きを読む

【Deeplearningでポケモン図鑑計画_その2】画像のクレイジングとデータ仕分け

  • はじめに
  • 画像のクレイジング
  • コード
  • まとめ

はじめに

こんにちは、がんがんです。今回は画像のクレイジングを行い、転移学習を行っていきます。
転移学習の方が長くなりそうだったため、今回はこちらのみまとめておきます。

図鑑の計画編はこちらです。

gangannikki.hatenadiary.jp

前回の記事はこちらからどうぞ。

gangannikki.hatenadiary.jp

続きを読む

【paizaのプログラミング講座をはじめてみた】

  • はじめに
  • なぜやってみたのか
  • 感想
  • まとめ
  • 参考記事

はじめに

こんにちは、がんがんです。
10月も終わりに近づき、文化祭も徐々に近づいてきました。

今回はpaizaさんのプログラミング講座をやってみたのでそのまとめです。

続きを読む

【Deeplearningでポケモン図鑑計画】pandasで世代図鑑を作成【その0?】

はじめに

こんにちは、がんがんです。今回は計画の中に書き忘れていたpandasによる前処理をまとめました。
内容的にはpandasの練習的な内容になります。

世代ごとのcsvファイルの作成

今回行ったのは、各世代ごとのcsvファイルの作成です。
ポケモンに関する資料はありがたいことに様々な方がまとめられています。

ポケモンの番号と名前のデータを探しているときにこちらの記事に出会いました。

http://www.absolute-keitarou.net/blog/?p=727www.absolute-keitarou.net

ありがたいことに、すべてのポケモンの番号と名前をまとめたjsonファイルをgithubの方へ公開されていました。
githubへのリンクも貼っておきます。

GitHub - keitarou/pokemon_zukan: TODO: one-line summary of your gem


学習・管理を行う際に、全種まとめて行うよりも世代ごとに行ったほうが簡単だと思います。
そのため、今回はpandasを用いて世代ごとに分割していきました。

コード

コードは以下のようになっています。なお、マシンはWindowsPython環境は3.6です。

import pandas as pd
import json
from pathlib import Path

#  RG:赤緑, GS:金銀, RS:ルビー・サファイア, DP:ダイアモンド・パール
#  BW:ブラック・ホワイト, XY:X・Y, SM:サン・ムーン
name_list = [ "RG","GS", "RS", "DP", "BW", "XY", "SM"]
num_list = [ 1, 152, 252, 387, 494, 650, 721]

"""
	メイン
"""
def main():
	#  空のデータフレームを作成
	df_origin = pd.DataFrame( index=[], columns=['number','name'])

	#  jsonファイルの読み込み
	dir_path = Path("./zukan/name_table.json")
	with dir_path.open( mode="r", encoding="utf-8") as f:
		json_dict = json.load(f)

	#  DataFrameに追加
	df_origin['number'] = list(json_dict.values())
	df_origin['name'] = list(json_dict.keys())

	#  世代に合わせて図鑑を分けていく
	#  最終世代のみexcept文で例外処理
	try:
		for i in range( 0, len(num_list)):
			st = num_list[i]-1
			ed = num_list[i+1]-1
			
			df = df_origin[st:ed].copy()
			print("--------------------------")
			print(df.head())
			#  csvファイルに保存
			df.to_csv("./zukan/" + name_list[i] + ".csv", index=False)

	except IndexError:
		df = df_origin[st:].copy()

if __name__ == '__main__':
	main()

まとめ

無事に世代ごとのcsvファイルが作成出来ました。その1の方ではここで分割したcsvファイルを使用しています。
やったことを1つずつ忘れずに書いていきます。

また、Githubについてもそろそろ使用して慣れていこうと思います。

<追記> 2018.10.31
その1を更新したので以下にリンクを貼っておきます。

gangannikki.hatenadiary.jp

【pandas × openpyxl × ダンス】ダンスイベントの事務処理まとめ

 

はじめに

皆さんこんにちは、がんがんです。

実は趣味で昔からダンスをしています。仲間たちと練習会を開いたり、イベントスタッフなどもしています。

イベントを運営するにあたり、エントリー管理や対戦表の作成、タイムスケジュールの作成など多くの事務処理を行う必要があります。

せっかくプログラミングを勉強しているのだから、この事務処理を可能な限り自動化できないかなと昔からずっと考えていました。

 

今年の8月、イベントのスタッフとして事務処理関係を任されました。イベントまで時間があったおかげで、ある程度の処理を自動化することが出来ました。

今回は、自分が忘れないためにもまとめておこうと思います。

 

前提と作成手順

まずは前提として

  •  Pythonを使用する
  •  pandasや前処理の勉強がしたかった

この2つが挙げられます。

私はよく使用する言語がPythonで、当時はDeep Learningの前処理関係をよく調べていました。ちょうどpandasについて勉強したいと思っていたので、今回はpandasを使用して処理を書きました。

 

今回は以下のような手順で作業を進めました。

  1. Googleフォームでエントリーフォームを作成。
  2. Googleスプレッドシートを加工し、csvファイルとしてダウンロードする
  3. pandasを用いてcsvファイルから必要情報を取得、欠落値などの処理
  4. sampleメソッドを用いてランダムサンプリング
  5. openpyxlを用いてエクセル上に情報を格納

前回のイベントでもGoogleフォームは使用していたので、今回新たに追加したのは2~5の工程です。

 

Googleスプレッドシートの加工

Googleスプレッドシートについては何度か使用したことがありますが、加工して使用したのは今回が初めてです。

エントリーフォームの入力は入力者の負担を減らすため、1度の入力で必要な情報をすべて取得する必要があります。そのため、編集者が編集しやすい形式とはなっていません。

今回の場合ですと、エントリーの選択欄に1on1、2on2、Wエントリーの欄が存在しており、これを1on1と2on2の2つのリストに分ける必要があります。

 

そこで、FILTER関数を用いてリストを分けることにしました。

FILTER関数の詳細については以下を参照ください。

Googleスプレッドシート:FILTER関数で条件にあったデータのみを表示させる。 | ひとりで.com

  

FILTER関数を用いて、

・Wエントリーまたは1on1のみ → 1on1のリスト

・Wエントリーまたは2on2のみ → 2on2のリスト
という風に分けることが出来ました。

 

Googleスプレッドシートは使ってみると面白かったので、時間があるときにいろいろ
遊んでみます。以下は参考記事です(この中のrow関数も今回使いました)。
linq.career-tasu.jp

 

pandasによる処理

今回やりたかった勉強のメインです。意外とサクサク進んだので、後述のopenpyxlのがメインっぽいですが。pandasでは以下の3つをやっていきます。

  1. pandasにてcsvファイルの読み込み
  2. NaN値の削除
  3. sampleメソッドを使用してランダムリストの生成

 

まずはpandas部分のコードを以下に示します。


	
	#  csvファイルの読み込み
	df_origin = pd.read_csv(csv_path, engine='python', encoding='utf-8', header=0)
	#  NaN値を削除
	df_origin = df_origin.dropna(thresh=2)
	print("Before List:\n{}".format(df_origin))

	#  sampleメソッドでランダムランプリング
	df_rand = df_origin.sample(frac=1).reset_index(drop=True)
	print("After List:\n{}".format(df_rand))

1.csvファイルの読み込み

csvファイルの読み込みにはread_csvを使用しています。read_csvの使い方についてはこちらを参考にしました。

pandasでcsv/tsvファイル読み込み(read_csv, read_table) | note.nkmk.me

普通にread_csvを使う場合はこちらのみでいいのですが、OSError: Initializing from file failedというエラーと文字化けが起こりました。

 

OSError: Initializing from file failedというエラーはPython3.6の場合に起こるようです。csvファイルの名前を変更すると管理がめんどくさいので、今回はengine='python'として解決しました。

詳しい対策方法はこちらの記事をどうぞ。

Python3.6のpandasで「Initializing from file failed」が起きた場合の対策 | 自調自考の旅

 

文字化けについては、 encoding='utf-8'とすることで解決しました。

 

2.欠損値NaNの除去

こちらを参考にしてコーディングしました。

pandasで欠損値NaNを除外(削除)・置換(穴埋め)・抽出 | note.nkmk.me

 

Googleスプレッドシート上では、更新時に備えてあらかじめ40列用意していました。そのため、エントリー未登録の空白行が多くあります。これが全てNaN値として読み込まれるため、非常に邪魔でした。

手作業で消せば簡単ですが、それだと練習にならないので今回は pandasで消すことにしました。

 

NaNを消すだけであれば、df_origin = df_origin.dropna()で大丈夫です。

ただ、2on2において相方がわからないという場合は相方がNaNとなり、必要なエントリー情報まで消してしまうことになります。そのため、今回は

df_origin = df_origin.dropna(thresh=2)

と記述して、NaN値が2つ以上存在する場合に除去することにしました。

 

3.sampleメソッドを用いてランダムサンプリング

参考記事はこちらになります。

pandas.DataFrame, Seriesの行をランダムソート(シャッフル) | note.nkmk.me

 

前回のイベントではrandom関数により乱数を生成していましたが、それだと非常にめんどうでした。今回はSampleメソッドを用いることで非常に簡単にシャッフルすることが出来ました。

 

Excelによる処理

最後は印刷や管理を効率的に行うためにExcelに格納していきます。今回はpandasよりもopenpyxlの方が苦戦しました。openpyxlで行う処理は大きく分けて2つです。

  1. シートを読み込み、シャッフルなしのリストを格納
  2. シャッフルを行ったリストを格納

 

pandas同様、まずはコードを示します。こちらはソロバトルのコードです。



	"""
		Excelファイルの保存・処理
	"""
	print("-----------------------------------------------------------------")
	print("Open excel file:{}".format(ex_path))
	print("-----------------------------------------------------------------")
	wb = px.load_workbook(ex_path)
	sheetNames = list(wb.get_sheet_names())
	print("{}".format(sheetNames))

	#  Excelファイルに出力(受付用)
	ws = wb[sheetNames[0]]
	wb.active = wb.sheetnames.index(sheetNames[0])
	ws = wb.active				#  シートを取得
	print("0:{}".format(ws))

	for idx,row in enumerate(ws.iter_rows("B3:B33")):
		for cell in row:
			cell.value = df_origin.iloc[idx,1]
	for idx,row in enumerate(ws.iter_rows("C3:C33")):
		for cell in row:
			cell.value = df_origin.iloc[idx,2]


	#  Excelファイルに出力(受付以外)
	for cnt in range(1,4):
		ws = wb[sheetNames[cnt]]
		wb.active = wb.sheetnames.index(sheetNames[cnt])
		ws = wb.active				#  シートを取得
		print("{}:{}".format(cnt,ws))

		for idx,row in enumerate(ws.iter_rows("B3:B33")):
			for cell in row:
				cell.value = df_rand.iloc[idx,1]
		if cnt != 3:
			for idx, row in enumerate(ws.iter_rows("C3:C33")):
				for cell in row:
					cell.value = df_rand.iloc[idx,2]

	#  Excelの保存
	wb.save(ex_path)

受付の人はエントリー順のリスト、DJ・ジャッジ・MCの人はシャッフルしたリストの方がよいかなと思い、このようなコードなっています。

コードを別々に分ければ良かったとまとめていて気付きました。

 

openpyxlの使い方については以下のものがわかりやすく使用させてもらいました。

 Python openpyxlでExcelを操作

OpenPyXLで複数のセルの値を取得する方法

 

Excelの方はどちらも既存のファイルを使用しているため、本プログラムのようになった。

ソロバトルのExcelシートは「受付用、DJ用、ジャッジ用、集計用」、

2on2のExcelシートは「受付・DJ用、ジャッジ用、集計用」のシートをそれぞれ用意しました。

 

まとめ

今回の作成における課題としては

  • トーナメント表への反映が間に合わなかった
  •  Excel処理をもう少し綺麗にコーディングしたかった

この2つが挙げられるかなと思います。トーナメント表に反映させるところは今回断念したので次までの目標にしておきます。

また、GUIでトーナメントを作っても面白いかなと思ったので使う機会はないかもですが気が向いたら作ってみます。