PythonMania

普段はロボットとAIを組み合わせて色々作ってます。Python関係以外も色々投稿していくと思います。

【Python】keras 画像データセットの読み込み方 【DeepLearning】

f:id:mizuhiki0111:20190430180019p:plain

多クラス分類 csvのラベルファイルがある場合

#ラべルの読み込み
LABELS = "../input/train.csv"
train_df = pd.read_csv(LABELS)
top = sorted(list(train_df['label_id'].value_counts().head(16).index))
train_df = train_df[train_df['label_id'].isin(top)]

from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import load_img
from sklearn.model_selection import train_test_split

#データセットの成型
SEED = 1234
TRAIN_FOLDER = "../input/train/train/"
TEST_FOLDER = "../input/test/test/"
DIM = 299
train_df['image_path'] = train_df.apply( lambda x: ( TRAIN_FOLDER + x["file_name"] ), axis=1 )
train_data = np.array([ img_to_array(load_img(img, target_size=(DIM, DIM))) for img in train_df['image_path'].values.tolist()]).astype('float32')
train_labels = train_df['label_id']

#データ分割
x_train, x_validation, y_train, y_validation = train_test_split(train_data, train_labels, test_size=0.2, stratify=np.array(train_labels), random_state=SEED)
#ラベルをカテゴリ変数に変換
y_train = pd.get_dummies(y_train.reset_index(drop=True), columns=top_breeds).as_matrix()
y_validation = pd.get_dummies(y_validation.reset_index(drop=True), columns=top_breeds).as_matrix()


カテゴリがフォルダ毎に別れている場合

#globを使いデータを読み込み
z = glob.glob("../input/train/*/*.png")
ori_label = []
ori_imgs = []
for fn in z:
    if fn[-3:] != 'png':
        continue
    ori_label.append(fn.split('/')[-2])
    new_img = Image.open(fn)
    ori_imgs.append(ImageOps.fit(new_img, (48, 48), Image.ANTIALIAS).convert('RGB'))

#画像の配列化、正則化、カテゴリラベルの数値化
imgs = np.array([np.array(im) for im in ori_imgs])
imgs = imgs.reshape(imgs.shape[0], 48, 48, 3) / 255
lb = LabelBinarizer().fit(ori_label)
label = lb.transform(ori_label)
#データの分割
trainX, validX, trainY, validY = train_test_split(imgs, label, test_size=0.05, random_state=42)

【Python】fastai ImageDataBunchの作り方 【DeepLearning】


fastai ImageDataBunchの作成方法

多クラス分類

ファイルディレクトリを指定して ImageList.from_dfで作成する

ImageList.from_df
第一引数にcsvデータ(ラベルや提出用ファイルのパス)を指定、
第二引数(path=)で画像データのディレクトリを指定
第三引数(folder)で画像データが格納されているフォルダ名を指定

画像データとラベルデータ対になったデータ形式(ImageDataBunch)が作成される

データを複製する場合にはget_transforms()関数でそれぞれのパラメータを指定しておく

#ディレクトリの指定
data_folder = Path("../input")
train_df = pd.read_csv("../input/train.csv")
test_df = pd.read_csv("../input/sample_submit.csv")

#学習用データの読み込み
test_img = ImageList.from_df(test_df, path=data_folder/'test', folder='test')
trfm = get_transforms(do_flip=True, flip_vert=True, max_rotate=10.0, max_zoom=1.1, max_lighting=0.2, max_warp=0.2, p_affine=0.75, p_lighting=0.75)
train_img = (ImageList.from_df(train_df,path=data_folder/"train",folder="train")
            .split_by_rand_pct(0.01)
            .label_from_df()
            .add_test(test_img)
            .transform(trfm,size=128)
            .databunch(path=".",bs=64,device=torch.device('cuda:0'))
             .normalize(imagenet_stats))

0,1で分類するようなケースも基本的には同じ



今度はpandasDataFrameではなく、csvからImageDataBunchを作成してみる

使用するのはImageDataBunch.from_csv()

csvファイルの画像パスにファイルの拡張子まで含まれていないときは
「suffix=」で指定することができる(ex,suffix=".png")

