前提
kerasを用いて画像分類をしているのいるのですが、データに偏りのある不均衡データを用いて学習しているため偏りをなくしたいと考えています。
そのため、imbalanced-learnを用いて少数派データのOver sampling(SMOTE)か少数派クラスに重み(重要度)を付与?させる方法を考えています。
とりあえず、SMOTEの方をプログラムで実現しようとしてます。
画像枚数が、aに13926枚,bに31865枚,cに24686枚,dに1897枚,eに293枚,fに1708枚入っており、それぞれのサイズとしては画像枚数,縦,横,チャンネル数となっています。
実現したいこと
・少数派データのOver sampling(SMOTE)
・少数派クラスに重み(重要度)を付与?させる
発生している問題・エラーメッセージ
ValueError: Found array with dim 4. Estimator expected <= 2.
該当のソースコード
python
1import numpy as np 2from PIL import Image 3import tensorflow as tf 4import time 5import matplotlib.pyplot as plt 6# import os 7# os.environ["CUDA_VISIBLE_DEVICES"] = "-1" 8from tensorflow.keras.models import Model 9from tensorflow.keras.preprocessing import image 10from tensorflow.keras.preprocessing.image import ImageDataGenerator,array_to_img 11from tensorflow.keras.optimizers import Adam 12from tensorflow.keras.callbacks import EarlyStopping, LearningRateScheduler,ReduceLROnPlateau, ModelCheckpoint 13 14Image.MAX_IMAGE_PIXELS = None 15 16#-------切り取り定義------- 17def kiritori(img): 18 img_array=np.array(img,dtype='int16') #(50行,83列,3次元)の3次元配列 19 a=np.split(img_array,img.height/50) 20 img_data=np.split(a[0],img.width/50,axis=1)#stackする土台づくり 21 for i in range(len(a)-1): 22 img_data=np.vstack([img_data,np.split(a[i+1],img.width/50,axis=1)]) 23 24 return img_data 25 26 27#-------切り取り処理(トレーニングデータ)------- 28x_train=kiritori(Image.open('8Gatu_Data/DJI_0513.png'))#(#(1200,100,100,3) 29 30train_label=np.loadtxt(fname='label//8Gatu_513_50.csv',delimiter=',',dtype='int16')#(30, 40) 31train_label=np.reshape(train_label,(train_label.size)) 32 33a_train_data = x_train[np.where(train_label==0)] 34b_train_data = x_train[np.where(train_label==1)] 35c_train_data = x_train[np.where(train_label==2)] 36d_train_data = x_train[np.where(train_label==3)] 37e_train_data = x_train[np.where(train_label==4)] 38f_train_data = x_train[np.where(train_label==5)] 39 40 41x_train=a_train_data 42x_train=np.vstack([x_train,b_train_data]) 43x_train=np.vstack([x_train,c_train_data]) 44x_train=np.vstack([x_train,d_train_data]) 45x_train=np.vstack([x_train,e_train_data]) 46x_train=np.vstack([x_train,f_train_data]) 47 48 49###-------テストデータ処理-------### 50val_test=kiritori(Image.open('8Gatu_Data/ortho_0809_2022.png')) 51 52test_label=np.loadtxt(fname='label//8Gatu_ortho1_50.csv',delimiter=',',dtype='int16')#(30, 40) 53test_label=np.reshape(test_label,(test_label.size)) 54 55a_test_data = val_test[np.where(test_label==0)] 56b_test_data = val_test[np.where(test_label==1)] 57c_test_data = val_test[np.where(test_label==2)] 58d_test_data = val_test[np.where(test_label==3)] 59e_test_data = val_test[np.where(test_label==4)] 60f_test_data = val_test[np.where(test_label==5)] 61 62val_test=a_test_data 63val_test=np.vstack([val_test,b_test_data]) 64val_test=np.vstack([val_test,c_test_data]) 65val_test=np.vstack([val_test,d_test_data]) 66val_test=np.vstack([val_test,e_test_data]) 67val_test=np.vstack([val_test,f_test_data]) 68 69y_train=np.full((a_train_data.shape[0],1),0) 70y_train=np.vstack([y_train,np.full((b_train_data.shape[0],1),[1])]) 71y_train=np.vstack([y_train,np.full((c_train_data.shape[0],1),[2])]) 72y_train=np.vstack([y_train,np.full((d_train_data.shape[0],1),[3])]) 73y_train=np.vstack([y_train,np.full((e_train_data.shape[0],1),[4])]) 74y_train=np.vstack([y_train,np.full((f_train_data.shape[0],1),[5])]) 75 76y_test=np.full((a_test_data.shape[0],1),[0]) 77y_test=np.vstack([y_test,np.full((b_test_data.shape[0],1),[1])]) 78y_test=np.vstack([y_test,np.full((c_test_data.shape[0],1),[2])]) 79y_test=np.vstack([y_test,np.full((d_test_data.shape[0],1),[3])]) 80y_test=np.vstack([y_test,np.full((e_test_data.shape[0],1),[4])]) 81y_test=np.vstack([y_test,np.full((f_test_data.shape[0],1),[5])]) 82 83# a = [] 84 85# for i in range(x_train.shape[0]): 86# img = x_train[i] 87# a.append(img) 88 89from imblearn.over_sampling import SMOTE 90sm = SMOTE(random_state=42) 91x_train1, y_train1 = sm.fit_sample(x_train, y_train) 92 93x_datagen_partial = image.ImageDataGenerator( 94 rescale = 1./255, 95 rotation_range = 180, 96 fill_mode="constant", 97 vertical_flip = True, 98 brightness_range = [0.7, 1.117], 99 horizontal_flip = True, 100 dtype = np.float64 101 )
試したこと
4次元配列から2次元配列に変換したかったのですが、リストに画像を入れることしかできませんでした。
また、Over sampling(SMOTE)したあとにまた4次元配列に戻してImageDataGeneratorにて変換したいです。
解決方法を教えていただけると幸いです
補足情報(FW/ツールのバージョンなど)
windows10(64bit)
anacondaを使用
python 3.8.13
TensorFlow 2.3
Spyder 5.3.3を利用
あなたの回答
tips
プレビュー