ごはんと飲み物は紙一重

このブログは,自己のモチベーションアップのために情報工学関連について記事を更新していこうと思います。三日坊主にならないよう頑張ります…

【俺妹】大好きな黒猫をディープラーニングで認識しないわけがない【データ準備編】

前回の記事

twdlab.hatenablog.com


引き続き【データ準備編】と題しまして記事の方を執筆していきたいと思います.

ここからは・・・

怒涛の手作業

です.初っ端から何をするのかというと自分の目でキャラクター毎に分類をしてあげなければいけません.機械で分類できるようであればディープラーニングしてまで認識をする必要はないですし←

というわけで,はじめは自分1人で分類していたのですが,ほんと流れ作業でしたので眠くなるわ疲れるわでかなり苦労しました・・・途中から友人に手伝っていただき分類を2人でやることに.

そして4日後,約8000枚すべての分類が完了しました!

f:id:ST_ha1cyon:20161026084524p:plain

(ここだけの話開発の大部分はここに時間を取られました・・・結構予想外でしたw)

やっと各キャラクターごとの分類ができ,1キャラにつき約1500枚のデータをとることができたのですが,ここで思い立つわけです.

「サンプルはかさ増しできるんじゃないか」

そう考えて,画像に対し上下反転や左右反転をすることで物量で勝負しようなんて甘い考えをしてました.そんなとき同じ考えを持つ同士の勇者様がいたので参考にさせてもらい,

ket-30.hatenablog.com

# -*- coding: utf-8 -*-

from PIL import Image
import os

folder = "sample/tamura_manami/"

def readImg(imgName):
    try:
        img_src = Image.open(folder + imgName)
        print("read img!")
    except:
        print("{} is not image file!".format(imgName))
        img_src = 1
    return img_src

def spinImg(imgNames):
    for imgName in imgNames:
        img_src = readImg(imgName)
        if img_src == 1:
            continue
        else:
            #上下反転
            tmp = img_src.transpose(Image.FLIP_TOP_BOTTOM)
            tmp.save(folder + "flipTB_" + imgName)
            #90度回転
            tmp = img_src.transpose(Image.ROTATE_90)
            tmp.save(folder + "spin90_" + imgName)
            #270度回転
            tmp = img_src.transpose(Image.ROTATE_270)
            tmp.save(folder + "spin270_" + imgName)
            #左右反転
            tmp = img_src.transpose(Image.FLIP_LEFT_RIGHT)
            tmp.save(folder + "flipLR_" + imgName)
            print("{} is done!".format(imgName))

if __name__ == '__main__':
    #read imgs names
    imgNames = os.listdir(folder)#画像が保存されているディレクトリへのpathを書く
    print(imgNames)
    spinImg(imgNames)

その結果.単純計算で5倍増しのなんと約40000枚

や っ た ぜ(何が)

これだけデータが増えれば学習も十分?にしてくれるはずと思い次の段階へ.

データが十分に集まり整理できたところでモデル式に読み込ませるためにデータの変形を行わなければいけませんね.

qiita.com

学習を行うためのモジュールによって変換する形が異なる可能性もあるので,この辺はしっかりしらべながらやっていました.上記のリンク先とMNISTのloadプログラムを参考にしながら,プログラムを構築.

# -*- coding: utf-8 -*-

##
## oreimoface.py
##
## 俺妹のキャラクターの顔データを読み込むためのプログラム
##

import os
import numpy as np
import sys
sys.path.append("/usr/local/lib/python2.7/site-packages")
import cv2

def load_data():
    # クラス数
    nb_classes = 8

    # データセットの配列
    X_train = []
    X_test = []
    y_train = []
    y_test = []

    # 主要キャラクターの画像枚数
    oreimo_num = 3000
    # その他モブキャラ等の画像枚数
    other_num = 10000

    # 画像のあるディレクトリ
    train_image_dirs = ['KosakaKirino', 'KosakaKyosuke', 'Kuroneko', 'AragakiAyase', 'TamuraManami', 'KurusuKanako', 'MakishimaSaori', 'other']

    # 学習画像データ
    train_image = []
    # 学習データのラベル
    train_label = []

    for i in range(0,7):
        # 各ディレクトリ内のファイル名取得
        files = os.listdir('DataSet/' + train_image_dirs[i])
        if i == 7:
            image_num = other_num
        else:
            image_num = oreimo_num

        for f in range(len(files)):
            # 画像の読み込み
            # ラスト100枚はテストデータとして取る
            if f == image_num:
                break

            if files[f].find('.jpg') > 0:
                if image_num - f > 100:
                    X_train.append(cv2.imread('DataSet/' + train_image_dirs[i] + '/' + files[f]))
                    y_train.append(i)
                else:
                    X_test.append(cv2.imread('DataSet/' + train_image_dirs[i] + '/' + files[f]))
                    y_test.append(i)

    return (X_train, y_train), (X_test, y_test)

上記のプログラムでは画像を通常の配列に落とし込んでいます.この時点でnp型配列に変換する手もあったのですがなぜかうまくいかなかったです(要検証).【学習編】にてソースコードを載せますが,読み込みを行ってからnp型配列に変換しています.

これにて下準備は完了です.ここまで来ると後はモデル式の構築と学習の実行とくるので華やかな未来が見えそうですw.こうやって経験するからこそなんですが華やかな結果の裏には地道な作業が沢山待ち構えているんだなと改めて思いました.

というわけで,次回はやっと本編である【学習編】です.学習から分類器の作成,あとがきまでざざざっと記事にすることができればなと考えています.忙しくないうちにきっちり書き切りたい(切実).