#データディレクトリの指定
model_path = "."
path = "../input/"
train_folder=f'{path}train'
test_folder=f'{path}test'
train_lbl=f'{path}train.csv'
ORG_SIZE=96

#ラベルデータの読み込み
df_trn = pd.read_csv(train_lbl)

#画像複製する場合はパラメータ設定
tfms = get_transforms(do_flip=True, flip_vert=True, max_rotate=.0, max_zoom=.1,
                      max_lighting=0.05, max_warp=0.)

#画像データから入力用データ(ImageDataBunch)の作成
data = ImageDataBunch.from_csv(path,csv_labels=train_lbl,folder="train",
                              ds_tfms=tfms,size=sz,test=test_folder,bs=bs)

#データの正則化等
stats=data.batch_stats()
data.normalize(stats)


<||




またcsvのラベルファイルが別途用意されていない場合(フォルダ分けされていてフォルダ名がカテゴリ名になっている場合)は
以下のようにして読み込む

path=でトレーニングデータのディレクトリを指定することで簡単に作成可能

>|python|

path = Path('input/train/')
np.random.seed(42)

data = ImageDataBunch.from_folder(path,test='../test', ds_tfms=get_transforms(),valid_pct=0.25,size=299,bs=32,num_workers=0)
data.normalize(imagenet_stats)

【Python】画像認識 - VGG19で犬の種類分類をしてみる 【DeepLearning】


今回はこちらをもとに学習していきます

www.kaggle.com


コンペではないのですが、kernelが非常に勉強になります。


犬の画像から120の犬種を判別していきます。


使用しているモデルはVGG19で、今回は前加工等はしていません。

以下コードになります。

#必要なライブラリの読み込み
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import keras
from keras.applications.vgg19 import VGG19
from keras.models import Model
from keras.layers import Dense, Dropout, Flatten

import os
from tqdm import tqdm
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
import cv2
# Input data files are available in the "../input/" directory.
# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory

from subprocess import check_output
print(check_output(["ls", "../input"]).decode("utf8"))


#csvファイルを読み込む
df_train = pd.read_csv('../input/labels.csv')
df_test = pd.read_csv('../input/sample_submission.csv')
df_train.head(10)


#正解ラベルをワンホットエンコーディングする
targets_series = pd.Series(df_train['breed'])
one_hot = pd.get_dummies(targets_series, sparse = True)
one_hot_labels = np.asarray(one_hot)

#トレーニング画像データの読み込み、正解ラベルとの対応付け
im_size = 90
x_train = []
y_train = []
x_test = []
i = 0 
for f, breed in tqdm(df_train.values):
    img = cv2.imread('../input/train/{}.jpg'.format(f))
    label = one_hot_labels[i]
    x_train.append(cv2.resize(img, (im_size, im_size)))
    y_train.append(label)
    i += 1


#テストデータの読み込み
for f in tqdm(df_test['id'].values):
    img = cv2.imread('../input/test/{}.jpg'.format(f))
    x_test.append(cv2.resize(img, (im_size, im_size)))

#画像データをnumpy配列に変換,正則化
y_train_raw = np.array(y_train, np.uint8)
x_train_raw = np.array(x_train, np.float32) / 255.
x_test  = np.array(x_test, np.float32) / 255.
num_class = y_train_raw.shape[1]

#データの分割
X_train, X_valid, Y_train, Y_valid = train_test_split(x_train_raw, y_train_raw, test_size=0.3, random_state=1)


#VGG19モデルの読み込み
base_model = VGG19(#weights='imagenet',
    weights = None, include_top=False, input_shape=(im_size, im_size, 3))



#モデル層のカスタマイズ
x = base_model.output
x = Flatten()(x)
predictions = Dense(num_class, activation='softmax')(x)


model = Model(inputs=base_model.input, outputs=predictions)


for layer in base_model.layers:
    layer.trainable = False

model.compile(loss='categorical_crossentropy', 
              optimizer='adam', 
              metrics=['accuracy'])

callbacks_list = [keras.callbacks.EarlyStopping(monitor='val_acc', patience=3, verbose=1)]
model.summary()


#学習実行
model.fit(X_train, Y_train, epochs=1, validation_data=(X_valid, Y_valid), verbose=1)

#予測の実行
preds = model.predict(x_test, verbose=1)
sub = pd.DataFrame(preds)

col_names = one_hot.columns.values
sub.columns = col_names

sub.insert(0, 'id', df_test['id'])
sub.head(5)
sub.to_csv('../input/sample_submission.csv', index=True)

【Python】画像認識 - SIGNATEで画像分類に挑戦してみる 【DeepLearning】

今回はKaggleではなくSIGNATEのコンペに挑戦してみます。


正確にはコンペというよりはチュートリアルみたいなものですが笑


signate.jp




20種類のラベルを分類してみます。


今回はfastaiを使っていきます。


モデルはDenseNetを転移学習させていきます。


以下コードです。

#必要なライブラリのインポート
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from pathlib import Path
from fastai import *
from fastai.vision import *
import torch


#ファイルディレクトリの指定
data_folder = Path("../input")
train_df = pd.read_csv("../input/train.csv")
test_df = pd.read_csv("../input/sample_submit.csv")


#学習用データの読み込み
test_img = ImageList.from_df(test_df, path=data_folder/'test', folder='test')
trfm = get_transforms(do_flip=True, flip_vert=True, max_rotate=10.0, max_zoom=1.1, max_lighting=0.2, max_warp=0.2, p_affine=0.75, p_lighting=0.75)
train_img = (ImageList.from_df(train_df,path=data_folder/"train",folder="train")
            .split_by_rand_pct(0.01)
            .label_from_df()
            .add_test(test_img)
            .transform(trfm,size=128)
            .databunch(path=".",bs=64,device=torch.device('cuda:0'))
             .normalize(imagenet_stats))

#モデル構築
learn = cnn_learner(train_img, models.densenet161, metrics=[error_rate, accuracy])


#学習の実行
lr = 3e-02
learn.fit_one_cycle(6, slice(lr))

#推論実行・提出用ファイル作成
preds,_ = learn.get_preds(ds_type=DatasetType.Test)
test_df.has_cactus = preds.numpy()[:, 0]
test_df.to_csv('submission.csv', index=True)

【Python】画像認識 - データ読み込み方法まとめ 【DeepLearning】

データセットがカテゴリ(ラベル)毎にフォルダ分けされている場合


BASE_DATA_FOLDER = "../input/"
TRAin_DATA_FOLDER = os.path.join(BASE_DATA_FOLDER, "train")
images_per_class = {}
for class_folder_name in os.listdir(TRAin_DATA_FOLDER):
    class_folder_path = os.path.join(TRAin_DATA_FOLDER, class_folder_name)
    class_label = class_folder_name
    images_per_class[class_label] = []
    for image_path in glob(os.path.join(class_folder_path, "*.png")):
        image_bgr = cv2.imread(image_path, cv2.IMREAD_COLOR)
        images_per_class[class_label].append(image_bgr)
z = glob.glob("../input/train/*/*.png")
ori_label = []
ori_imgs = []
for fn in z:
    if fn[-3:] != 'png':
        continue
    ori_label.append(fn.split('/')[-2])
    new_img = Image.open(fn)
    ori_imgs.append(ImageOps.fit(new_img, (48, 48), Image.ANTIALIAS).convert('RGB'))


#画像のサイズ指定
ScaleTo = 70
seed = 7

#トレーニングデータの読み込み
path = "./train/*/*.png"
files = glob(path)

trainImg = []
trainLabel = []
j = 1
num = len(files)

for img in files:
    print(str(j) + "/" + str(num) , end="\r")
    trainImg.append(cv2.resize(cv2.imread(img) ,(ScaleTo,ScaleTo)))
    trainLabel.append(img.split("/")[-2])
    j += 1

trainImg = np.asarray(trainImg)
trainLabel = pd.DataFrame(trainLabel)

ImageDataBunchの作成

#トレーニングデータの読み込み
data_path = Path('../input')
df = pd.read_csv(data_path/'train.csv')
df.head()


#提出用データの読み込み
sub_csv = pd.read_csv(data_path/'sample_submission.csv')
sub_csv.head()

#データ束の作成
def create_databunch(valid_idx):
    test = ImageList.from_df(sub_csv, path=data_path/'test', folder='test')
    data = (ImageList.from_df(df, path=data_path/'train', folder='train')
            .split_by_idx(valid_idx)
            .label_from_df()
            .add_test(test)
            .transform(get_transforms(flip_vert=True, max_rotate=20.0), size=128)
            .databunch(path='.', bs=64)
            .normalize(imagenet_stats)
           )
    return data







画像データとラベルが別々に保存されている場合

#トレーニングデータ、テストデータ、ラベルデータのパス読み込み
train_dir = "../input/train/train/"
test_dir = "../input/test/test/"
train_df = pd.read_csv('../input/train.csv')
train_df.head()


X_tr = []
Y_tr = []
images = train_df["id"].values
for img_id in tqdm_notebook(images):
    X_tr.append(cv2.imread(train_dir+img_id))
    Y_tr.append(train_df[train_df["id"]==img_id]["has_cactus"].values[0])
X_tr = np.asarray(X_tr)
X_tr = X_tr.astype('float32')
X_tr /= 255
Y_tr = np.asarray(Y_tr)

Zip以下に配置されたフォルダに画像がある場合

#ファイルディレクトリの指定
data_folder = Path("../input")
train_df = pd.read_csv("../input/train.csv")
test_df = pd.read_csv("../input/sample_submission.csv")



#学習用データの読み込み
train_img = (ImageList.from_df(train_df,path=data_folder/"train",folder="train")
            .split_by_rand_pct(0.01)
            .label_from_df()
            .add_test(test_img)
            .transform(trfm,size=128)
            .databunch(path=".",bs=64,device=torch.device('cuda:0'))
             .normalize(imagenet_stats))

【Python】画像認識 - データセットの読み込み方 追記 【DeepLearning】


Zipファイルの中にさらにフォルダが配置されており、その中に画像データが


配置されている場合の読み込み方について


ex.../input/train.zip/train/〇〇〇.jp 



こちらのコンペを参考にしています

www.kaggle.com


以下コードです

#必要なライブラリのインポート
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from pathlib import Path
from fastai import *
from fastai.vision import *
import torch


#ファイルディレクトリの指定
data_folder = Path("../input")
train_df = pd.read_csv("../input/train.csv")
test_df = pd.read_csv("../input/sample_submission.csv")



#学習用データの読み込み
train_img = (ImageList.from_df(train_df,path=data_folder/"train",folder="train")
            .split_by_rand_pct(0.01)
            .label_from_df()
            .add_test(test_img)
            .transform(trfm,size=128)
            .databunch(path=".",bs=64,device=torch.device('cuda:0'))
             .normalize(imagenet_stats))


#モデル構築
learn = cnn_learner(train_img, models.densenet161, metrics=[error_rate, accuracy])

#学習の実行
lr = 3e-02
learn.fit_one_cycle(5, slice(lr))



preds,_ = learn.get_preds(ds_type=DatasetType.Test)
test_df.has_cactus = preds.numpy()[:, 0]
test_df.to_csv('submission.csv', index=False)

【Python】画像認識 - fastaiとDenseNetでがん細胞の判別をしてみる【DeepLearning】

Fastaiについて理解を深めたいので、今回も記事にまとめてみます。



www.kaggle.com


以前はサボテンの分類を行いましたが、今回は画像にがん細胞が写っているかの分類を行います。


モデルは前回同様のDenseNet169を読み込んで使います


今回は学習時だけではなく推論時にもデータの複製を行う

TTA(Test Time Augmentation)という手法を使用しています

以下コードになります

#必要なライブラリの読み込み
import numpy as np
import os
from sklearn.metrics import f1_score

from fastai import *
from fastai.vision import *

import torch
import torch.nn as nn
import torchvision
import cv2

from tqdm import tqdm
from skmultilearn.model_selection import iterative_train_test_split
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MultiLabelBinarizer
import warnings
warnings.filterwarnings("ignore")

%load_ext autoreload
%autoreload


#データディレクトリの指定
model_path = "."
path = "../input/"
train_folder=f'{path}train'
test_folder=f'{path}test'
train_lbl=f'{path}train_labels.csv'
ORG_SIZE=96

bs=64
num_workers=None # Apprently 2 cpus per kaggle node, so 4 threads I think
sz=96


#ラベルデータの読み込み
df_trn = pd.read_csv(train_lbl)
#画像複製のパラメータ設定
tfms = get_transforms(do_flip=True, flip_vert=True, max_rotate=.0, max_zoom=.1,
                      max_lighting=0.05, max_warp=0.)


#画像データから入力用データ(ImageDataBunch)の作成
data = ImageDataBunch.from_csv(path,csv_labels=train_lbl,folder="train",
                              ds_tfms=tfms,size=sz,suffix=".tif",test=test_folder,bs=bs)
stats=data.batch_stats()
data.normalize(stats)

#いくつかデータを可視化してみる
data.show_batch(rows=5, figsize=(12,9))


#評価関数(auc)の設定
from sklearn.metrics import roc_auc_score
def auc_score(y_pred,y_true,tens=True):
    score=roc_auc_score(y_true,torch.sigmoid(y_pred)[:,1])
    if tens:
        score=tensor(score)
    else:
        score=score
    return score



#モデルの作成
from torchvision.models import *
learn = create_cnn(data,
                  densenet169,
                  path=".",
                  metrics=[auc_score],
                  ps = 0.5,
                  )


#モデル学習時のLearning Curveの表示?
learn.lr_find()
learn.recorder.plot()


#1エポック学習
learn.fit_one_cycle(1,3e-2)
learn.recorder.plot()
learn.recorder.plot_losses()
learn.recorder.plot()


learn.unfreeze()
learn.lr_find()



#学習の実行(20epoch)
learn.fit_one_cycle(20,slice(1e-4,1e-3))

learn.recorder.plot()
learn.recorder.plot_losses()


TTAを使用しvalidation dataでテスト
preds,y=learn.get_preds()
pred_score=auc_score(preds,y)
pred_score
preds,y=learn.TTA()
pred_score_tta=auc_score(preds,y)
pred_score_tta


#テストデータで予測
preds_test,y_test=learn.get_preds(ds_type=DatasetType.Test)
preds_test_tta,y_test_tta=learn.TTA(ds_type=DatasetType.Test)




#提出用ファイルの作成
sub=pd.read_csv(f'{path}/sample_submission.csv').set_index('id')
sub.head()

clean_fname=np.vectorize(lambda fname: str(fname).split('/')[-1].split('.')[0])
fname_cleaned=clean_fname(data.test_ds.items)
fname_cleaned=fname_cleaned.astype(str)

sub.loc[fname_cleaned,'label']=to_np(preds_test[:,1])
sub.to_csv(f'submission_{pred_score}.csv')

sub.loc[fname_cleaned,'label']=to_np(preds_test_tta[:,1])
sub.to_csv(f'submission_{pred_score_tta}.csv')

【Python】画像認識 - 画像認識ワークフローまとめ【DeepLearning】


ここまで学習してきたことについて軽くまとめてみます。






まだまだ深くは理解できていませんが、画像認識をする際のワークフローは

概ね以下のような流れが多かったと思います



①プロジェクトの理解
②データの理解
③データの読み込み・加工・複製
④モデルの選択
⑤モデルの評価


精度を確認しながら③~⑤を繰り返す
それぞれについてまとめていきます




①プロジェクトの理解

まず初めにやることはプロジェクト全体をよく理解することです。

どのようなデータが与えられていて、データをもとに何を求めていけばいいのかということをまとめます。

以前行ったがん細胞の判別コンぺの場合は、がん細胞が非常に小さなものでかつ画像の狭い領域に

しか映っていないことが課題として挙げられていました。

また最終的にどのような評価関数で精度を導き出すのが適切か、ということも検討する必要があります。

プロジェクト全体の大まかなフローをこの段階で決めておくと以後の作業が進めやすくなるような気がします。




②データの理解

次に与えられたデータを理解する必要があります。

主に以下のような内容を確認していきます。

・データフォーマット
・データサイズ
・チャンネル数
・データ型
・圧縮
・データ数
・カテゴリごとのデータの分布
・注目すべきオブジェクトの特徴

このフェーズで得た情報をもとに、データ整形を行っていくためよく理解する必要があります。

例えば注目すべき物体が同一色であったら、色をもとにオリジナル画像を加工していく、等の方法が考えられます。




③データの読み込み・加工・複製

今まで見てきた中だと、このフェーズが非常に重要だと感じました。

どのモデルを使うかよりも、データの特徴を生かした前加工をしっかりしたものの方が精度が上がっている気がします。


まずデータの読み込みですが、データの形式として

①画像データがカテゴリごとにフォルダに分類されているもの

②一つのフォルダに全てのトレーニングデータが入っており、別途csv形式でカテゴリが指定してあるもの


の2種類がありました。

データの読み込み方が違うみたいなので、形式にあった方法で読み込んでいきます。
僕は経験が浅いので、まずここで詰まりました笑
(以前記事にまとめたので、詳細はそちらを参照ください)


また、読み込んだデータは数値(Numpy配列)等に変換、
ラベルデータも数値に変換(ワンホットエンコーディング)しておきます


次にデータの加工です。

データの特徴に合わせて加工をする必要がありますが、

今まで見てきたものだと、主に以下のような処理を行っていました。

・データをRGB→HSV変換し、オブジェクトの色に注目、マスク作成
・画像のノイズを削除するために、ぼかしを加える(cv2.GaussianBlur)
・不要な領域を削除するためのトリミング
・エッジを検出
など

主にOpenCVの関数を使用して、オリジナル画像を加工していくことが多いみたいです。



画像の加工が終わったら、データを複製していきます。

データが十分に用意されている場合は必要ないですが、たいていの場合はデータが偏っていたり、

そもそも元データが少なかったりで、この処理を行うことになると思います。

主に以下のような処理を行います

・ズーム
・回転
・コントラスト強調
・輝度調整
・スライド



④モデルの選択

ここまで来てやっとモデルの構築を行っています。

見てきた中では、既存のモデル(ResNet,DenseNet等)を転移学習するものが多かったので、

プロジェクトやデータにもよると思いますが、まずは転移学習を試してみるといい気がします。

pytorchなんかを使えば、学習済モデルを簡単に読み込めるみたいです

Keras等のフレームワークを使って一段ずつ層を作っていくパターンもありました。



まだまだ勉強不足ですがアンサンブルなんかも試してみたいと思っています。




⑤モデルの精度検証


学習が終わったら、バリデーションデータでモデルの精度を検証していきます。

ConfusionMatrixなどでどこがうまく判別できなかったのか、などを確認してみるのもいいかもしれません




今まで学んだ内容をとりあえずまとめてみました。


また理解が進んだら改めて記事にまとめたいと思います。

【Python】画像認識 - CNNモデルの作成【DeepLearning】



今回はこちらのコンペをもとにCNNモデルの作成までをまとめてみます




www.kaggle.com



以下コードになります。
Kerasを使用してモデルを作成しています。

#必要なライブラリの読み込み
from numpy.random import seed
seed(101)
from tensorflow import set_random_seed
set_random_seed(101)

import pandas as pd
import numpy as np


import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Dense, Dropout, Flatten, Activation
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
from tensorflow.keras.optimizers import Adam

import os
import cv2

from sklearn.utils import shuffle
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
import itertools
import shutil
import matplotlib.pyplot as plt
%matplotlib inline
IMAGE_SIZE = 96
IMAGE_CHANNELS = 3

SAMPLE_SIZE = 80000


os.listdir('../input')


#トレーニング・テストデータの読み込み
print(len(os.listdir('../input/train')))
print(len(os.listdir('../input/test')))


#全てのデータを含んだデータフレームの作成
df_data = pd.read_csv('../input/train_labels.csv')

# 一部データを削除
df_data[df_data['id'] != 'dd6dfed324f9fcb6f93f46f32fc800f2ec196be2']
df_data[df_data['id'] != '9369c7278ec8bcc6c880d99194de09fc2bd4efbe']


print(df_data.shape)


#それぞれのカテゴリのデータ数を確認
df_data['label'].value_counts()



#0,1カテゴリそれぞれの写真を表示してみる
def draw_category_images(col_name,figure_cols,df,IMAGE_PATH):
    categories = (df.groupby([col_name])[col_name].nunique()).index
    f,ax = plt.subplots(nrows=len(categories),ncols=figure_cols,
                       figsize=(4*figure_cols,4*len(categories)))
    for i,cat in enumerate(categories):
        sample = df[df[col_name]==cat].sample(figure_cols) # figure_cols is also the sample size
        for j in range(0,figure_cols):
           file=IMAGE_PATH + sample.iloc[j]['id'] + '.tif'
           im=cv2.imread(file)
           ax[i, j].imshow(im, resample=True, cmap='gray')
           ax[i, j].set_title(cat, fontsize=16)  
    plt.tight_layout()
    plt.show()


IMAGE_PATH = '../input/train/' 
draw_category_images('label',4, df_data, IMAGE_PATH)


#データセットの作成
df_data.head()
#0,1それぞれのデータ数が合わないのでラベル0のデータ数を減らす
df_0 = df_data[df_data['label'] == 0].sample(SAMPLE_SIZE, random_state = 101)
df_1 = df_data[df_data['label'] == 1].sample(SAMPLE_SIZE, random_state = 101)
#2つのデータフレームを結合する
df_data = pd.concat([df_0, df_1], axis=0).reset_index(drop=True)
# シャッフルする
df_data = shuffle(df_data)

df_data['label'].value_counts()

#データセットを分割する
y = df_data['label']
df_train, df_val = train_test_split(df_data, test_size=0.10, random_state=101, stratify=y)
print(df_train.shape)
print(df_val.shape)


#分割後のデータ数の確認

df_train['label'].value_counts()
df_val['label'].value_counts()


#ディレクトリ構成を変える
base_dir = 'base_dir'
os.mkdir(base_dir)
train_dir = os.path.join(base_dir, 'train_dir')
os.mkdir(train_dir)
val_dir = os.path.join(base_dir, 'val_dir')
os.mkdir(val_dir)
no_tumor_tissue = os.path.join(train_dir, 'a_no_tumor_tissue')
os.mkdir(no_tumor_tissue)
has_tumor_tissue = os.path.join(train_dir, 'b_has_tumor_tissue')
os.mkdir(has_tumor_tissue)
no_tumor_tissue = os.path.join(val_dir, 'a_no_tumor_tissue')
os.mkdir(no_tumor_tissue)
has_tumor_tissue = os.path.join(val_dir, 'b_has_tumor_tissue')
os.mkdir(has_tumor_tissue)


# 作成後のディレクトリを確認
os.listdir('base_dir/train_dir')


#トレーニング・バリデーションデータリストの取得
train_list = list(df_train['id'])
val_list = list(df_val['id'])



# 新しく作ったフォルダ用にファイル名等を変換していく

for image in train_list:
    
   
    fname = image + '.tif'
    target = df_data.loc[image,'label']
    
   
    if target == 0:
        label = 'a_no_tumor_tissue'
    if target == 1:
        label = 'b_has_tumor_tissue'
    
    
    src = os.path.join('../input/train', fname)
   
    dst = os.path.join(train_dir, label, fname)
   
    shutil.copyfile(src, dst)




for image in val_list:
    

    fname = image + '.tif'
    
    target = df_data.loc[image,'label']
    
  
    if target == 0:
        label = 'a_no_tumor_tissue'
    if target == 1:
        label = 'b_has_tumor_tissue'
    

  
    src = os.path.join('../input/train', fname)

    dst = os.path.join(val_dir, label, fname)
 
    shutil.copyfile(src, dst)



#CNNモデルの作成
kernel_size = (3,3)
pool_size= (2,2)
first_filters = 32
second_filters = 64
third_filters = 128

dropout_conv = 0.3
dropout_dense = 0.3


model = Sequential()
model.add(Conv2D(first_filters, kernel_size, activation = 'relu', input_shape = (96, 96, 3)))
model.add(Conv2D(first_filters, kernel_size, activation = 'relu'))
model.add(Conv2D(first_filters, kernel_size, activation = 'relu'))
model.add(MaxPooling2D(pool_size = pool_size)) 
model.add(Dropout(dropout_conv))

model.add(Conv2D(second_filters, kernel_size, activation ='relu'))
model.add(Conv2D(second_filters, kernel_size, activation ='relu'))
model.add(Conv2D(second_filters, kernel_size, activation ='relu'))
model.add(MaxPooling2D(pool_size = pool_size))
model.add(Dropout(dropout_conv))

model.add(Conv2D(third_filters, kernel_size, activation ='relu'))
model.add(Conv2D(third_filters, kernel_size, activation ='relu'))
model.add(Conv2D(third_filters, kernel_size, activation ='relu'))
model.add(MaxPooling2D(pool_size = pool_size))
model.add(Dropout(dropout_conv))

model.add(Flatten())
model.add(Dense(256, activation = "relu"))
model.add(Dropout(dropout_dense))
model.add(Dense(2, activation = "softmax"))

model.summary()

【Python】画像認識 - 画像ファイルとラベルファイルが分かれている場合のトレーニングデータの読み込み方法【DeepLearning】


学習用のデータを読み込む際、ラベルごとにフォルダ分けしてデータを保存していることが多かったんで、

ラベルを別途csvファイルで用意されているパターンに遭遇して詰まりました笑


今回は画像ファイルとラベルファイル(csv)が分かれている場合の読み込み方法についてまとめてみます。

参考にしたのはこちらのコンペです


www.kaggle.com



for文を使って、画像のパスとcsvに表記されている画像のパスが

同じ場合cv2.imreadで読み込む、みたいな感じらしいです。



データ読み込み部分だけでなく、全体のコードを載せておきます。


#必要なライブラリの読み込み
import cv2
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import json
import os
from tqdm import tqdm, tqdm_notebook
from keras.models import Sequential
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.applications import VGG16
from keras.optimizers import Adam




#トレーニングデータ、テストデータ、ラベルデータのパス読み込み
train_dir = "../input/train/train/"
test_dir = "../input/test/test/"
train_df = pd.read_csv('../input/train.csv')
train_df.head()



#試しに1枚プロットしてみる
im = cv2.imread("../input/train/train/01e30c0ba6e91343a12d2126fcafc0dd.jpg")
plt.imshow(im)


#vgg16の読み込み
vgg16_net = VGG16(weights='imagenet', 
                  include_top=False, 
                  input_shape=(32, 32, 3))



vgg16_net.trainable = False
#モデルの概要を表示
vgg16_net.summary()

#モデル作成
model = Sequential()
model.add(vgg16_net)
model.add(Flatten())
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer=Adam(lr=1e-5), 
              metrics=['accuracy'])


#データの読み込み
X_tr = []
Y_tr = []
images = train_df["id"].values
for img_id in tqdm_notebook(images):
    X_tr.append(cv2.imread(train_dir+img_id))
    Y_tr.append(train_df[train_df["id"]==img_id]["has_cactus"].values[0])
X_tr = np.asarray(X_tr)
X_tr = X_tr.astype('float32')
X_tr /= 255
Y_tr = np.asarray(Y_tr)


with open('history.json', 'w') as f:
    json.dump(history.history, f)

history_df = pd.DataFrame(history.history)
history_df[['loss', 'val_loss']].plot()
history_df[['acc', 'val_acc']].plot()


#学習の実行
batch_size = 32
nb_epoch = 1000

# Train model
history = model.fit(X_tr, Y_tr,
              batch_size=batch_size,
              epochs=nb_epoch,
              validation_split=0.1,
              shuffle=True,
              verbose=2)

#テストファイルの読み込み
X_tst = []
Test_imgs = []
for img_id in tqdm_notebook(os.listdir(test_dir)):
    X_tst.append(cv2.imread(test_dir + img_id))     
    Test_imgs.append(img_id)
X_tst = np.asarray(X_tst)
X_tst = X_tst.astype('float32')

#テストデータ予測
test_predictions = model.predict(X_tst)
sub_df = pd.DataFrame(test_predictions, columns=['has_cactus'])
sub_df['has_cactus'] = sub_df['has_cactus'].apply(lambda x: 1 if x > 0.75 else 0)
sub_df['id'] = ''
cols = sub_df.columns.tolist()
cols = cols[-1:] + cols[:-1]
sub_df=sub_df[cols]
for i, img in enumerate(Test_imgs):
    sub_df.set_value(i,'id',img)
X_tst /= 255


sub_df.head()